summaryrefslogtreecommitdiff
path: root/gcc/config/mips/mips.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/mips/mips.c')
-rw-r--r--gcc/config/mips/mips.c56
1 files changed, 52 insertions, 4 deletions
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 2d6984b8737..706a9bfe7bf 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -5011,9 +5011,32 @@ save_restore_insns (store_p, large_reg, large_offset, file)
base_offset = gp_offset;
if (file == (FILE *)0)
{
- insn = emit_move_insn (base_reg_rtx, GEN_INT (gp_offset));
- if (store_p)
- RTX_FRAME_RELATED_P (insn) = 1;
+ rtx gp_offset_rtx = GEN_INT (gp_offset);
+
+ /* Instruction splitting doesn't preserve the RTX_FRAME_RELATED_P
+ bit, so make sure that we don't emit anything that can be
+ split. */
+ /* ??? There is no DImode ori immediate pattern, so we can only
+ do this for 32 bit code. */
+ if (large_int (gp_offset_rtx)
+ && GET_MODE (base_reg_rtx) == SImode)
+ {
+ insn = emit_move_insn (base_reg_rtx,
+ GEN_INT (gp_offset & 0xffff0000));
+ if (store_p)
+ RTX_FRAME_RELATED_P (insn) = 1;
+ insn = emit_insn (gen_iorsi3 (base_reg_rtx, base_reg_rtx,
+ GEN_INT (gp_offset & 0x0000ffff)));
+ if (store_p)
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+ else
+ {
+ insn = emit_move_insn (base_reg_rtx, gp_offset_rtx);
+ if (store_p)
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
if (TARGET_LONG64)
insn = emit_insn (gen_adddi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
else
@@ -5131,7 +5154,32 @@ save_restore_insns (store_p, large_reg, large_offset, file)
base_offset = fp_offset;
if (file == (FILE *)0)
{
- insn = emit_move_insn (base_reg_rtx, GEN_INT (fp_offset));
+ rtx fp_offset_rtx = GEN_INT (fp_offset);
+
+ /* Instruction splitting doesn't preserve the RTX_FRAME_RELATED_P
+ bit, so make sure that we don't emit anything that can be
+ split. */
+ /* ??? There is no DImode ori immediate pattern, so we can only
+ do this for 32 bit code. */
+ if (large_int (fp_offset_rtx)
+ && GET_MODE (base_reg_rtx) == SImode)
+ {
+ insn = emit_move_insn (base_reg_rtx,
+ GEN_INT (fp_offset & 0xffff0000));
+ if (store_p)
+ RTX_FRAME_RELATED_P (insn) = 1;
+ insn = emit_insn (gen_iorsi3 (base_reg_rtx, base_reg_rtx,
+ GEN_INT (fp_offset & 0x0000ffff)));
+ if (store_p)
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+ else
+ {
+ insn = emit_move_insn (base_reg_rtx, fp_offset_rtx);
+ if (store_p)
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
if (store_p)
RTX_FRAME_RELATED_P (insn) = 1;
if (TARGET_LONG64)