aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mips
diff options
context:
space:
mode:
authorRichard Sandiford <richard@codesourcery.com>2006-03-21 21:49:13 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2006-03-21 21:49:13 +0000
commitd9870b7ef4d6cbc588da427a64b022139df0708d (patch)
tree16c45bc0cafdad54bcfc9ce0a93a731a67ef690a /gcc/config/mips
parent487d9a61530a00accfe91cd54598e23608580fe7 (diff)
downloadgcc-d9870b7ef4d6cbc588da427a64b022139df0708d.zip
gcc-d9870b7ef4d6cbc588da427a64b022139df0708d.tar.gz
gcc-d9870b7ef4d6cbc588da427a64b022139df0708d.tar.bz2
predicates.md (const_call_insn_operand): Allow direct calls to locally-defined functions if TARGET_ABSOLUTE_ABICALLS.
* 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
Diffstat (limited to 'gcc/config/mips')
-rw-r--r--gcc/config/mips/mips-protos.h23
-rw-r--r--gcc/config/mips/mips.c131
-rw-r--r--gcc/config/mips/mips.h34
-rw-r--r--gcc/config/mips/mips.md56
-rw-r--r--gcc/config/mips/mips.opt6
-rw-r--r--gcc/config/mips/predicates.md10
6 files changed, 190 insertions, 70 deletions
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index b737375..60f81ad 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -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);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index f907c01..ffe047e 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -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);
}
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 51d383c..3823963 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -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 "%/")
/* Control the assembler format that we output. */
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index ce2cce6..32d0c41 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -166,14 +166,15 @@
;; 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.
@@ -3982,7 +3983,7 @@
(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))
@@ -3996,6 +3997,19 @@
}
[(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
@@ -5060,9 +5074,7 @@
[(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"
@@ -5082,9 +5094,7 @@
(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"
@@ -5095,9 +5105,7 @@
(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"
@@ -5153,7 +5161,7 @@
(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)]
{
@@ -5166,12 +5174,12 @@
(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"
@@ -5193,7 +5201,7 @@
(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)]
{
@@ -5208,12 +5216,12 @@
(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.
@@ -5226,7 +5234,7 @@
(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)]
{
@@ -5241,7 +5249,7 @@
(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))
@@ -5249,7 +5257,7 @@
(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.
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index 737f5ed..7f8214b 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -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
diff --git a/gcc/config/mips/predicates.md b/gcc/config/mips/predicates.md
index 23e85d8..9a6756c 100644
--- a/gcc/config/mips/predicates.md
+++ b/gcc/config/mips/predicates.md
@@ -103,6 +103,16 @@
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. */