From b73ce23b1dd70ef25f54d0dc4ecb5c6154bdb62f Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sun, 1 Aug 2004 11:17:36 +0000 Subject: [PATCH] mips-protos.h (mips_gp_save_slot): Remove. * config/mips/mips-protos.h (mips_gp_save_slot): Remove. (mips_restore_gp): Declare. * config/mips/mips.c (mips_add_offset): Add a scratch register argument. Reimplement in rtl only, reusing MIPS16 logic from mips_output_mi_thunk. (mips_legitimize_address, mips_legitimize_const_move): Adjust calls to mips_add_offset. (mips_gp_save_slot): Delete. (mips_restore_gp): New function. (mips_set_return_address, mips_output_mi_thunk): Use mips_add_offset. * config/mips/mips.md (exception_receiver): Turn into a define_insn_and_split. Use mips_restore_gp to do the split. (call_internal, call_value_internal, call_value_multiple_internal): Use mips_restore_gp to restore $gp. From-SVN: r85404 --- gcc/ChangeLog | 17 ++++++ gcc/config/mips/mips-protos.h | 2 +- gcc/config/mips/mips.c | 105 +++++++++++++++------------------- gcc/config/mips/mips.md | 18 +++--- 4 files changed, 75 insertions(+), 67 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5b8bfd5e7fa..c47eb67d586 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2004-08-01 Richard Sandiford + + * config/mips/mips-protos.h (mips_gp_save_slot): Remove. + (mips_restore_gp): Declare. + * config/mips/mips.c (mips_add_offset): Add a scratch register + argument. Reimplement in rtl only, reusing MIPS16 logic from + mips_output_mi_thunk. + (mips_legitimize_address, mips_legitimize_const_move): Adjust calls + to mips_add_offset. + (mips_gp_save_slot): Delete. + (mips_restore_gp): New function. + (mips_set_return_address, mips_output_mi_thunk): Use mips_add_offset. + * config/mips/mips.md (exception_receiver): Turn into a + define_insn_and_split. Use mips_restore_gp to do the split. + (call_internal, call_value_internal, call_value_multiple_internal): Use + mips_restore_gp to restore $gp. + 2004-07-31 Andrew Pinski PR other/16842 diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 73a7e75ad92..f09d704b862 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -121,7 +121,7 @@ extern rtx mips_subword (rtx, int); extern bool mips_split_64bit_move_p (rtx, rtx); extern void mips_split_64bit_move (rtx, rtx); extern const char *mips_output_move (rtx, rtx); -extern rtx mips_gp_save_slot (void); +extern void mips_restore_gp (void); #ifdef RTX_CODE extern bool mips_emit_scc (enum rtx_code, rtx); extern void gen_conditional_branch (rtx *, enum rtx_code); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index f5b2a08bc85..825172b0058 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -164,7 +164,7 @@ static bool mips16_unextended_reference_p (enum machine_mode mode, rtx, rtx); static rtx mips_force_temporary (rtx, rtx); static rtx mips_split_symbol (rtx, rtx); static rtx mips_unspec_offset_high (rtx, rtx, rtx, enum mips_symbol_type); -static rtx mips_add_offset (rtx, HOST_WIDE_INT); +static rtx mips_add_offset (rtx, rtx, HOST_WIDE_INT); static unsigned int mips_build_shift (struct mips_integer_op *, HOST_WIDE_INT); static unsigned int mips_build_lower (struct mips_integer_op *, unsigned HOST_WIDE_INT); @@ -1742,18 +1742,33 @@ mips_unspec_offset_high (rtx temp, rtx base, rtx addr, } -/* Return a legitimate address for REG + OFFSET. This function will - create a temporary register if OFFSET is not a SMALL_OPERAND. */ +/* Return a legitimate address for REG + OFFSET. TEMP is as for + mips_force_temporary; it is only needed when OFFSET is not a + SMALL_OPERAND. */ static rtx -mips_add_offset (rtx reg, HOST_WIDE_INT offset) +mips_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset) { if (!SMALL_OPERAND (offset)) - reg = expand_simple_binop (GET_MODE (reg), PLUS, - GEN_INT (CONST_HIGH_PART (offset)), - reg, NULL, 0, OPTAB_WIDEN); - - return plus_constant (reg, CONST_LOW_PART (offset)); + { + rtx high; + if (TARGET_MIPS16) + { + /* Load the full offset into a register so that we can use + an unextended instruction for the address itself. */ + high = GEN_INT (offset); + offset = 0; + } + else + { + /* Leave OFFSET as a 16-bit offset and put the excess in HIGH. */ + high = GEN_INT (CONST_HIGH_PART (offset)); + offset = CONST_LOW_PART (offset); + } + high = mips_force_temporary (temp, high); + reg = mips_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg)); + } + return plus_constant (reg, offset); } @@ -1784,7 +1799,7 @@ mips_legitimize_address (rtx *xloc, enum machine_mode mode) reg = XEXP (*xloc, 0); if (!mips_valid_base_register_p (reg, mode, 0)) reg = copy_to_mode_reg (Pmode, reg); - *xloc = mips_add_offset (reg, INTVAL (XEXP (*xloc, 1))); + *xloc = mips_add_offset (0, reg, INTVAL (XEXP (*xloc, 1))); return true; } @@ -1962,7 +1977,7 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src) && (!no_new_pseudos || SMALL_OPERAND (offset))) { base = mips_force_temporary (dest, base); - emit_move_insn (dest, mips_add_offset (base, offset)); + emit_move_insn (dest, mips_add_offset (0, base, offset)); return; } @@ -2666,25 +2681,28 @@ mips_output_move (rtx dest, rtx src) abort (); } -/* Return an rtx for the gp save slot. Valid only when using o32 or +/* Restore $gp from its save slot. Valid only when using o32 or o64 abicalls. */ -rtx -mips_gp_save_slot (void) +void +mips_restore_gp (void) { - rtx loc; + rtx address, slot; - if (!TARGET_ABICALLS || TARGET_NEWABI) + if (!TARGET_ABICALLS || !TARGET_OLDABI) abort (); - if (frame_pointer_needed) - loc = hard_frame_pointer_rtx; - else - loc = stack_pointer_rtx; - loc = plus_constant (loc, current_function_outgoing_args_size); - loc = gen_rtx_MEM (Pmode, loc); - RTX_UNCHANGING_P (loc) = 1; - return loc; + address = mips_add_offset (pic_offset_table_rtx, + frame_pointer_needed + ? hard_frame_pointer_rtx + : stack_pointer_rtx, + current_function_outgoing_args_size); + slot = gen_rtx_MEM (Pmode, address); + RTX_UNCHANGING_P (slot) = 1; + + emit_move_insn (pic_offset_table_rtx, slot); + if (!TARGET_EXPLICIT_RELOCS) + emit_insn (gen_blockage ()); } /* Emit an instruction of the form (set TARGET (CODE OP0 OP1)). */ @@ -3101,26 +3119,15 @@ mips_emit_fcc_reload (rtx dest, rtx src, rtx scratch) void mips_set_return_address (rtx address, rtx scratch) { - HOST_WIDE_INT gp_offset; + rtx slot_address; compute_frame_size (get_frame_size ()); if (((cfun->machine->frame.mask >> 31) & 1) == 0) abort (); - gp_offset = cfun->machine->frame.gp_sp_offset; - - /* Reduce SP + GP_OFSET to a legitimate address and put it in SCRATCH. */ - if (gp_offset < 32768) - scratch = plus_constant (stack_pointer_rtx, gp_offset); - else - { - emit_move_insn (scratch, GEN_INT (gp_offset)); - if (Pmode == DImode) - emit_insn (gen_adddi3 (scratch, scratch, stack_pointer_rtx)); - else - emit_insn (gen_addsi3 (scratch, scratch, stack_pointer_rtx)); - } + slot_address = mips_add_offset (scratch, stack_pointer_rtx, + cfun->machine->frame.gp_sp_offset); - emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address); + emit_move_insn (gen_rtx_MEM (GET_MODE (address), slot_address), address); } /* Emit straight-line code to move LENGTH bytes from SRC to DEST. @@ -6773,25 +6780,7 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, emit_move_insn (temp1, gen_rtx_MEM (Pmode, this)); /* Set ADDR to a legitimate address for *THIS + VCALL_OFFSET. */ - if (SMALL_OPERAND (vcall_offset)) - addr = gen_rtx_PLUS (Pmode, temp1, GEN_INT (vcall_offset)); - else if (TARGET_MIPS16) - { - /* Load the full offset into a register so that we can use - an unextended instruction for the load itself. */ - emit_move_insn (temp2, GEN_INT (vcall_offset)); - emit_insn (gen_add3_insn (temp1, temp1, temp2)); - addr = temp1; - } - else - { - /* Load the high part of the offset into a register and - leave the low part for the address. */ - emit_move_insn (temp2, GEN_INT (CONST_HIGH_PART (vcall_offset))); - emit_insn (gen_add3_insn (temp1, temp1, temp2)); - addr = gen_rtx_PLUS (Pmode, temp1, - GEN_INT (CONST_LOW_PART (vcall_offset))); - } + addr = mips_add_offset (temp2, temp1, vcall_offset); /* Load the offset and add it to THIS. */ emit_move_insn (temp1, gen_rtx_MEM (Pmode, addr)); diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 407172d7963..586f12df177 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -6860,17 +6860,19 @@ dsrl\t%3,%3,1\n\ DONE; }) -(define_insn "exception_receiver" +(define_insn_and_split "exception_receiver" [(set (reg:SI 28) (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))] "TARGET_ABICALLS && TARGET_OLDABI" + "#" + "&& reload_completed" + [(const_int 0)] { - operands[0] = pic_offset_table_rtx; - operands[1] = mips_gp_save_slot (); - return mips_output_move (operands[0], operands[1]); + mips_restore_gp (); + DONE; } [(set_attr "type" "load") - (set_attr "length" "8")]) + (set_attr "length" "12")]) ;; ;; .................... @@ -7041,7 +7043,7 @@ dsrl\t%3,%3,1\n\ { emit_call_insn (gen_call_split (operands[0], operands[1])); if (!find_reg_note (operands[2], REG_NORETURN, 0)) - emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ()); + mips_restore_gp (); DONE; } [(set_attr "jal" "indirect,direct") @@ -7082,7 +7084,7 @@ dsrl\t%3,%3,1\n\ emit_call_insn (gen_call_value_split (operands[0], operands[1], operands[2])); if (!find_reg_note (operands[3], REG_NORETURN, 0)) - emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ()); + mips_restore_gp (); DONE; } [(set_attr "jal" "indirect,direct") @@ -7115,7 +7117,7 @@ dsrl\t%3,%3,1\n\ emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1], operands[2], operands[3])); if (!find_reg_note (operands[4], REG_NORETURN, 0)) - emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ()); + mips_restore_gp (); DONE; } [(set_attr "jal" "indirect,direct") -- 2.30.2