From dd7218bb0fe32b82563c64568e1c057817176089 Mon Sep 17 00:00:00 2001 From: rsandifo Date: Thu, 18 Jan 2007 19:40:12 +0000 Subject: [PATCH] gcc/ * config/m68k/m68k-protos.h (m68k_output_pic_call): Delete. (output_call, m68k_legitimize_call_address): Declare. * config/m68k/m68k.h (EXTRA_CONSTRAINT): Remove unnecessary parenthesees. Add support for a 'W' constraint. (LEGITIMATE_PIC_OPERAND_P): Remove SYMBOL_REF_FLAG handling. (PRINT_OPERAND_PUNCT_VALID_P): Remove comment about 'o'. (m68k_symbolic_call, m68k_symbolic_jump): Declare. * config/m68k/m68k.c (m68k_symbolic_call, m68k_symbolic_jump): New variables. (override_options): Initialize them. Do not set flag_no_function_cse for TARGET_ID_SHARED_LIBRARY. (m68k_output_pic_call): Delete. (m68k_legitimize_call_address): New function. (print_operand): Remove the %o prefix. Handle the %p prefix. (output_call): New function. (m68k_output_mi_thunk): Use m68k_symbolic_jump. Always load the target address from the GOT if symbolic jumps are not allowed. * config/m68k/m68k.md (call, general_operand): Do not set SYMBOL_REF_FLAG. Use m68k_legitimize_call_address instead. Merge separate flag_pic and !flag_pic define_insns into... (*call, *call_value): ...these new patterns. Match the address rather than the containing MEM and require it to be a call_operand. Use output_call to generate the asm template. * config/m68k/predicates.md (const_call_operand): New predicate. (call_operand): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120921 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 28 ++++++++ gcc/config/m68k/m68k-protos.h | 3 +- gcc/config/m68k/m68k.c | 156 ++++++++++++++++++++---------------------- gcc/config/m68k/m68k.h | 20 +++--- gcc/config/m68k/m68k.md | 106 ++++------------------------ gcc/config/m68k/predicates.md | 11 +++ 6 files changed, 143 insertions(+), 181 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9719e09c818..2459a97ce57 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,31 @@ +2007-01-18 Richard Sandiford + + * config/m68k/m68k-protos.h (m68k_output_pic_call): Delete. + (output_call, m68k_legitimize_call_address): Declare. + * config/m68k/m68k.h (EXTRA_CONSTRAINT): Remove unnecessary + parenthesees. Add support for a 'W' constraint. + (LEGITIMATE_PIC_OPERAND_P): Remove SYMBOL_REF_FLAG handling. + (PRINT_OPERAND_PUNCT_VALID_P): Remove comment about 'o'. + (m68k_symbolic_call, m68k_symbolic_jump): Declare. + * config/m68k/m68k.c (m68k_symbolic_call, m68k_symbolic_jump): New + variables. + (override_options): Initialize them. Do not set flag_no_function_cse + for TARGET_ID_SHARED_LIBRARY. + (m68k_output_pic_call): Delete. + (m68k_legitimize_call_address): New function. + (print_operand): Remove the %o prefix. Handle the %p prefix. + (output_call): New function. + (m68k_output_mi_thunk): Use m68k_symbolic_jump. Always load the + target address from the GOT if symbolic jumps are not allowed. + * config/m68k/m68k.md (call, general_operand): Do not set + SYMBOL_REF_FLAG. Use m68k_legitimize_call_address instead. + Merge separate flag_pic and !flag_pic define_insns into... + (*call, *call_value): ...these new patterns. Match the address + rather than the containing MEM and require it to be a call_operand. + Use output_call to generate the asm template. + * config/m68k/predicates.md (const_call_operand): New predicate. + (call_operand): Likewise. + 2007-01-18 Nathan Sidwell * config/m68k/m68k.h (REGISTER_MOVE_COST): Simplify definition. diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h index 75f6f25bee2..30d25b75510 100644 --- a/gcc/config/m68k/m68k-protos.h +++ b/gcc/config/m68k/m68k-protos.h @@ -39,7 +39,7 @@ extern const char *output_addsi3 (rtx *); extern const char *output_andsi3 (rtx *); extern const char *output_iorsi3 (rtx *); extern const char *output_xorsi3 (rtx *); -extern void m68k_output_pic_call (rtx dest); +extern const char *output_call (rtx); extern void output_dbcc_and_branch (rtx *); extern int floating_exact_log2 (rtx); extern bool strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn, rtx target); @@ -64,4 +64,5 @@ extern void override_options (void); extern const char *m68k_cpp_cpu_ident (const char *); extern const char *m68k_cpp_cpu_family (const char *); extern void init_68881_table (void); +extern rtx m68k_legitimize_call_address (rtx); extern int m68k_hard_regno_rename_ok(unsigned int, unsigned int); diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 25b8f0cfa2f..03d59b98f9b 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -327,6 +327,12 @@ enum fpu_type m68k_fpu; /* The set of FL_* flags that apply to the target processor. */ unsigned int m68k_cpu_flags; + +/* Asm templates for calling or jumping to an arbitrary symbolic address, + or NULL if such calls or jumps are not supported. The address is held + in operand 0. */ +const char *m68k_symbolic_call; +const char *m68k_symbolic_jump; /* See whether TABLE has an entry with name NAME. Return true and store the entry in *ENTRY if so, otherwise return false and @@ -530,13 +536,42 @@ override_options (void) if (TARGET_PCREL && flag_pic == 0) flag_pic = 1; - /* Turn off function cse if we are doing PIC. We always want function call - to be done as `bsr foo@PLTPC', so it will force the assembler to create - the PLT entry for `foo'. Doing function cse will cause the address of - `foo' to be loaded into a register, which is exactly what we want to - avoid when we are doing PIC on svr4 m68k. */ - if (flag_pic) - flag_no_function_cse = 1; + if (!flag_pic) + { +#if MOTOROLA && !defined (USE_GAS) + m68k_symbolic_call = "jsr %a0"; + m68k_symbolic_jump = "jmp %a0"; +#else + m68k_symbolic_call = "jbsr %a0"; + m68k_symbolic_jump = "jra %a0"; +#endif + } + else if (TARGET_ID_SHARED_LIBRARY) + /* All addresses must be loaded from the GOT. */ + ; + else if (TARGET_68020 || TARGET_ISAB) + { + if (TARGET_PCREL) + { + m68k_symbolic_call = "bsr.l %c0"; + m68k_symbolic_jump = "bra.l %c0"; + } + else + { +#if defined(USE_GAS) + m68k_symbolic_call = "bsr.l %p0"; + m68k_symbolic_jump = "bra.l %p0"; +#else + m68k_symbolic_call = "bsr %p0"; + m68k_symbolic_jump = "bra %p0"; +#endif + } + /* Turn off function cse if we are doing PIC. We always want + function call to be done as `bsr foo@PLTPC'. */ + /* ??? It's traditional to do this for -mpcrel too, but it isn't + clear how intentional that is. */ + flag_no_function_cse = 1; + } SUBTARGET_OVERRIDE_OPTIONS; } @@ -1332,33 +1367,16 @@ flags_in_68881 (void) return cc_status.flags & CC_IN_68881; } -/* Output a BSR instruction suitable for PIC code. */ -void -m68k_output_pic_call (rtx dest) -{ - const char *out; - - if (!(GET_CODE (dest) == MEM && GET_CODE (XEXP (dest, 0)) == SYMBOL_REF)) - out = "jsr %0"; - /* We output a BSR instruction if we're building for a target that - supports long branches. Otherwise we generate one of two sequences: - a shorter one that uses a GOT entry or a longer one that doesn't. - We'll use the -Os command-line flag to decide which to generate. - Both sequences take the same time to execute on the ColdFire. */ - else if (TARGET_PCREL) - out = "bsr.l %o0"; - else if (TARGET_68020) -#if defined(USE_GAS) - out = "bsr.l %0@PLTPC"; -#else - out = "bsr %0@PLTPC"; -#endif - else if (optimize_size || TARGET_ID_SHARED_LIBRARY) - out = "move.l %0@GOT(%%a5), %%a1\n\tjsr (%%a1)"; - else - out = "lea %0-.-8,%%a1\n\tjsr 0(%%pc,%%a1)"; +/* Convert X to a legitimate function call memory reference and return the + result. */ - output_asm_insn (out, &dest); +rtx +m68k_legitimize_call_address (rtx x) +{ + gcc_assert (MEM_P (x)); + if (call_operand (XEXP (x, 0), VOIDmode)) + return x; + return replace_equiv_address (x, force_reg (Pmode, XEXP (x, 0))); } /* Output a dbCC; jCC sequence. Note we do not handle the @@ -3083,12 +3101,10 @@ floating_exact_log2 (rtx x) 'b' for byte insn (no effect, on the Sun; this is for the ISI). 'd' to force memory addressing to be absolute, not relative. 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex) - 'o' for operands to go directly to output_operand_address (bypassing - print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL) 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex), or print pair of registers as rx:ry. - - */ + 'p' print an address with @PLTPC attached, but only if the operand + is not locally-bound. */ void print_operand (FILE *file, rtx op, int letter) @@ -3120,13 +3136,11 @@ print_operand (FILE *file, rtx op, int letter) } else if (letter == '/') asm_fprintf (file, "%R"); - else if (letter == 'o') + else if (letter == 'p') { - /* This is only for direct addresses with TARGET_PCREL */ - gcc_assert (GET_CODE (op) == MEM - && GET_CODE (XEXP (op, 0)) == SYMBOL_REF - && TARGET_PCREL); - output_addr_const (file, XEXP (op, 0)); + output_addr_const (file, op); + if (!(GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op))) + fprintf (file, "@PLTPC"); } else if (GET_CODE (op) == REG) { @@ -3693,6 +3707,18 @@ output_xorsi3 (rtx *operands) return "eor%.l %2,%0"; } +/* Return the instruction that should be used for a call to address X, + which is known to be in operand 0. */ + +const char * +output_call (rtx x) +{ + if (symbolic_operand (x, VOIDmode)) + return m68k_symbolic_call; + else + return "jsr %a0"; +} + #ifdef M68K_TARGET_COFF /* Output assembly to switch to section NAME with attribute FLAGS. */ @@ -3759,43 +3785,13 @@ m68k_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, xops[0] = DECL_RTL (function); - /* Logic taken from call patterns in m68k.md. */ - if (flag_pic) - { - if (TARGET_PCREL) - fmt = "bra.l %o0"; - else if (flag_pic == 1 || TARGET_68020) - { - if (MOTOROLA) - { -#if defined (USE_GAS) - fmt = "bra.l %0@PLTPC"; -#else - fmt = "bra %0@PLTPC"; -#endif - } - else /* !MOTOROLA */ - { -#ifdef USE_GAS - fmt = "bra.l %0"; -#else - fmt = "jra %0,a1"; -#endif - } - } - else if (optimize_size || TARGET_ID_SHARED_LIBRARY) - fmt = "move.l %0@GOT(%%a5), %%a1\n\tjmp (%%a1)"; - else - fmt = "lea %0-.-8,%%a1\n\tjmp 0(%%pc,%%a1)"; - } - else - { -#if MOTOROLA && !defined (USE_GAS) - fmt = "jmp %0"; -#else - fmt = "jra %0"; -#endif - } + gcc_assert (MEM_P (xops[0]) + && symbolic_operand (XEXP (xops[0], 0), VOIDmode)); + xops[0] = XEXP (xops[0], 0); + + fmt = m68k_symbolic_jump; + if (m68k_symbolic_jump == NULL) + fmt = "move.l %%a1@GOT(%%a5), %%a1\n\tjmp (%%a1)"; output_asm_insn (fmt, xops); } diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index 3d46ee9c37c..2b72781bc1b 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -513,32 +513,35 @@ extern enum reg_class regno_reg_class[]; /* `Q' means address register indirect addressing mode. `S' is for operands that satisfy 'm' when -mpcrel is in effect. `T' is for operands that satisfy 's' when -mpcrel is not in effect. - `U' is for register offset addressing. */ + `U' is for register offset addressing. + `W' is for const_call_operands. */ #define EXTRA_CONSTRAINT(OP,CODE) \ - (((CODE) == 'S') \ + ((CODE) == 'S' \ ? (TARGET_PCREL \ && GET_CODE (OP) == MEM \ && (GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \ || GET_CODE (XEXP (OP, 0)) == LABEL_REF \ || GET_CODE (XEXP (OP, 0)) == CONST)) \ : \ - (((CODE) == 'T') \ + (CODE) == 'T' \ ? ( !TARGET_PCREL \ && (GET_CODE (OP) == SYMBOL_REF \ || GET_CODE (OP) == LABEL_REF \ || GET_CODE (OP) == CONST)) \ : \ - (((CODE) == 'Q') \ + (CODE) == 'Q' \ ? (GET_CODE (OP) == MEM \ && GET_CODE (XEXP (OP, 0)) == REG) \ : \ - (((CODE) == 'U') \ + (CODE) == 'U' \ ? (GET_CODE (OP) == MEM \ && GET_CODE (XEXP (OP, 0)) == PLUS \ && GET_CODE (XEXP (XEXP (OP, 0), 0)) == REG \ && GET_CODE (XEXP (XEXP (OP, 0), 1)) == CONST_INT) \ : \ - 0)))) + (CODE) == 'W' \ + ? const_call_operand (OP, VOIDmode) \ + : 0) /* On the m68k, use a data reg if possible when the value is a constant in the range where moveq could be used @@ -803,7 +806,6 @@ __transfer_from_trampoline () \ #define LEGITIMATE_PIC_OPERAND_P(X) \ (! symbolic_operand (X, VOIDmode) \ - || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X)) \ || PCREL_GENERAL_OPERAND_OK) #ifndef REG_OK_STRICT @@ -1232,8 +1234,6 @@ do { if (cc_prev_status.flags & CC_IN_68881) \ 'b' for byte insn (no effect, on the Sun; this is for the ISI). 'd' to force memory addressing to be absolute, not relative. 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex) - 'o' for operands to go directly to output_operand_address (bypassing - print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL) 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex), or print pair of registers as rx:ry. */ @@ -1292,3 +1292,5 @@ extern enum target_device m68k_cpu; extern enum uarch_type m68k_tune; extern enum fpu_type m68k_fpu; extern unsigned int m68k_cpu_flags; +extern const char *m68k_symbolic_call; +extern const char *m68k_symbolic_jump; diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index f7971923706..91b95fb2cca 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -6371,122 +6371,46 @@ "subql #1,%0\;cmpl #-1,%0\;jne %l1"; }) - -;; For PIC calls, in order to be able to support -;; dynamic linker LAZY BINDING, all the procedure calls need to go -;; through the PLT (Procedure Linkage Table) section in PIC mode. -;; -;; PIC calls are handled by loading the address of the function into a -;; register (via movsi), then emitting a register indirect call using -;; the "jsr" function call syntax. -;; -;; When outputting MIT syntax (e.g. on Suns), we add a bogus extra -;; operand to the jbsr statement to indicate that this call should -;; go through the PLT (why? because this is the way that Sun does it). -;; -;; We have different patterns for PIC calls and non-PIC calls. The -;; different patterns are only used to choose the right syntax. -;; -;; The svr4 m68k assembler recognizes this syntax: `bsr FUNC@PLTPC' and it -;; will create the correct relocation entry (R_68K_PLT32) for `FUNC', -;; that tells the linker editor to create an entry for `FUNC' in PLT -;; section at link time. However, all global objects reference are still -;; done by using `OBJ@GOT'. So, the goal here is to output the function -;; call operand as `FUNC@PLTPC', but output object operand as `OBJ@GOT'. -;; We need to have a way to differentiate these two different operands. -;; -;; The strategy I use here is to use SYMBOL_REF_FLAG to differentiate -;; these two different operands. The macro LEGITIMATE_PIC_OPERAND_P needs -;; to be changed to recognize function calls symbol_ref operand as a valid -;; PIC operand (by checking whether SYMBOL_REF_FLAG is set). This will -;; avoid the compiler to load this symbol_ref operand into a register. -;; Remember, the operand "foo@PLTPC" cannot be called via jsr directly -;; since the value is a PC relative offset, not a real address. -;; -;; All global objects are treated in the similar way as in SUN3. The only -;; difference is: on m68k svr4, the reference of such global object needs -;; to end with a suffix "@GOT" so the assembler and linker know to create -;; an entry for it in GOT (Global Offset Table) section. This is done in -;; m68k.c. - ;; Call subroutine with no return value. (define_expand "call" [(call (match_operand:QI 0 "memory_operand" "") (match_operand:SI 1 "general_operand" ""))] ;; Operand 1 not really used on the m68000. - "" { - if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) - SYMBOL_REF_FLAG (XEXP (operands[0], 0)) = 1; + operands[0] = m68k_legitimize_call_address (operands[0]); }) -;; This is a normal call sequence. -(define_insn "" - [(call (match_operand:QI 0 "memory_operand" "o") - (match_operand:SI 1 "general_operand" "g"))] +(define_insn "*call" + [(call (mem:QI (match_operand:SI 0 "call_operand" "a,W")) + (match_operand:SI 1 "general_operand" "g,g"))] ;; Operand 1 not really used on the m68000. - - "! flag_pic" -{ -#if MOTOROLA && !defined (USE_GAS) - return "jsr %0"; -#else - return "jbsr %0"; -#endif -}) - -;; This is a PIC call sequence. -(define_insn "" - [(call (match_operand:QI 0 "memory_operand" "o") - (match_operand:SI 1 "general_operand" "g"))] - ;; Operand 1 not really used on the m68000. - - "flag_pic" + "" { - m68k_output_pic_call(operands[0]); - return ""; + return output_call (operands[0]); }) ;; Call subroutine, returning value in operand 0 ;; (which must be a hard register). -;; See comments before "call" regarding PIC calls. (define_expand "call_value" [(set (match_operand 0 "" "") (call (match_operand:QI 1 "memory_operand" "") - (match_operand:SI 2 "general_operand" "")))] + (match_operand:SI 2 "general_operand" "")))] ;; Operand 2 not really used on the m68000. "" { - if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) - SYMBOL_REF_FLAG (XEXP (operands[1], 0)) = 1; + operands[1] = m68k_legitimize_call_address (operands[1]); }) -;; This is a normal call_value -(define_insn "" - [(set (match_operand 0 "" "=rf") - (call (match_operand:QI 1 "memory_operand" "o") - (match_operand:SI 2 "general_operand" "g")))] +(define_insn "*call_value" + [(set (match_operand 0 "" "=rf,rf") + (call (mem:QI (match_operand:SI 1 "call_operand" "a,W")) + (match_operand:SI 2 "general_operand" "g,g")))] ;; Operand 2 not really used on the m68000. - "! flag_pic" -{ -#if MOTOROLA && !defined (USE_GAS) - return "jsr %1"; -#else - return "jbsr %1"; -#endif -}) - -;; This is a PIC call_value -(define_insn "" - [(set (match_operand 0 "" "=rf") - (call (match_operand:QI 1 "memory_operand" "o") - (match_operand:SI 2 "general_operand" "g")))] - ;; Operand 2 not really used on the m68000. - "flag_pic" + "" { - m68k_output_pic_call(operands[1]); - return ""; + operands[0] = operands[1]; + return output_call (operands[0]); }) ;; Call subroutine returning any type. diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md index ca97e0b75b0..11e10f189b6 100644 --- a/gcc/config/m68k/predicates.md +++ b/gcc/config/m68k/predicates.md @@ -159,6 +159,17 @@ } }) +;; A constant that can be used the address in a call insn. +(define_predicate "const_call_operand" + (ior (match_operand 0 "const_int_operand") + (and (match_test "m68k_symbolic_call != NULL") + (match_operand 0 "symbolic_operand")))) + +;; An operand that can be used as the address in a call insn. +(define_predicate "call_operand" + (ior (match_operand 0 "const_call_operand") + (match_operand 0 "register_operand"))) + ;; TODO: Add a comment here. (define_predicate "post_inc_operand" -- 2.11.0