Commit d9870b7e by Richard Sandiford Committed by Richard Sandiford

predicates.md (const_call_insn_operand): Allow direct calls to locally-defined…

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
parent 487d9a61
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> 2006-03-21 Steve Ellcey <sje@cup.hp.com>
* config/ia64/unwind-hpux.c: New file. * config/ia64/unwind-hpux.c: New file.
......
...@@ -105,6 +105,28 @@ enum mips_symbol_type { ...@@ -105,6 +105,28 @@ enum mips_symbol_type {
}; };
#define NUM_SYMBOL_TYPES (SYMBOL_64_LOW + 1) #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 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 int mips_regno_mode_ok_for_base_p (int, enum machine_mode, int);
extern bool mips_stack_address_p (rtx, enum machine_mode); extern bool mips_stack_address_p (rtx, enum machine_mode);
...@@ -194,6 +216,7 @@ extern rtx mips_rewrite_small_data (rtx); ...@@ -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 compute_frame_size (HOST_WIDE_INT);
extern HOST_WIDE_INT mips_initial_elimination_offset (int, int); extern HOST_WIDE_INT mips_initial_elimination_offset (int, int);
extern rtx mips_return_addr (int, rtx); 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_prologue (void);
extern void mips_expand_epilogue (int); extern void mips_expand_epilogue (int);
extern int mips_can_use_return_insn (void); extern int mips_can_use_return_insn (void);
......
...@@ -1182,7 +1182,7 @@ mips_classify_symbol (rtx x) ...@@ -1182,7 +1182,7 @@ mips_classify_symbol (rtx x)
{ {
if (TARGET_MIPS16) if (TARGET_MIPS16)
return SYMBOL_CONSTANT_POOL; return SYMBOL_CONSTANT_POOL;
if (TARGET_ABICALLS) if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS)
return SYMBOL_GOT_LOCAL; return SYMBOL_GOT_LOCAL;
return SYMBOL_GENERAL; return SYMBOL_GENERAL;
} }
...@@ -1197,13 +1197,8 @@ mips_classify_symbol (rtx x) ...@@ -1197,13 +1197,8 @@ mips_classify_symbol (rtx x)
if (TARGET_MIPS16) if (TARGET_MIPS16)
return SYMBOL_CONSTANT_POOL; return SYMBOL_CONSTANT_POOL;
if (TARGET_ABICALLS)
return SYMBOL_GOT_LOCAL;
if (GET_MODE_SIZE (get_pool_mode (x)) <= mips_section_threshold) if (GET_MODE_SIZE (get_pool_mode (x)) <= mips_section_threshold)
return SYMBOL_SMALL_DATA; return SYMBOL_SMALL_DATA;
return SYMBOL_GENERAL;
} }
if (SYMBOL_REF_SMALL_P (x)) if (SYMBOL_REF_SMALL_P (x))
...@@ -1212,32 +1207,43 @@ mips_classify_symbol (rtx x) ...@@ -1212,32 +1207,43 @@ mips_classify_symbol (rtx x)
if (TARGET_ABICALLS) if (TARGET_ABICALLS)
{ {
if (SYMBOL_REF_DECL (x) == 0) if (SYMBOL_REF_DECL (x) == 0)
return SYMBOL_REF_LOCAL_P (x) ? SYMBOL_GOT_LOCAL : SYMBOL_GOT_GLOBAL; {
if (!SYMBOL_REF_LOCAL_P (x))
/* There are three cases to consider: return SYMBOL_GOT_GLOBAL;
}
- o32 PIC (either with or without explicit relocs) else
- n32/n64 PIC without explicit relocs {
- n32/n64 PIC with explicit relocs /* Don't use GOT accesses for locally-binding symbols if
TARGET_ABSOLUTE_ABICALLS. Otherwise, there are three
In the first case, both local and global accesses will use an cases to consider:
R_MIPS_GOT16 relocation. We must correctly predict which of
the two semantics (local or global) the assembler and linker - o32 PIC (either with or without explicit relocs)
will apply. The choice doesn't depend on the symbol's - n32/n64 PIC without explicit relocs
visibility, so we deliberately ignore decl_visibility and - n32/n64 PIC with explicit relocs
binds_local_p here.
In the first case, both local and global accesses will use an
In the second case, the assembler will not use R_MIPS_GOT16 R_MIPS_GOT16 relocation. We must correctly predict which of
relocations, but it chooses between local and global accesses the two semantics (local or global) the assembler and linker
in the same way as for o32 PIC. will apply. The choice doesn't depend on the symbol's
visibility, so we deliberately ignore decl_visibility and
In the third case we have more freedom since both forms of binds_local_p here.
access will work for any kind of symbol. However, there seems
little point in doing things differently. */ In the second case, the assembler will not use R_MIPS_GOT16
if (DECL_P (SYMBOL_REF_DECL (x)) && TREE_PUBLIC (SYMBOL_REF_DECL (x))) relocations, but it chooses between local and global accesses
return SYMBOL_GOT_GLOBAL; 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; return SYMBOL_GENERAL;
...@@ -4753,15 +4759,18 @@ override_options (void) ...@@ -4753,15 +4759,18 @@ override_options (void)
target_flags &= ~MASK_ABICALLS; 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) 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; flag_pic = 1;
if (mips_section_threshold > 0) 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 /* mips_split_addresses is a half-way house between explicit
...@@ -5797,7 +5806,6 @@ mips_file_start (void) ...@@ -5797,7 +5806,6 @@ mips_file_start (void)
/* Generate the pseudo ops that System V.4 wants. */ /* Generate the pseudo ops that System V.4 wants. */
if (TARGET_ABICALLS) if (TARGET_ABICALLS)
/* ??? but do not want this (or want pic0) if -non-shared? */
fprintf (asm_out_file, "\t.abicalls\n"); fprintf (asm_out_file, "\t.abicalls\n");
if (TARGET_MIPS16) if (TARGET_MIPS16)
...@@ -6493,22 +6501,55 @@ mips_output_cplocal (void) ...@@ -6493,22 +6501,55 @@ mips_output_cplocal (void)
output_asm_insn (".cplocal %+", 0); 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 /* If we're generating n32 or n64 abicalls, emit instructions
to set up the global pointer. */ to set up the global pointer. */
static void static void
mips_emit_loadgp (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); addr = XEXP (DECL_RTL (current_function_decl), 0);
offset = mips_unspec_address (addr, SYMBOL_GOTOFF_LOADGP); offset = mips_unspec_address (addr, SYMBOL_GOTOFF_LOADGP);
incoming_address = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM); incoming_address = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
emit_insn (gen_loadgp (offset, incoming_address)); emit_insn (gen_loadgp (offset, incoming_address));
if (!TARGET_EXPLICIT_RELOCS) if (!TARGET_EXPLICIT_RELOCS)
emit_insn (gen_loadgp_blockage ()); emit_insn (gen_loadgp_blockage ());
break;
default:
break;
} }
} }
...@@ -6588,7 +6629,7 @@ mips_output_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED) ...@@ -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. */ 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. */ /* Handle the initialization of $gp for SVR4 PIC. */
if (!cfun->machine->all_noreorder_p) if (!cfun->machine->all_noreorder_p)
...@@ -6775,12 +6816,12 @@ mips_expand_prologue (void) ...@@ -6775,12 +6816,12 @@ mips_expand_prologue (void)
stack_pointer_rtx)) = 1; stack_pointer_rtx)) = 1;
} }
mips_emit_loadgp ();
/* If generating o32/o64 abicalls, save $gp on the stack. */ /* If generating o32/o64 abicalls, save $gp on the stack. */
if (TARGET_ABICALLS && !TARGET_NEWABI && !current_function_is_leaf) if (TARGET_ABICALLS && !TARGET_NEWABI && !current_function_is_leaf)
emit_insn (gen_cprestore (GEN_INT (current_function_outgoing_args_size))); 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 /* If we are profiling, make sure no instructions are scheduled before
the call to mcount. */ the call to mcount. */
...@@ -10674,13 +10715,13 @@ mips_encode_section_info (tree decl, rtx rtl, int first) ...@@ -10674,13 +10715,13 @@ mips_encode_section_info (tree decl, rtx rtl, int first)
} }
} }
/* Implement TARGET_EXTRA_LIVE_ON_ENTRY. TARGET_ABICALLS makes /* Implement TARGET_EXTRA_LIVE_ON_ENTRY. PIC_FUNCTION_ADDR_REGNUM is live
PIC_FUNCTION_ADDR_REGNUM live on entry to a function. */ on entry to a function when generating -mshared abicalls code. */
static void static void
mips_extra_live_on_entry (bitmap regs) mips_extra_live_on_entry (bitmap regs)
{ {
if (!TARGET_ABICALLS) if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS)
bitmap_set_bit (regs, PIC_FUNCTION_ADDR_REGNUM); bitmap_set_bit (regs, PIC_FUNCTION_ADDR_REGNUM);
} }
......
...@@ -149,6 +149,19 @@ extern const struct mips_rtx_cost_data *mips_cost; ...@@ -149,6 +149,19 @@ extern const struct mips_rtx_cost_data *mips_cost;
#define TARGET_SPLIT_CALLS \ #define TARGET_SPLIT_CALLS \
(TARGET_EXPLICIT_RELOCS && TARGET_ABICALLS && !TARGET_NEWABI) (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 /* True if we can optimize sibling calls. For simplicity, we only
handle cases in which call_insn_operand will reject invalid handle cases in which call_insn_operand will reject invalid
sibcall addresses. There are two cases in which this isn't true: 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; ...@@ -820,6 +833,7 @@ extern const struct mips_rtx_cost_data *mips_cost;
%(subtarget_asm_debugging_spec) \ %(subtarget_asm_debugging_spec) \
%{mabi=*} %{!mabi*: %(asm_abi_default_spec)} \ %{mabi=*} %{!mabi*: %(asm_abi_default_spec)} \
%{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} \ %{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} \
%{mshared} %{mno-shared} \
%{msym32} %{mno-sym32} \ %{msym32} %{mno-sym32} \
%{mtune=*} %{v} \ %{mtune=*} %{v} \
%(subtarget_asm_spec)" %(subtarget_asm_spec)"
...@@ -2281,6 +2295,26 @@ typedef struct mips_args { ...@@ -2281,6 +2295,26 @@ typedef struct mips_args {
its operands. */ its operands. */
#define MIPS_BRANCH(OPCODE, OPERANDS) \ #define MIPS_BRANCH(OPCODE, OPERANDS) \
"%*" OPCODE "%?\t" 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. */ /* Control the assembler format that we output. */
......
...@@ -166,14 +166,15 @@ ...@@ -166,14 +166,15 @@
;; This attribute is YES if the instruction is a jal macro (not a ;; This attribute is YES if the instruction is a jal macro (not a
;; real jal instruction). ;; real jal instruction).
;; ;;
;; jal is always a macro in SVR4 PIC since it includes an instruction to ;; jal is always a macro for o32 and o64 abicalls because it includes an
;; restore $gp. Direct jals are also macros in NewABI PIC since they ;; instruction to restore $gp. Direct jals are also macros for -mshared
;; load the target address into $25. ;; abicalls because they first load the target address into $25.
(define_attr "jal_macro" "no,yes" (define_attr "jal_macro" "no,yes"
(cond [(eq_attr "jal" "direct") (cond [(eq_attr "jal" "direct")
(symbol_ref "TARGET_ABICALLS != 0") (symbol_ref "TARGET_ABICALLS
&& (TARGET_OLDABI || !TARGET_ABSOLUTE_ABICALLS)")
(eq_attr "jal" "indirect") (eq_attr "jal" "indirect")
(symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")] (symbol_ref "TARGET_ABICALLS && TARGET_OLDABI")]
(const_string "no"))) (const_string "no")))
;; Classification of each insn. ;; Classification of each insn.
...@@ -3982,7 +3983,7 @@ ...@@ -3982,7 +3983,7 @@
(define_insn_and_split "loadgp" (define_insn_and_split "loadgp"
[(unspec_volatile [(match_operand 0 "" "") [(unspec_volatile [(match_operand 0 "" "")
(match_operand 1 "register_operand" "")] UNSPEC_LOADGP)] (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 (match_dup 2) (match_dup 3))
...@@ -3996,6 +3997,19 @@ ...@@ -3996,6 +3997,19 @@
} }
[(set_attr "length" "12")]) [(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. ;; The use of gp is hidden when not using explicit relocations.
;; This blockage instruction prevents the gp load from being ;; This blockage instruction prevents the gp load from being
;; scheduled after an implicit use of gp. It also prevents ;; scheduled after an implicit use of gp. It also prevents
...@@ -5060,9 +5074,7 @@ ...@@ -5060,9 +5074,7 @@
[(call (mem:SI (match_operand 0 "call_insn_operand" "j,S")) [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
(match_operand 1 "" ""))] (match_operand 1 "" ""))]
"TARGET_SIBCALLS && SIBLING_CALL_P (insn)" "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
"@ { return MIPS_CALL ("j", operands, 0); }
%*jr\t%0%/
%*j\t%0%/"
[(set_attr "type" "call")]) [(set_attr "type" "call")])
(define_expand "sibcall_value" (define_expand "sibcall_value"
...@@ -5082,9 +5094,7 @@ ...@@ -5082,9 +5094,7 @@
(call (mem:SI (match_operand 1 "call_insn_operand" "j,S")) (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
(match_operand 2 "" "")))] (match_operand 2 "" "")))]
"TARGET_SIBCALLS && SIBLING_CALL_P (insn)" "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
"@ { return MIPS_CALL ("j", operands, 1); }
%*jr\t%1%/
%*j\t%1%/"
[(set_attr "type" "call")]) [(set_attr "type" "call")])
(define_insn "sibcall_value_multiple_internal" (define_insn "sibcall_value_multiple_internal"
...@@ -5095,9 +5105,7 @@ ...@@ -5095,9 +5105,7 @@
(call (mem:SI (match_dup 1)) (call (mem:SI (match_dup 1))
(match_dup 2)))] (match_dup 2)))]
"TARGET_SIBCALLS && SIBLING_CALL_P (insn)" "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
"@ { return MIPS_CALL ("j", operands, 1); }
%*jr\t%1%/
%*j\t%1%/"
[(set_attr "type" "call")]) [(set_attr "type" "call")])
(define_expand "call" (define_expand "call"
...@@ -5153,7 +5161,7 @@ ...@@ -5153,7 +5161,7 @@
(match_operand 1 "" "")) (match_operand 1 "" ""))
(clobber (reg:SI 31))] (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)" "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
[(const_int 0)] [(const_int 0)]
{ {
...@@ -5166,12 +5174,12 @@ ...@@ -5166,12 +5174,12 @@
(set_attr "extended_mips16" "no,yes")]) (set_attr "extended_mips16" "no,yes")])
(define_insn "call_split" (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 "" "")) (match_operand 1 "" ""))
(clobber (reg:SI 31)) (clobber (reg:SI 31))
(clobber (reg:SI 28))] (clobber (reg:SI 28))]
"TARGET_SPLIT_CALLS" "TARGET_SPLIT_CALLS"
"%*jalr\t%0%/" { return MIPS_CALL ("jal", operands, 0); }
[(set_attr "type" "call")]) [(set_attr "type" "call")])
(define_expand "call_value" (define_expand "call_value"
...@@ -5193,7 +5201,7 @@ ...@@ -5193,7 +5201,7 @@
(match_operand 2 "" ""))) (match_operand 2 "" "")))
(clobber (reg:SI 31))] (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)" "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
[(const_int 0)] [(const_int 0)]
{ {
...@@ -5208,12 +5216,12 @@ ...@@ -5208,12 +5216,12 @@
(define_insn "call_value_split" (define_insn "call_value_split"
[(set (match_operand 0 "register_operand" "=df") [(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 "" ""))) (match_operand 2 "" "")))
(clobber (reg:SI 31)) (clobber (reg:SI 31))
(clobber (reg:SI 28))] (clobber (reg:SI 28))]
"TARGET_SPLIT_CALLS" "TARGET_SPLIT_CALLS"
"%*jalr\t%1%/" { return MIPS_CALL ("jal", operands, 1); }
[(set_attr "type" "call")]) [(set_attr "type" "call")])
;; See comment for call_internal. ;; See comment for call_internal.
...@@ -5226,7 +5234,7 @@ ...@@ -5226,7 +5234,7 @@
(match_dup 2))) (match_dup 2)))
(clobber (reg:SI 31))] (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)" "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
[(const_int 0)] [(const_int 0)]
{ {
...@@ -5241,7 +5249,7 @@ ...@@ -5241,7 +5249,7 @@
(define_insn "call_value_multiple_split" (define_insn "call_value_multiple_split"
[(set (match_operand 0 "register_operand" "=df") [(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 "" ""))) (match_operand 2 "" "")))
(set (match_operand 3 "register_operand" "=df") (set (match_operand 3 "register_operand" "=df")
(call (mem:SI (match_dup 1)) (call (mem:SI (match_dup 1))
...@@ -5249,7 +5257,7 @@ ...@@ -5249,7 +5257,7 @@
(clobber (reg:SI 31)) (clobber (reg:SI 31))
(clobber (reg:SI 28))] (clobber (reg:SI 28))]
"TARGET_SPLIT_CALLS" "TARGET_SPLIT_CALLS"
"%*jalr\t%1%/" { return MIPS_CALL ("jal", operands, 1); }
[(set_attr "type" "call")]) [(set_attr "type" "call")])
;; Call subroutine returning any type. ;; Call subroutine returning any type.
......
...@@ -25,7 +25,7 @@ Target RejectNegative Joined ...@@ -25,7 +25,7 @@ Target RejectNegative Joined
mabicalls mabicalls
Target Report Mask(ABICALLS) Target Report Mask(ABICALLS)
Use SVR4-style PIC Generate code that can be used in SVR4-style dynamic objects
mad mad
Target Report Var(TARGET_MAD) Target Report Var(TARGET_MAD)
...@@ -185,6 +185,10 @@ mpaired-single ...@@ -185,6 +185,10 @@ mpaired-single
Target Report Mask(PAIRED_SINGLE_FLOAT) Target Report Mask(PAIRED_SINGLE_FLOAT)
Use paired-single floating-point instructions 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 msingle-float
Target Report RejectNegative Mask(SINGLE_FLOAT) Target Report RejectNegative Mask(SINGLE_FLOAT)
Restrict the use of hardware floating-point instructions to 32-bit operations Restrict the use of hardware floating-point instructions to 32-bit operations
......
...@@ -103,6 +103,16 @@ ...@@ -103,6 +103,16 @@
switch (symbol_type) switch (symbol_type)
{ {
case SYMBOL_GENERAL: 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 -mlong-calls, force all calls to use register addressing. Also,
if this function has the long_call attribute, we must use register if this function has the long_call attribute, we must use register
addressing. */ addressing. */
......
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