Commit f5678792 by Richard Sandiford Committed by Richard Sandiford

mips.c (mips_output_mi_thunk): Use mips_function_ok_for_sibcall and…

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
parent ec49e31c
2007-09-17 Richard Sandiford <rsandifo@nildram.co.uk> 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. * config/mips/mips.md (*clear_upper32): Use "W" as the memory operand.
2007-09-17 Chao-ying Fu <fu@mips.com> 2007-09-17 Chao-ying Fu <fu@mips.com>
...@@ -8872,6 +8872,7 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, ...@@ -8872,6 +8872,7 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
tree function) tree function)
{ {
rtx this, temp1, temp2, insn, fnaddr; rtx this, temp1, temp2, insn, fnaddr;
bool use_sibcall_p;
/* Pretend to be a post-reload pass while generating rtl. */ /* Pretend to be a post-reload pass while generating rtl. */
reload_completed = 1; reload_completed = 1;
...@@ -8879,22 +8880,30 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, ...@@ -8879,22 +8880,30 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
/* Mark the end of the (empty) prologue. */ /* Mark the end of the (empty) prologue. */
emit_note (NOTE_INSN_PROLOGUE_END); emit_note (NOTE_INSN_PROLOGUE_END);
/* Pick a global pointer. Use a call-clobbered register if /* Determine if we can use a sibcall to call FUNCTION directly. */
TARGET_CALL_SAVED_GP, so that we can use a sibcall. */ fnaddr = XEXP (DECL_RTL (function), 0);
if (TARGET_USE_GOT) use_sibcall_p = (mips_function_ok_for_sibcall (function, NULL)
&& const_call_insn_operand (fnaddr, Pmode));
/* 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 = cfun->machine->global_pointer =
TARGET_CALL_SAVED_GP ? 15 : GLOBAL_POINTER_REGNUM; TARGET_CALL_SAVED_GP ? 15 : GLOBAL_POINTER_REGNUM;
SET_REGNO (pic_offset_table_rtx, cfun->machine->global_pointer); SET_REGNO (pic_offset_table_rtx, cfun->machine->global_pointer);
}
/* Set up the global pointer for n32 or n64 abicalls. If /* Set up the global pointer for n32 or n64 abicalls. */
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 (); mips_emit_loadgp ();
break;
default:
break;
}
/* We need two temporary registers in some cases. */ /* We need two temporary registers in some cases. */
temp1 = gen_rtx_REG (Pmode, 2); temp1 = gen_rtx_REG (Pmode, 2);
...@@ -8936,9 +8945,12 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, ...@@ -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 /* Jump to the target function. Use a sibcall if direct jumps are
allowed, otherwise load the address into a register first. */ allowed, otherwise load the address into a register first. */
fnaddr = XEXP (DECL_RTL (function), 0); if (use_sibcall_p)
if (TARGET_MIPS16 || TARGET_USE_GOT || SYMBOL_REF_LONG_CALL_P (fnaddr) {
|| mips_use_mips16_mode_p (function)) 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 /* This is messy. gas treats "la $25,foo" as part of a call
sequence and may allow a global "foo" to be lazily bound. 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, ...@@ -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); mips_emit_move (gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM), temp1);
emit_jump_insn (gen_indirect_jump (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 /* Run just enough of rest_of_compilation. This sequence was
"borrowed" from alpha.c. */ "borrowed" from alpha.c. */
......
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