From d9870b7ef4d6cbc588da427a64b022139df0708d Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 21 Mar 2006 21:49:13 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 45 ++++++++++++ gcc/config/mips/mips-protos.h | 23 +++++++ gcc/config/mips/mips.c | 125 ++++++++++++++++++++++------------ gcc/config/mips/mips.h | 34 +++++++++ gcc/config/mips/mips.md | 56 ++++++++------- gcc/config/mips/mips.opt | 6 +- gcc/config/mips/predicates.md | 10 +++ 7 files changed, 232 insertions(+), 67 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index de9d0844275..6b1c06eccd5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,48 @@ +2006-03-21 Richard Sandiford + + * 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 * config/ia64/unwind-hpux.c: New file. diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index b737375af61..60f81ada5aa 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 f907c01b0b3..ffe047ea068 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; + { + 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: - /* 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 - - 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 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 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; + } - 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; - - 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; + rtx addr, offset, incoming_address; + switch (mips_current_loadgp_style ()) + { + 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 51d383c59cf..3823963ebac 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 ce2cce650ac..32d0c418697 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 737f5edecb1..7f8214bb146 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 23e85d82be8..9a6756c20a2 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. */