m68k-protos.h (m68k_output_pic_call): Delete.
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. From-SVN: r120921
This commit is contained in:
parent
85dbf7e225
commit
29ca003a7a
6 changed files with 143 additions and 181 deletions
|
@ -1,3 +1,31 @@
|
|||
2007-01-18 Richard Sandiford <richard@codesourcery.com>
|
||||
|
||||
* 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 <nathan@codesourcery.com>
|
||||
|
||||
* config/m68k/m68k.h (REGISTER_MOVE_COST): Simplify definition.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
/* Convert X to a legitimate function call memory reference and return the
|
||||
result. */
|
||||
|
||||
rtx
|
||||
m68k_legitimize_call_address (rtx x)
|
||||
{
|
||||
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)";
|
||||
|
||||
output_asm_insn (out, &dest);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Reference in a new issue