OSDN Git Service

gcc/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 17 Sep 2007 22:29:59 +0000 (22:29 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 17 Sep 2007 22:29:59 +0000 (22:29 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128560 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/mips/mips.c

index 636018d..3c57479 100644 (file)
@@ -1,5 +1,12 @@
 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.
 
 2007-09-17  Chao-ying Fu  <fu@mips.com>
index 5c26195..b285572 100644 (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.  */
+       mips_emit_loadgp ();
+       break;
 
-  /* 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 ();
+      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.  */