mips.c (mips_output_mi_thunk): Use mips_function_ok_for_sibcall and const_call_insn_operand to determine if...

gcc/
	* config/mips/mips.c (mips_output_mi_thunk): Use
	mips_function_ok_for_sibcall and const_call_insn_operand
	to determine if a direct sibcall is allowed.  Use
	mips_classify_symbol to determine a global pointer is needed.

From-SVN: r128560
This commit is contained in:
Richard Sandiford 2007-09-17 22:29:59 +00:00 committed by Richard Sandiford
parent ec49e31c8f
commit f5678792a3
2 changed files with 36 additions and 22 deletions

View File

@ -1,3 +1,10 @@
2007-09-17 Richard Sandiford <rsandifo@nildram.co.uk>
* config/mips/mips.c (mips_output_mi_thunk): Use
mips_function_ok_for_sibcall and const_call_insn_operand
to determine if a direct sibcall is allowed. Use
mips_classify_symbol to determine a global pointer is needed.
2007-09-17 Richard Sandiford <rsandifo@nildram.co.uk>
* config/mips/mips.md (*clear_upper32): Use "W" as the memory operand.

View File

@ -8872,6 +8872,7 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
tree function)
{
rtx this, temp1, temp2, insn, fnaddr;
bool use_sibcall_p;
/* Pretend to be a post-reload pass while generating rtl. */
reload_completed = 1;
@ -8879,22 +8880,30 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
/* Mark the end of the (empty) prologue. */
emit_note (NOTE_INSN_PROLOGUE_END);
/* Pick a global pointer. Use a call-clobbered register if
TARGET_CALL_SAVED_GP, so that we can use a sibcall. */
if (TARGET_USE_GOT)
{
cfun->machine->global_pointer =
TARGET_CALL_SAVED_GP ? 15 : GLOBAL_POINTER_REGNUM;
/* Determine if we can use a sibcall to call FUNCTION directly. */
fnaddr = XEXP (DECL_RTL (function), 0);
use_sibcall_p = (mips_function_ok_for_sibcall (function, NULL)
&& const_call_insn_operand (fnaddr, Pmode));
SET_REGNO (pic_offset_table_rtx, cfun->machine->global_pointer);
}
/* Determine if we need to load FNADDR from the GOT. */
if (!use_sibcall_p)
switch (mips_classify_symbol (fnaddr, SYMBOL_CONTEXT_LEA))
{
case SYMBOL_GOT_PAGE_OFST:
case SYMBOL_GOT_DISP:
/* Pick a global pointer. Use a call-clobbered register if
TARGET_CALL_SAVED_GP. */
cfun->machine->global_pointer =
TARGET_CALL_SAVED_GP ? 15 : GLOBAL_POINTER_REGNUM;
SET_REGNO (pic_offset_table_rtx, cfun->machine->global_pointer);
/* Set up the global pointer for n32 or n64 abicalls. If
LOADGP_ABSOLUTE then the thunk does not use the gp and there is
no need to load it.*/
if (mips_current_loadgp_style () != LOADGP_ABSOLUTE
|| !targetm.binds_local_p (function))
mips_emit_loadgp ();
/* Set up the global pointer for n32 or n64 abicalls. */
mips_emit_loadgp ();
break;
default:
break;
}
/* We need two temporary registers in some cases. */
temp1 = gen_rtx_REG (Pmode, 2);
@ -8936,9 +8945,12 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
/* Jump to the target function. Use a sibcall if direct jumps are
allowed, otherwise load the address into a register first. */
fnaddr = XEXP (DECL_RTL (function), 0);
if (TARGET_MIPS16 || TARGET_USE_GOT || SYMBOL_REF_LONG_CALL_P (fnaddr)
|| mips_use_mips16_mode_p (function))
if (use_sibcall_p)
{
insn = emit_call_insn (gen_sibcall_internal (fnaddr, const0_rtx));
SIBLING_CALL_P (insn) = 1;
}
else
{
/* This is messy. gas treats "la $25,foo" as part of a call
sequence and may allow a global "foo" to be lazily bound.
@ -8962,11 +8974,6 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
mips_emit_move (gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM), temp1);
emit_jump_insn (gen_indirect_jump (temp1));
}
else
{
insn = emit_call_insn (gen_sibcall_internal (fnaddr, const0_rtx));
SIBLING_CALL_P (insn) = 1;
}
/* Run just enough of rest_of_compilation. This sequence was
"borrowed" from alpha.c. */