predicates.md (const_call_insn_operand): Allow direct calls to locally-defined functi...
authorRichard Sandiford <richard@codesourcery.com>
Tue, 21 Mar 2006 21:49:13 +0000 (21:49 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 21 Mar 2006 21:49:13 +0000 (21:49 +0000)
* config/mips/predicates.md (const_call_insn_operand): Allow direct
calls to locally-defined functions if TARGET_ABSOLUTE_ABICALLS.
* config/mips/mips.md (jal_macro): Test TARGET_ABSOLUTE_ABICALLS.
Use TARGET_OLDABI instead of !TARGET_NEWABI.
(loadgp): Use mips_current_loadgp_style.
(loadgp_noshared): New pattern.
(sibcall_internal): Use MIPS_CALL.
(sibcall_value_internal): Likewise.
(sibcall_value_multiple_internal): Likewise.
(call_internal): Likewise.
(call_value_internal): Likewise.
(call_value_multiple_internal): Likewise.
(call_split): Use MIPS_CALL and add an 'S' constraint.
(call_value_split): Likewise.
(call_value_multiple_split): Likewise.
* config/mips/mips.opt (-mabicalls): Tweak docstring.
(-mshared): New option.
* config/mips/mips-protos.h (mips_loadgp_style): New enum.
(mips_current_loadgp_style): Declare.
* config/mips/mips.c (mips_classify_symbol): Avoid using
SYMBOL_GOT_LOCAL if TARGET_ABSOLUTE_ABICALLS.  Use SYMBOL_GENERAL
rather than SYMBOL_GOT_GLOBAL for locally-binding symbols if
TARGET_ABSOLUTE_ABICALLS.
(override_options): Adjust comments.  Improve the warning that is
issued when -mabicalls and -G are used together.
(mips_file_start): Remove comment.
(mips_current_loadgp_style): New function.
(mips_gnu_local_gp): New variable.
(mips_emit_loadgp): Use mips_current_loadgp_style.  Handle
LOADGP_ABSOLUTE.
(mips_output_function_prologue): Use mips_current_laodgp_style.
(mips_expand_prologue): Call mips_emit_loadgp before emitting
the cprestore instruction.
(mips_extra_live_on_entry): Fix reversed test.  Don't make $25
live for TARGET_ABSOLUTE_ABICALLS.
* config/mips/mips.h (TARGET_ABSOLUTE_ABICALLS): New macro.
(ASM_SPEC): Pass down -mshared and -mno-shared.
(MIPS_CALL): New macro.
* config/mips/netbsd.h (TARGET_OS_CPP_BUILTINS): Remove __ABICALLS__
definition.
* doc/invoke.texi (-mabicalls): Update documentation.
(-mshared): Document.

From-SVN: r112261

gcc/ChangeLog
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/mips.md
gcc/config/mips/mips.opt
gcc/config/mips/predicates.md

index de9d0844275e15794fd764fb41e69b3ca80d6d6e..6b1c06eccd5571e25481682190de01c0534d9916 100644 (file)
@@ -1,3 +1,48 @@
+2006-03-21  Richard Sandiford  <richard@codesourcery.com>
+
+       * config/mips/predicates.md (const_call_insn_operand): Allow direct
+       calls to locally-defined functions if TARGET_ABSOLUTE_ABICALLS.
+       * config/mips/mips.md (jal_macro): Test TARGET_ABSOLUTE_ABICALLS.
+       Use TARGET_OLDABI instead of !TARGET_NEWABI.
+       (loadgp): Use mips_current_loadgp_style.
+       (loadgp_noshared): New pattern.
+       (sibcall_internal): Use MIPS_CALL.
+       (sibcall_value_internal): Likewise.
+       (sibcall_value_multiple_internal): Likewise.
+       (call_internal): Likewise.
+       (call_value_internal): Likewise.
+       (call_value_multiple_internal): Likewise.
+       (call_split): Use MIPS_CALL and add an 'S' constraint.
+       (call_value_split): Likewise.
+       (call_value_multiple_split): Likewise.
+       * config/mips/mips.opt (-mabicalls): Tweak docstring.
+       (-mshared): New option.
+       * config/mips/mips-protos.h (mips_loadgp_style): New enum.
+       (mips_current_loadgp_style): Declare.
+       * config/mips/mips.c (mips_classify_symbol): Avoid using
+       SYMBOL_GOT_LOCAL if TARGET_ABSOLUTE_ABICALLS.  Use SYMBOL_GENERAL
+       rather than SYMBOL_GOT_GLOBAL for locally-binding symbols if
+       TARGET_ABSOLUTE_ABICALLS.
+       (override_options): Adjust comments.  Improve the warning that is
+       issued when -mabicalls and -G are used together.
+       (mips_file_start): Remove comment.
+       (mips_current_loadgp_style): New function.
+       (mips_gnu_local_gp): New variable.
+       (mips_emit_loadgp): Use mips_current_loadgp_style.  Handle
+       LOADGP_ABSOLUTE.
+       (mips_output_function_prologue): Use mips_current_laodgp_style.
+       (mips_expand_prologue): Call mips_emit_loadgp before emitting
+       the cprestore instruction.
+       (mips_extra_live_on_entry): Fix reversed test.  Don't make $25
+       live for TARGET_ABSOLUTE_ABICALLS.
+       * config/mips/mips.h (TARGET_ABSOLUTE_ABICALLS): New macro.
+       (ASM_SPEC): Pass down -mshared and -mno-shared.
+       (MIPS_CALL): New macro.
+       * config/mips/netbsd.h (TARGET_OS_CPP_BUILTINS): Remove __ABICALLS__
+       definition.
+       * doc/invoke.texi (-mabicalls): Update documentation.
+       (-mshared): Document.
+
 2006-03-21  Steve Ellcey  <sje@cup.hp.com>
 
        * config/ia64/unwind-hpux.c: New file.
index b737375af6180bffeebc79306cf2fbc81b81fe44..60f81ada5aa4e0f24f3714d99b59b843065cdb86 100644 (file)
@@ -105,6 +105,28 @@ enum mips_symbol_type {
 };
 #define NUM_SYMBOL_TYPES (SYMBOL_64_LOW + 1)
 
+/* Identifiers a style of $gp initialization sequence.
+
+   LOADGP_NONE
+       No initialization sequence is needed.
+
+   LOADGP_OLDABI
+       The o32 and o64 PIC sequence (the kind traditionally generated
+       by .cpload).
+
+   LOADGP_NEWABI
+       The n32 and n64 PIC sequence (the kind traditionally generated
+       by .cpsetup).
+
+   LOADGP_ABSOLUTE
+       The GNU absolute sequence, as generated by loadgp_noshared.  */
+enum mips_loadgp_style {
+  LOADGP_NONE,
+  LOADGP_OLDABI,
+  LOADGP_NEWABI,
+  LOADGP_ABSOLUTE
+};
+
 extern bool mips_symbolic_constant_p (rtx, enum mips_symbol_type *);
 extern int mips_regno_mode_ok_for_base_p (int, enum machine_mode, int);
 extern bool mips_stack_address_p (rtx, enum machine_mode);
@@ -194,6 +216,7 @@ extern rtx mips_rewrite_small_data (rtx);
 extern HOST_WIDE_INT compute_frame_size (HOST_WIDE_INT);
 extern HOST_WIDE_INT mips_initial_elimination_offset (int, int);
 extern rtx mips_return_addr (int, rtx);
+extern enum mips_loadgp_style mips_current_loadgp_style (void);
 extern void mips_expand_prologue (void);
 extern void mips_expand_epilogue (int);
 extern int mips_can_use_return_insn (void);
index f907c01b0b3ef70b1849af6693c9b75e51b2fb78..ffe047ea0689ce93aad147d3220a92d1b6f90651 100644 (file)
@@ -1182,7 +1182,7 @@ mips_classify_symbol (rtx x)
     {
       if (TARGET_MIPS16)
        return SYMBOL_CONSTANT_POOL;
-      if (TARGET_ABICALLS)
+      if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS)
        return SYMBOL_GOT_LOCAL;
       return SYMBOL_GENERAL;
     }
@@ -1197,13 +1197,8 @@ mips_classify_symbol (rtx x)
       if (TARGET_MIPS16)
        return SYMBOL_CONSTANT_POOL;
 
-      if (TARGET_ABICALLS)
-       return SYMBOL_GOT_LOCAL;
-
       if (GET_MODE_SIZE (get_pool_mode (x)) <= mips_section_threshold)
        return SYMBOL_SMALL_DATA;
-
-      return SYMBOL_GENERAL;
     }
 
   if (SYMBOL_REF_SMALL_P (x))
@@ -1212,32 +1207,43 @@ mips_classify_symbol (rtx x)
   if (TARGET_ABICALLS)
     {
       if (SYMBOL_REF_DECL (x) == 0)
-       return SYMBOL_REF_LOCAL_P (x) ? SYMBOL_GOT_LOCAL : SYMBOL_GOT_GLOBAL;
-
-      /* There are three cases to consider:
-
-            - o32 PIC (either with or without explicit relocs)
-            - n32/n64 PIC without explicit relocs
-            - n32/n64 PIC with explicit relocs
-
-         In the first case, both local and global accesses will use an
-         R_MIPS_GOT16 relocation.  We must correctly predict which of
-         the two semantics (local or global) the assembler and linker
-         will apply.  The choice doesn't depend on the symbol's
-         visibility, so we deliberately ignore decl_visibility and
-         binds_local_p here.
-
-         In the second case, the assembler will not use R_MIPS_GOT16
-         relocations, but it chooses between local and global accesses
-         in the same way as for o32 PIC.
-
-         In the third case we have more freedom since both forms of
-         access will work for any kind of symbol.  However, there seems
-         little point in doing things differently.  */
-      if (DECL_P (SYMBOL_REF_DECL (x)) && TREE_PUBLIC (SYMBOL_REF_DECL (x)))
-       return SYMBOL_GOT_GLOBAL;
+       {
+         if (!SYMBOL_REF_LOCAL_P (x))
+           return SYMBOL_GOT_GLOBAL;
+       }
+      else
+       {
+         /* Don't use GOT accesses for locally-binding symbols if
+            TARGET_ABSOLUTE_ABICALLS.  Otherwise, there are three
+            cases to consider:
+
+               - o32 PIC (either with or without explicit relocs)
+               - n32/n64 PIC without explicit relocs
+               - n32/n64 PIC with explicit relocs
+
+            In the first case, both local and global accesses will use an
+            R_MIPS_GOT16 relocation.  We must correctly predict which of
+            the two semantics (local or global) the assembler and linker
+            will apply.  The choice doesn't depend on the symbol's
+            visibility, so we deliberately ignore decl_visibility and
+            binds_local_p here.
+
+            In the second case, the assembler will not use R_MIPS_GOT16
+            relocations, but it chooses between local and global accesses
+            in the same way as for o32 PIC.
+
+            In the third case we have more freedom since both forms of
+            access will work for any kind of symbol.  However, there seems
+            little point in doing things differently.  */
+         if (DECL_P (SYMBOL_REF_DECL (x))
+             && TREE_PUBLIC (SYMBOL_REF_DECL (x))
+             && !(TARGET_ABSOLUTE_ABICALLS
+                  && targetm.binds_local_p (SYMBOL_REF_DECL (x))))
+           return SYMBOL_GOT_GLOBAL;
+       }
 
-      return SYMBOL_GOT_LOCAL;
+      if (!TARGET_ABSOLUTE_ABICALLS)
+       return SYMBOL_GOT_LOCAL;
     }
 
   return SYMBOL_GENERAL;
@@ -4753,15 +4759,18 @@ override_options (void)
       target_flags &= ~MASK_ABICALLS;
     }
 
-  /* -fpic (-KPIC) is the default when TARGET_ABICALLS is defined.  We need
-     to set flag_pic so that the LEGITIMATE_PIC_OPERAND_P macro will work.  */
-  /* ??? -non_shared turns off pic code generation, but this is not
-     implemented.  */
   if (TARGET_ABICALLS)
     {
+      /* We need to set flag_pic for executables as well as DSOs
+        because we may reference symbols that are not defined in
+        the final executable.  (MIPS does not use things like
+        copy relocs, for example.)
+
+        Also, there is a body of code that uses __PIC__ to distinguish
+        between -mabicalls and -mno-abicalls code.  */
       flag_pic = 1;
       if (mips_section_threshold > 0)
-       warning (0, "-G is incompatible with PIC code which is the default");
+       warning (0, "%<-G%> is incompatible with %<-mabicalls%>");
     }
 
   /* mips_split_addresses is a half-way house between explicit
@@ -5797,7 +5806,6 @@ mips_file_start (void)
 
   /* Generate the pseudo ops that System V.4 wants.  */
   if (TARGET_ABICALLS)
-    /* ??? but do not want this (or want pic0) if -non-shared? */
     fprintf (asm_out_file, "\t.abicalls\n");
 
   if (TARGET_MIPS16)
@@ -6493,22 +6501,55 @@ mips_output_cplocal (void)
     output_asm_insn (".cplocal %+", 0);
 }
 
+/* Return the style of GP load sequence that is being used for the
+   current function.  */
+
+enum mips_loadgp_style
+mips_current_loadgp_style (void)
+{
+  if (!TARGET_ABICALLS || cfun->machine->global_pointer == 0)
+    return LOADGP_NONE;
+
+  if (TARGET_ABSOLUTE_ABICALLS)
+    return LOADGP_ABSOLUTE;
+
+  return TARGET_NEWABI ? LOADGP_NEWABI : LOADGP_OLDABI;
+}
+
+/* The __gnu_local_gp symbol.  */
+
+static GTY(()) rtx mips_gnu_local_gp;
+
 /* If we're generating n32 or n64 abicalls, emit instructions
    to set up the global pointer.  */
 
 static void
 mips_emit_loadgp (void)
 {
-  if (TARGET_ABICALLS && TARGET_NEWABI && cfun->machine->global_pointer > 0)
+  rtx addr, offset, incoming_address;
+
+  switch (mips_current_loadgp_style ())
     {
-      rtx addr, offset, incoming_address;
+    case LOADGP_ABSOLUTE:
+      if (mips_gnu_local_gp == NULL)
+       {
+         mips_gnu_local_gp = gen_rtx_SYMBOL_REF (Pmode, "__gnu_local_gp");
+         SYMBOL_REF_FLAGS (mips_gnu_local_gp) |= SYMBOL_FLAG_LOCAL;
+       }
+      emit_insn (gen_loadgp_noshared (mips_gnu_local_gp));
+      break;
 
+    case LOADGP_NEWABI:
       addr = XEXP (DECL_RTL (current_function_decl), 0);
       offset = mips_unspec_address (addr, SYMBOL_GOTOFF_LOADGP);
       incoming_address = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
       emit_insn (gen_loadgp (offset, incoming_address));
       if (!TARGET_EXPLICIT_RELOCS)
        emit_insn (gen_loadgp_blockage ());
+      break;
+
+    default:
+      break;
     }
 }
 
@@ -6588,7 +6629,7 @@ mips_output_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
         HIGHEST_GP_SAVED == *FRAMEREG + FRAMESIZE + GPOFFSET => can find saved regs.  */
     }
 
-  if (TARGET_ABICALLS && !TARGET_NEWABI && cfun->machine->global_pointer > 0)
+  if (mips_current_loadgp_style () == LOADGP_OLDABI)
     {
       /* Handle the initialization of $gp for SVR4 PIC.  */
       if (!cfun->machine->all_noreorder_p)
@@ -6775,12 +6816,12 @@ mips_expand_prologue (void)
                                             stack_pointer_rtx)) = 1;
     }
 
+  mips_emit_loadgp ();
+
   /* If generating o32/o64 abicalls, save $gp on the stack.  */
   if (TARGET_ABICALLS && !TARGET_NEWABI && !current_function_is_leaf)
     emit_insn (gen_cprestore (GEN_INT (current_function_outgoing_args_size)));
 
-  mips_emit_loadgp ();
-
   /* If we are profiling, make sure no instructions are scheduled before
      the call to mcount.  */
 
@@ -10674,13 +10715,13 @@ mips_encode_section_info (tree decl, rtx rtl, int first)
     }
 }
 
-/* Implement TARGET_EXTRA_LIVE_ON_ENTRY.  TARGET_ABICALLS makes
-   PIC_FUNCTION_ADDR_REGNUM live on entry to a function.  */
+/* Implement TARGET_EXTRA_LIVE_ON_ENTRY.  PIC_FUNCTION_ADDR_REGNUM is live
+   on entry to a function when generating -mshared abicalls code.  */
 
 static void
 mips_extra_live_on_entry (bitmap regs)
 {
-  if (!TARGET_ABICALLS)
+  if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS)
     bitmap_set_bit (regs, PIC_FUNCTION_ADDR_REGNUM);
 }
 
index 51d383c59cf536da052fbd1632417810dc99b18b..3823963ebacaf940bb11d35d0b2fefcdcfd68c03 100644 (file)
@@ -149,6 +149,19 @@ extern const struct mips_rtx_cost_data *mips_cost;
 #define TARGET_SPLIT_CALLS \
   (TARGET_EXPLICIT_RELOCS && TARGET_ABICALLS && !TARGET_NEWABI)
 
+/* True if we're generating a form of -mabicalls in which we can use
+   operators like %hi and %lo to refer to locally-binding symbols.
+   We can only do this for -mno-shared, and only then if we can use
+   relocation operations instead of assembly macros.  It isn't really
+   worth using absolute sequences for 64-bit symbols because GOT
+   accesses are so much shorter.  */
+
+#define TARGET_ABSOLUTE_ABICALLS       \
+  (TARGET_ABICALLS                     \
+   && !TARGET_SHARED                   \
+   && TARGET_EXPLICIT_RELOCS           \
+   && !ABI_HAS_64BIT_SYMBOLS)
+
 /* True if we can optimize sibling calls.  For simplicity, we only
    handle cases in which call_insn_operand will reject invalid
    sibcall addresses.  There are two cases in which this isn't true:
@@ -820,6 +833,7 @@ extern const struct mips_rtx_cost_data *mips_cost;
 %(subtarget_asm_debugging_spec) \
 %{mabi=*} %{!mabi*: %(asm_abi_default_spec)} \
 %{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} \
+%{mshared} %{mno-shared} \
 %{msym32} %{mno-sym32} \
 %{mtune=*} %{v} \
 %(subtarget_asm_spec)"
@@ -2281,6 +2295,26 @@ typedef struct mips_args {
    its operands.  */
 #define MIPS_BRANCH(OPCODE, OPERANDS) \
   "%*" OPCODE "%?\t" OPERANDS "%/"
+
+/* Return the asm template for a call.  INSN is the instruction's mnemonic
+   ("j" or "jal"), OPERANDS are its operands, and OPNO is the operand number
+   of the target.
+
+   When generating -mabicalls without explicit relocation operators,
+   all calls should use assembly macros.  Otherwise, all indirect
+   calls should use "jr" or "jalr"; we will arrange to restore $gp
+   afterwards if necessary.  Finally, we can only generate direct
+   calls for -mabicalls by temporarily switching to non-PIC mode.  */
+#define MIPS_CALL(INSN, OPERANDS, OPNO)                                \
+  (TARGET_ABICALLS && !TARGET_EXPLICIT_RELOCS                  \
+   ? "%*" INSN "\t%" #OPNO "%/"                                        \
+   : REG_P (OPERANDS[OPNO])                                    \
+   ? "%*" INSN "r\t%" #OPNO "%/"                               \
+   : TARGET_ABICALLS                                           \
+   ? (".option\tpic0\n\t"                                      \
+      "%*" INSN "\t%" #OPNO "%/\n\t"                           \
+      ".option\tpic2")                                         \
+   : "%*" INSN "\t%" #OPNO "%/")
 \f
 /* Control the assembler format that we output.  */
 
index ce2cce650acb277e649392114ec1f9f4726a3343..32d0c4186974cc2a7559ada411bc8fbda9566a4d 100644 (file)
 ;; This attribute is YES if the instruction is a jal macro (not a
 ;; real jal instruction).
 ;;
-;; jal is always a macro in SVR4 PIC since it includes an instruction to
-;; restore $gp.  Direct jals are also macros in NewABI PIC since they
-;; load the target address into $25.
+;; jal is always a macro for o32 and o64 abicalls because it includes an
+;; instruction to restore $gp.  Direct jals are also macros for -mshared
+;; abicalls because they first load the target address into $25.
 (define_attr "jal_macro" "no,yes"
   (cond [(eq_attr "jal" "direct")
-        (symbol_ref "TARGET_ABICALLS != 0")
+        (symbol_ref "TARGET_ABICALLS
+                     && (TARGET_OLDABI || !TARGET_ABSOLUTE_ABICALLS)")
         (eq_attr "jal" "indirect")
-        (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
+        (symbol_ref "TARGET_ABICALLS && TARGET_OLDABI")]
        (const_string "no")))
 
 ;; Classification of each insn.
 (define_insn_and_split "loadgp"
   [(unspec_volatile [(match_operand 0 "" "")
                     (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
-  "TARGET_ABICALLS && TARGET_NEWABI"
+  "mips_current_loadgp_style () == LOADGP_NEWABI"
   "#"
   ""
   [(set (match_dup 2) (match_dup 3))
 }
   [(set_attr "length" "12")])
 
+;; Likewise, for -mno-shared code.  Operand 0 is the __gnu_local_gp symbol.
+(define_insn_and_split "loadgp_noshared"
+  [(unspec_volatile [(match_operand 0 "" "")] UNSPEC_LOADGP)]
+  "mips_current_loadgp_style () == LOADGP_ABSOLUTE"
+  "#"
+  ""
+  [(const_int 0)]
+{
+  emit_move_insn (pic_offset_table_rtx, operands[0]);
+  DONE;
+}
+  [(set_attr "length" "8")])
+
 ;; The use of gp is hidden when not using explicit relocations.
 ;; This blockage instruction prevents the gp load from being
 ;; scheduled after an implicit use of gp.  It also prevents
   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
         (match_operand 1 "" ""))]
   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
-  "@
-    %*jr\t%0%/
-    %*j\t%0%/"
+  { return MIPS_CALL ("j", operands, 0); }
   [(set_attr "type" "call")])
 
 (define_expand "sibcall_value"
         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
               (match_operand 2 "" "")))]
   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
-  "@
-    %*jr\t%1%/
-    %*j\t%1%/"
+  { return MIPS_CALL ("j", operands, 1); }
   [(set_attr "type" "call")])
 
 (define_insn "sibcall_value_multiple_internal"
        (call (mem:SI (match_dup 1))
              (match_dup 2)))]
   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
-  "@
-    %*jr\t%1%/
-    %*j\t%1%/"
+  { return MIPS_CALL ("j", operands, 1); }
   [(set_attr "type" "call")])
 
 (define_expand "call"
         (match_operand 1 "" ""))
    (clobber (reg:SI 31))]
   ""
-  { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
+  { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0); }
   "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
   [(const_int 0)]
 {
    (set_attr "extended_mips16" "no,yes")])
 
 (define_insn "call_split"
-  [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
+  [(call (mem:SI (match_operand 0 "call_insn_operand" "cS"))
         (match_operand 1 "" ""))
    (clobber (reg:SI 31))
    (clobber (reg:SI 28))]
   "TARGET_SPLIT_CALLS"
-  "%*jalr\t%0%/"
+  { return MIPS_CALL ("jal", operands, 0); }
   [(set_attr "type" "call")])
 
 (define_expand "call_value"
               (match_operand 2 "" "")))
    (clobber (reg:SI 31))]
   ""
-  { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
+  { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
   "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
   [(const_int 0)]
 {
 
 (define_insn "call_value_split"
   [(set (match_operand 0 "register_operand" "=df")
-        (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
+        (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
               (match_operand 2 "" "")))
    (clobber (reg:SI 31))
    (clobber (reg:SI 28))]
   "TARGET_SPLIT_CALLS"
-  "%*jalr\t%1%/"
+  { return MIPS_CALL ("jal", operands, 1); }
   [(set_attr "type" "call")])
 
 ;; See comment for call_internal.
              (match_dup 2)))
    (clobber (reg:SI 31))]
   ""
-  { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
+  { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
   "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
   [(const_int 0)]
 {
 
 (define_insn "call_value_multiple_split"
   [(set (match_operand 0 "register_operand" "=df")
-        (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
+        (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
               (match_operand 2 "" "")))
    (set (match_operand 3 "register_operand" "=df")
        (call (mem:SI (match_dup 1))
    (clobber (reg:SI 31))
    (clobber (reg:SI 28))]
   "TARGET_SPLIT_CALLS"
-  "%*jalr\t%1%/"
+  { return MIPS_CALL ("jal", operands, 1); }
   [(set_attr "type" "call")])
 
 ;; Call subroutine returning any type.
index 737f5edecb1881a06dcfcae824ae13544aa45702..7f8214bb1468845853e50d70561aecb2732a8437 100644 (file)
@@ -25,7 +25,7 @@ Target RejectNegative Joined
 
 mabicalls
 Target Report Mask(ABICALLS)
-Use SVR4-style PIC
+Generate code that can be used in SVR4-style dynamic objects
 
 mad
 Target Report Var(TARGET_MAD)
@@ -185,6 +185,10 @@ mpaired-single
 Target Report Mask(PAIRED_SINGLE_FLOAT)
 Use paired-single floating-point instructions
 
+mshared
+Target Report Var(TARGET_SHARED) Init(1)
+When generating -mabicalls code, make the code suitable for use in shared libraries
+
 msingle-float
 Target Report RejectNegative Mask(SINGLE_FLOAT)
 Restrict the use of hardware floating-point instructions to 32-bit operations
index 23e85d82be8d09343b051dea62915e78d2a2238b..9a6756c20a2f43769144efabbca968c8c8556b1e 100644 (file)
   switch (symbol_type)
     {
     case SYMBOL_GENERAL:
+      /* We can only use direct calls for TARGET_ABSOLUTE_ABICALLS if we
+        are sure that the target function does not need $25 to be live
+        on entry.  This is true for any locally-defined function because
+        any such function will use %hi/%lo accesses to set up $gp.  */
+      if (TARGET_ABSOLUTE_ABICALLS
+          && !(GET_CODE (op) == SYMBOL_REF
+              && SYMBOL_REF_DECL (op)
+              && !DECL_EXTERNAL (SYMBOL_REF_DECL (op))))
+       return false;
+
       /* If -mlong-calls, force all calls to use register addressing.  Also,
         if this function has the long_call attribute, we must use register
         addressing.  */