Commit b73ce23b by Richard Sandiford Committed by Richard Sandiford

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
parent b828123e
2004-08-01 Richard Sandiford <rsandifo@redhat.com>
* 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 <apinski@apple.com> 2004-07-31 Andrew Pinski <apinski@apple.com>
PR other/16842 PR other/16842
......
...@@ -121,7 +121,7 @@ extern rtx mips_subword (rtx, int); ...@@ -121,7 +121,7 @@ extern rtx mips_subword (rtx, int);
extern bool mips_split_64bit_move_p (rtx, rtx); extern bool mips_split_64bit_move_p (rtx, rtx);
extern void mips_split_64bit_move (rtx, rtx); extern void mips_split_64bit_move (rtx, rtx);
extern const char *mips_output_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 #ifdef RTX_CODE
extern bool mips_emit_scc (enum rtx_code, rtx); extern bool mips_emit_scc (enum rtx_code, rtx);
extern void gen_conditional_branch (rtx *, enum rtx_code); extern void gen_conditional_branch (rtx *, enum rtx_code);
......
...@@ -164,7 +164,7 @@ static bool mips16_unextended_reference_p (enum machine_mode mode, rtx, rtx); ...@@ -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_force_temporary (rtx, rtx);
static rtx mips_split_symbol (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_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_shift (struct mips_integer_op *, HOST_WIDE_INT);
static unsigned int mips_build_lower (struct mips_integer_op *, static unsigned int mips_build_lower (struct mips_integer_op *,
unsigned HOST_WIDE_INT); unsigned HOST_WIDE_INT);
...@@ -1742,18 +1742,33 @@ mips_unspec_offset_high (rtx temp, rtx base, rtx addr, ...@@ -1742,18 +1742,33 @@ mips_unspec_offset_high (rtx temp, rtx base, rtx addr,
} }
/* Return a legitimate address for REG + OFFSET. This function will /* Return a legitimate address for REG + OFFSET. TEMP is as for
create a temporary register if OFFSET is not a SMALL_OPERAND. */ mips_force_temporary; it is only needed when OFFSET is not a
SMALL_OPERAND. */
static rtx 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)) if (!SMALL_OPERAND (offset))
reg = expand_simple_binop (GET_MODE (reg), PLUS, {
GEN_INT (CONST_HIGH_PART (offset)), rtx high;
reg, NULL, 0, OPTAB_WIDEN); if (TARGET_MIPS16)
{
return plus_constant (reg, CONST_LOW_PART (offset)); /* 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) ...@@ -1784,7 +1799,7 @@ mips_legitimize_address (rtx *xloc, enum machine_mode mode)
reg = XEXP (*xloc, 0); reg = XEXP (*xloc, 0);
if (!mips_valid_base_register_p (reg, mode, 0)) if (!mips_valid_base_register_p (reg, mode, 0))
reg = copy_to_mode_reg (Pmode, reg); 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; return true;
} }
...@@ -1962,7 +1977,7 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src) ...@@ -1962,7 +1977,7 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
&& (!no_new_pseudos || SMALL_OPERAND (offset))) && (!no_new_pseudos || SMALL_OPERAND (offset)))
{ {
base = mips_force_temporary (dest, base); 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; return;
} }
...@@ -2666,25 +2681,28 @@ mips_output_move (rtx dest, rtx src) ...@@ -2666,25 +2681,28 @@ mips_output_move (rtx dest, rtx src)
abort (); 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. */ o64 abicalls. */
rtx void
mips_gp_save_slot (void) mips_restore_gp (void)
{ {
rtx loc; rtx address, slot;
if (!TARGET_ABICALLS || TARGET_NEWABI) if (!TARGET_ABICALLS || !TARGET_OLDABI)
abort (); abort ();
if (frame_pointer_needed) address = mips_add_offset (pic_offset_table_rtx,
loc = hard_frame_pointer_rtx; frame_pointer_needed
else ? hard_frame_pointer_rtx
loc = stack_pointer_rtx; : stack_pointer_rtx,
loc = plus_constant (loc, current_function_outgoing_args_size); current_function_outgoing_args_size);
loc = gen_rtx_MEM (Pmode, loc); slot = gen_rtx_MEM (Pmode, address);
RTX_UNCHANGING_P (loc) = 1; RTX_UNCHANGING_P (slot) = 1;
return loc;
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)). */ /* 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) ...@@ -3101,26 +3119,15 @@ mips_emit_fcc_reload (rtx dest, rtx src, rtx scratch)
void void
mips_set_return_address (rtx address, rtx scratch) mips_set_return_address (rtx address, rtx scratch)
{ {
HOST_WIDE_INT gp_offset; rtx slot_address;
compute_frame_size (get_frame_size ()); compute_frame_size (get_frame_size ());
if (((cfun->machine->frame.mask >> 31) & 1) == 0) if (((cfun->machine->frame.mask >> 31) & 1) == 0)
abort (); abort ();
gp_offset = cfun->machine->frame.gp_sp_offset; slot_address = mips_add_offset (scratch, stack_pointer_rtx,
cfun->machine->frame.gp_sp_offset);
/* Reduce SP + GP_OFSET to a legitimate address and put it in SCRATCH. */ emit_move_insn (gen_rtx_MEM (GET_MODE (address), slot_address), address);
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));
}
emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
} }
/* Emit straight-line code to move LENGTH bytes from SRC to DEST. /* 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, ...@@ -6773,25 +6780,7 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
emit_move_insn (temp1, gen_rtx_MEM (Pmode, this)); emit_move_insn (temp1, gen_rtx_MEM (Pmode, this));
/* Set ADDR to a legitimate address for *THIS + VCALL_OFFSET. */ /* Set ADDR to a legitimate address for *THIS + VCALL_OFFSET. */
if (SMALL_OPERAND (vcall_offset)) addr = mips_add_offset (temp2, temp1, 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)));
}
/* Load the offset and add it to THIS. */ /* Load the offset and add it to THIS. */
emit_move_insn (temp1, gen_rtx_MEM (Pmode, addr)); emit_move_insn (temp1, gen_rtx_MEM (Pmode, addr));
......
...@@ -6860,17 +6860,19 @@ dsrl\t%3,%3,1\n\ ...@@ -6860,17 +6860,19 @@ dsrl\t%3,%3,1\n\
DONE; DONE;
}) })
(define_insn "exception_receiver" (define_insn_and_split "exception_receiver"
[(set (reg:SI 28) [(set (reg:SI 28)
(unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))] (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
"TARGET_ABICALLS && TARGET_OLDABI" "TARGET_ABICALLS && TARGET_OLDABI"
"#"
"&& reload_completed"
[(const_int 0)]
{ {
operands[0] = pic_offset_table_rtx; mips_restore_gp ();
operands[1] = mips_gp_save_slot (); DONE;
return mips_output_move (operands[0], operands[1]);
} }
[(set_attr "type" "load") [(set_attr "type" "load")
(set_attr "length" "8")]) (set_attr "length" "12")])
;; ;;
;; .................... ;; ....................
...@@ -7041,7 +7043,7 @@ dsrl\t%3,%3,1\n\ ...@@ -7041,7 +7043,7 @@ dsrl\t%3,%3,1\n\
{ {
emit_call_insn (gen_call_split (operands[0], operands[1])); emit_call_insn (gen_call_split (operands[0], operands[1]));
if (!find_reg_note (operands[2], REG_NORETURN, 0)) if (!find_reg_note (operands[2], REG_NORETURN, 0))
emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ()); mips_restore_gp ();
DONE; DONE;
} }
[(set_attr "jal" "indirect,direct") [(set_attr "jal" "indirect,direct")
...@@ -7082,7 +7084,7 @@ dsrl\t%3,%3,1\n\ ...@@ -7082,7 +7084,7 @@ dsrl\t%3,%3,1\n\
emit_call_insn (gen_call_value_split (operands[0], operands[1], emit_call_insn (gen_call_value_split (operands[0], operands[1],
operands[2])); operands[2]));
if (!find_reg_note (operands[3], REG_NORETURN, 0)) if (!find_reg_note (operands[3], REG_NORETURN, 0))
emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ()); mips_restore_gp ();
DONE; DONE;
} }
[(set_attr "jal" "indirect,direct") [(set_attr "jal" "indirect,direct")
...@@ -7115,7 +7117,7 @@ dsrl\t%3,%3,1\n\ ...@@ -7115,7 +7117,7 @@ dsrl\t%3,%3,1\n\
emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1], emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
operands[2], operands[3])); operands[2], operands[3]));
if (!find_reg_note (operands[4], REG_NORETURN, 0)) if (!find_reg_note (operands[4], REG_NORETURN, 0))
emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ()); mips_restore_gp ();
DONE; DONE;
} }
[(set_attr "jal" "indirect,direct") [(set_attr "jal" "indirect,direct")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment