diff options
author | Richard Sandiford <rsandifo@redhat.com> | 2001-08-10 13:08:16 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2001-08-10 13:08:16 +0000 |
commit | 67070ffeb0f10bcc841e87756d18eb85de1ab8a8 (patch) | |
tree | dbed25d8882c9ff756cc85d3b8076f7b534a4bda /gcc | |
parent | a8205f032908c8d821e92aac477cf60804ca2d2e (diff) | |
download | gcc-67070ffeb0f10bcc841e87756d18eb85de1ab8a8.zip gcc-67070ffeb0f10bcc841e87756d18eb85de1ab8a8.tar.gz gcc-67070ffeb0f10bcc841e87756d18eb85de1ab8a8.tar.bz2 |
mips.c (mips_add_large_offset_to_sp): New function.
* config/mips/mips.c (mips_add_large_offset_to_sp): New function.
(mips_annotate_frame_insn): New function.
(mips_emit_frame_related_store): New function.
(save_restore_insns): Don't mark instructions that set up the base
registers as frame-related. Add REG_FRAME_RELATED_EXPR notes to
the store instructions instead.
(mips_expand_prologue): If the stack size is moved into a temporary
register, do not mark that move as frame-related. Add a
REG_FRAME_RELATED_EXPR note to the stack adjustment instruction.
From-SVN: r44761
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 234 |
2 files changed, 100 insertions, 146 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3e1d11a..dbbe9d1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,17 @@ 2001-08-10 Richard Sandiford <rsandifo@redhat.com> + * config/mips/mips.c (mips_add_large_offset_to_sp): New function. + (mips_annotate_frame_insn): New function. + (mips_emit_frame_related_store): New function. + (save_restore_insns): Don't mark instructions that set up the base + registers as frame-related. Add REG_FRAME_RELATED_EXPR notes to + the store instructions instead. + (mips_expand_prologue): If the stack size is moved into a temporary + register, do not mark that move as frame-related. Add a + REG_FRAME_RELATED_EXPR note to the stack adjustment instruction. + +2001-08-10 Richard Sandiford <rsandifo@redhat.com> + * config/mips/mips.c (save_restore_insns): Don't mark the RA's stack slot as unchanging if current_function_calls_eh_return. diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index dc1781c..59c7e25 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -91,6 +91,11 @@ static void block_move_loop PARAMS ((rtx, rtx, rtx, rtx)); static void block_move_call PARAMS ((rtx, rtx, rtx)); static FILE *mips_make_temp_file PARAMS ((void)); +static rtx mips_add_large_offset_to_sp PARAMS ((HOST_WIDE_INT, + FILE *)); +static void mips_annotate_frame_insn PARAMS ((rtx, rtx)); +static void mips_emit_frame_related_store PARAMS ((rtx, rtx, + HOST_WIDE_INT)); static void save_restore_insns PARAMS ((int, rtx, long, FILE *)); static void mips16_output_gp_offset PARAMS ((FILE *, rtx)); @@ -6447,6 +6452,73 @@ compute_frame_size (size) #define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0) +/* Emit instructions to load the value (SP + OFFSET) into MIPS_TEMP2_REGNUM + and return an rtl expression for the register. Write the assembly + instructions directly to FILE if it is not null, otherwise emit them as + rtl. + + This function is a subroutine of save_restore_insns. It is used when + OFFSET is too large to add in a single instruction. */ + +static rtx +mips_add_large_offset_to_sp (offset, file) + HOST_WIDE_INT offset; + FILE *file; +{ + rtx reg = gen_rtx_REG (Pmode, MIPS_TEMP2_REGNUM); + if (file == 0) + { + rtx offset_rtx = GEN_INT (offset); + + emit_move_insn (reg, offset_rtx); + if (Pmode == DImode) + emit_insn (gen_adddi3 (reg, reg, stack_pointer_rtx)); + else + emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx)); + } + else + { + fprintf (file, "\tli\t%s,0x%.08lx\t# ", + reg_names[MIPS_TEMP2_REGNUM], (long) offset); + fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset); + fprintf (file, "\n\t%s\t%s,%s,%s\n", + Pmode == DImode ? "daddu" : "addu", + reg_names[MIPS_TEMP2_REGNUM], + reg_names[MIPS_TEMP2_REGNUM], + reg_names[STACK_POINTER_REGNUM]); + } + return reg; +} + +/* Make INSN frame related and note that it performs the frame-related + operation DWARF_PATTERN. */ + +static void +mips_annotate_frame_insn (insn, dwarf_pattern) + rtx insn, dwarf_pattern; +{ + RTX_FRAME_RELATED_P (insn) = 1; + REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR, + dwarf_pattern, + REG_NOTES (insn)); +} + +/* Emit a move instruction that stores REG in MEM. Make the instruction + frame related and note that it stores REG at (SP + OFFSET). */ + +static void +mips_emit_frame_related_store (mem, reg, offset) + rtx mem; + rtx reg; + HOST_WIDE_INT offset; +{ + rtx dwarf_address = plus_constant (stack_pointer_rtx, offset); + rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address); + + mips_annotate_frame_insn (emit_move_insn (mem, reg), + gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg)); +} + static void save_restore_insns (store_p, large_reg, large_offset, file) int store_p; /* true if this is prologue */ @@ -6517,8 +6589,6 @@ save_restore_insns (store_p, large_reg, large_offset, file) else insn = emit_insn (gen_addsi3 (base_reg_rtx, large_reg, stack_pointer_rtx)); - if (store_p) - RTX_FRAME_RELATED_P (insn) = 1; } else fprintf (file, "\t%s\t%s,%s,%s\n", @@ -6527,61 +6597,10 @@ save_restore_insns (store_p, large_reg, large_offset, file) reg_names[REGNO (large_reg)], reg_names[STACK_POINTER_REGNUM]); } - else { - base_reg_rtx = gen_rtx_REG (Pmode, MIPS_TEMP2_REGNUM); base_offset = gp_offset; - if (file == 0) - { - 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 (gp_offset_rtx)) - && GET_MODE (base_reg_rtx) == SImode) - { - insn = emit_move_insn (base_reg_rtx, - GEN_INT (gp_offset & BITMASK_UPPER16)); - if (store_p) - RTX_FRAME_RELATED_P (insn) = 1; - insn - = emit_insn (gen_iorsi3 (base_reg_rtx, base_reg_rtx, - GEN_INT (gp_offset - & BITMASK_LOWER16))); - 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 (Pmode == DImode) - insn = emit_insn (gen_adddi3 (base_reg_rtx, base_reg_rtx, - stack_pointer_rtx)); - else - insn = emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, - stack_pointer_rtx)); - if (store_p) - RTX_FRAME_RELATED_P (insn) = 1; - } - else - { - fprintf (file, "\tli\t%s,0x%.08lx\t# ", - reg_names[MIPS_TEMP2_REGNUM], (long) base_offset); - fprintf (file, HOST_WIDE_INT_PRINT_DEC, base_offset); - fprintf (file, "\n\t%s\t%s,%s,%s\n", - Pmode == DImode ? "daddu" : "addu", - reg_names[MIPS_TEMP2_REGNUM], - reg_names[MIPS_TEMP2_REGNUM], - reg_names[STACK_POINTER_REGNUM]); - } + base_reg_rtx = mips_add_large_offset_to_sp (base_offset, file); } /* When we restore the registers in MIPS16 mode, then if we are @@ -6635,10 +6654,7 @@ save_restore_insns (store_p, large_reg, large_offset, file) reg_rtx = gen_rtx (REG, gpr_mode, regno); if (store_p) - { - insn = emit_move_insn (mem_rtx, reg_rtx); - RTX_FRAME_RELATED_P (insn) = 1; - } + mips_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset); else if (!TARGET_ABICALLS || (mips_abi != ABI_32 && mips_abi != ABI_O64) || regno != (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST)) @@ -6738,8 +6754,6 @@ save_restore_insns (store_p, large_reg, large_offset, file) else insn = emit_insn (gen_addsi3 (base_reg_rtx, large_reg, stack_pointer_rtx)); - if (store_p) - RTX_FRAME_RELATED_P (insn) = 1; } else @@ -6749,62 +6763,10 @@ save_restore_insns (store_p, large_reg, large_offset, file) reg_names[REGNO (large_reg)], reg_names[STACK_POINTER_REGNUM]); } - else { - base_reg_rtx = gen_rtx_REG (Pmode, MIPS_TEMP2_REGNUM); base_offset = fp_offset; - if (file == 0) - { - 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 (fp_offset_rtx)) - && GET_MODE (base_reg_rtx) == SImode) - { - insn = emit_move_insn (base_reg_rtx, - GEN_INT (fp_offset & BITMASK_UPPER16)); - if (store_p) - RTX_FRAME_RELATED_P (insn) = 1; - insn = emit_insn (gen_iorsi3 (base_reg_rtx, base_reg_rtx, - GEN_INT (fp_offset - & BITMASK_LOWER16))); - 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 (Pmode == DImode) - insn = emit_insn (gen_adddi3 (base_reg_rtx, base_reg_rtx, - stack_pointer_rtx)); - else - insn = emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, - stack_pointer_rtx)); - if (store_p) - RTX_FRAME_RELATED_P (insn) = 1; - } - else - { - fprintf (file, "\tli\t%s,0x%.08lx\t# ", - reg_names[MIPS_TEMP2_REGNUM], (long) base_offset); - fprintf (file, HOST_WIDE_INT_PRINT_DEC, base_offset); - fprintf (file, "\n\t%s\t%s,%s,%s\n", - Pmode == DImode ? "daddu" : "addu", - reg_names[MIPS_TEMP2_REGNUM], - reg_names[MIPS_TEMP2_REGNUM], - reg_names[STACK_POINTER_REGNUM]); - } + base_reg_rtx = mips_add_large_offset_to_sp (fp_offset, file); } /* This loop must iterate over the same space as its companion in @@ -6826,10 +6788,7 @@ save_restore_insns (store_p, large_reg, large_offset, file) RTX_UNCHANGING_P (mem_rtx) = 1; if (store_p) - { - insn = emit_move_insn (mem_rtx, reg_rtx); - RTX_FRAME_RELATED_P (insn) = 1; - } + mips_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset); else emit_move_insn (reg_rtx, mem_rtx); } @@ -7305,45 +7264,28 @@ mips_expand_prologue () if ((!TARGET_ABICALLS || (mips_abi != ABI_32 && mips_abi != ABI_O64)) && (!TARGET_MIPS16 || tsize <= 32767)) { - rtx insn; + rtx adjustment_rtx, insn, dwarf_pattern; if (tsize > 32767) { - tmp_rtx = gen_rtx (REG, Pmode, MIPS_TEMP1_REGNUM); - - /* 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 (tsize_rtx, GET_MODE (tsize_rtx)) - && GET_MODE (tmp_rtx) == SImode) - { - insn = emit_move_insn (tmp_rtx, - GEN_INT (tsize & BITMASK_UPPER16)); - RTX_FRAME_RELATED_P (insn) = 1; - insn = emit_insn (gen_iorsi3 (tmp_rtx, tmp_rtx, - GEN_INT (tsize - & BITMASK_LOWER16))); - RTX_FRAME_RELATED_P (insn) = 1; - } - else - { - insn = emit_move_insn (tmp_rtx, tsize_rtx); - RTX_FRAME_RELATED_P (insn) = 1; - } - - tsize_rtx = tmp_rtx; + adjustment_rtx = gen_rtx (REG, Pmode, MIPS_TEMP1_REGNUM); + emit_move_insn (adjustment_rtx, tsize_rtx); } + else + adjustment_rtx = tsize_rtx; if (Pmode == DImode) insn = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, - tsize_rtx)); + adjustment_rtx)); else insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, - tsize_rtx)); + adjustment_rtx)); + + dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx, + plus_constant (stack_pointer_rtx, + -tsize)); - RTX_FRAME_RELATED_P (insn) = 1; + mips_annotate_frame_insn (insn, dwarf_pattern); } if (! mips_entry) |