mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-20 01:19:21 +08:00
Jakub Jelinek <jakub@redhat.com>
* config/sparc/sparc.h (FIXED_REGISTERS, CONDITIONAL_REGISTER_USAGE): Allow the user to override call-used/fixed state of %g2-5 registers from the command line (with the exception of %g4 for embedded model). (REG_LEAF_ALLOC_ORDER): Move %g1 and %g4-7 registers to front, so that there is a higher chance of having a leaf function. (MACHINE_STATE_SAVE, MACHINE_STATE_RESTORE): Provide separate macros for ARCH64 which has %ccr register. * config/sparc/sparc.md (return_losum_si, return_losum_di): New patterns. * config/sparc/sparc.c (eligible_for_epilogue_delay): For the return insn accept into delay slot any insn which does not use %[ol] registers. Accept some LO_SUM and shift left by 1 for the normal restore case. (output_function_epilogue): Likewise. (epilogue_renumber): Added argument which inhibits any renumbering and just tests if the rtx does not use any %[ol] registers. (output_return): Reflect above change. From-SVN: r30727
This commit is contained in:
parent
f34e52f774
commit
e48addeebc
@ -1,3 +1,24 @@
|
||||
1999-11-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* config/sparc/sparc.h (FIXED_REGISTERS, CONDITIONAL_REGISTER_USAGE):
|
||||
Allow the user to override call-used/fixed state of %g2-5
|
||||
registers from the command line (with the exception of %g4 for
|
||||
embedded model).
|
||||
(REG_LEAF_ALLOC_ORDER): Move %g1 and %g4-7 registers to front, so that
|
||||
there is a higher chance of having a leaf function.
|
||||
(MACHINE_STATE_SAVE, MACHINE_STATE_RESTORE): Provide separate macros
|
||||
for ARCH64 which has %ccr register.
|
||||
* config/sparc/sparc.md (return_losum_si, return_losum_di): New
|
||||
patterns.
|
||||
* config/sparc/sparc.c (eligible_for_epilogue_delay): For the return
|
||||
insn accept into delay slot any insn which does not use %[ol]
|
||||
registers. Accept some LO_SUM and shift left by 1 for the normal
|
||||
restore case.
|
||||
(output_function_epilogue): Likewise.
|
||||
(epilogue_renumber): Added argument which inhibits any renumbering
|
||||
and just tests if the rtx does not use any %[ol] registers.
|
||||
(output_return): Reflect above change.
|
||||
|
||||
1999-11-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* config/sparc/sparc.c (sparc_va_arg): Fix sparc64 va_arg
|
||||
|
@ -63,6 +63,10 @@ Boston, MA 02111-1307, USA. */
|
||||
static int apparent_fsize;
|
||||
static int actual_fsize;
|
||||
|
||||
/* Number of live general or floating point registers needed to be saved
|
||||
(as 4-byte quantities). This is only done if TARGET_EPILOGUE. */
|
||||
static int num_gfregs;
|
||||
|
||||
/* Save the operands last given to a compare for use when we
|
||||
generate a scc or bcc insn. */
|
||||
|
||||
@ -124,7 +128,7 @@ static void sparc_output_deferred_case_vectors PROTO((void));
|
||||
static void sparc_add_gc_roots PROTO ((void));
|
||||
static void mark_ultrasparc_pipeline_state PROTO ((void *));
|
||||
static int check_return_regs PROTO ((rtx));
|
||||
static void epilogue_renumber PROTO ((rtx *));
|
||||
static int epilogue_renumber PROTO ((rtx *, int));
|
||||
static int ultra_cmove_results_ready_p PROTO ((rtx));
|
||||
static int ultra_fpmode_conflict_exists PROTO ((enum machine_mode));
|
||||
static rtx *ultra_find_type PROTO ((int, rtx *, int));
|
||||
@ -2208,6 +2212,11 @@ eligible_for_epilogue_delay (trial, slot)
|
||||
optimize things as necessary. */
|
||||
if (TARGET_LIVE_G0)
|
||||
return 0;
|
||||
|
||||
/* If there are any call-saved registers, we should scan TRIAL if it
|
||||
does not reference them. For now just make it easy. */
|
||||
if (num_gfregs)
|
||||
return 0;
|
||||
|
||||
/* In the case of a true leaf function, anything can go into the delay slot.
|
||||
A delay slot only exists however if the frame size is zero, otherwise
|
||||
@ -2228,7 +2237,7 @@ eligible_for_epilogue_delay (trial, slot)
|
||||
pat = PATTERN (trial);
|
||||
|
||||
/* Otherwise, only operations which can be done in tandem with
|
||||
a `restore' insn can go into the delay slot. */
|
||||
a `restore' or `return' insn can go into the delay slot. */
|
||||
if (GET_CODE (SET_DEST (pat)) != REG
|
||||
|| REGNO (SET_DEST (pat)) >= 32
|
||||
|| REGNO (SET_DEST (pat)) < 24)
|
||||
@ -2247,7 +2256,7 @@ eligible_for_epilogue_delay (trial, slot)
|
||||
else
|
||||
return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (SImode);
|
||||
}
|
||||
|
||||
|
||||
/* This matches "*return_di". */
|
||||
else if (arith_double_operand (src, GET_MODE (src)))
|
||||
return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (DImode);
|
||||
@ -2257,6 +2266,12 @@ eligible_for_epilogue_delay (trial, slot)
|
||||
&& register_operand (src, SFmode))
|
||||
return 1;
|
||||
|
||||
/* If we have return instruction, anything that does not use
|
||||
local or output registers and can go into a delay slot wins. */
|
||||
else if (TARGET_V9 && ! epilogue_renumber (&pat, 1)
|
||||
&& (get_attr_in_uncond_branch_delay (trial) == IN_BRANCH_DELAY_TRUE))
|
||||
return 1;
|
||||
|
||||
/* This matches "*return_addsi". */
|
||||
else if (GET_CODE (src) == PLUS
|
||||
&& arith_operand (XEXP (src, 0), SImode)
|
||||
@ -2273,6 +2288,25 @@ eligible_for_epilogue_delay (trial, slot)
|
||||
|| register_operand (XEXP (src, 1), DImode)))
|
||||
return 1;
|
||||
|
||||
/* This can match "*return_losum_[sd]i".
|
||||
Catch only some cases, so that return_losum* don't have
|
||||
to be too big. */
|
||||
else if (GET_CODE (src) == LO_SUM
|
||||
&& ! TARGET_CM_MEDMID
|
||||
&& ((register_operand (XEXP (src, 0), SImode)
|
||||
&& immediate_operand (XEXP (src, 1), SImode))
|
||||
|| (TARGET_ARCH64
|
||||
&& register_operand (XEXP (src, 0), DImode)
|
||||
&& immediate_operand (XEXP (src, 1), DImode))))
|
||||
return 1;
|
||||
|
||||
/* sll{,x} reg,1,reg2 is add reg,reg,reg2 as well. */
|
||||
else if (GET_CODE (src) == ASHIFT
|
||||
&& (register_operand (XEXP (src, 0), SImode)
|
||||
|| register_operand (XEXP (src, 0), DImode))
|
||||
&& XEXP (src, 1) == const1_rtx)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2979,12 +3013,6 @@ restore_regs (file, low, high, base, offset, n_regs)
|
||||
return n_regs;
|
||||
}
|
||||
|
||||
/* Static variables we want to share between prologue and epilogue. */
|
||||
|
||||
/* Number of live general or floating point registers needed to be saved
|
||||
(as 4-byte quantities). This is only done if TARGET_EPILOGUE. */
|
||||
static int num_gfregs;
|
||||
|
||||
/* Compute the frame size required by the function. This function is called
|
||||
during the reload pass and also by output_function_prologue(). */
|
||||
|
||||
@ -3283,7 +3311,7 @@ output_function_epilogue (file, size, leaf_function)
|
||||
#endif
|
||||
|
||||
else if (current_function_epilogue_delay_list == 0)
|
||||
{
|
||||
{
|
||||
/* If code does not drop into the epilogue, we need
|
||||
do nothing except output pending case vectors. */
|
||||
rtx insn = get_last_insn ();
|
||||
@ -3339,13 +3367,38 @@ output_function_epilogue (file, size, leaf_function)
|
||||
/* If we wound up with things in our delay slot, flush them here. */
|
||||
if (current_function_epilogue_delay_list)
|
||||
{
|
||||
rtx insn = emit_jump_insn_after (gen_rtx_RETURN (VOIDmode),
|
||||
get_last_insn ());
|
||||
PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode,
|
||||
gen_rtvec (2,
|
||||
PATTERN (XEXP (current_function_epilogue_delay_list, 0)),
|
||||
PATTERN (insn)));
|
||||
final_scan_insn (insn, file, 1, 0, 1);
|
||||
rtx delay = PATTERN (XEXP (current_function_epilogue_delay_list, 0));
|
||||
|
||||
if (TARGET_V9 && ! epilogue_renumber (&delay, 1))
|
||||
{
|
||||
epilogue_renumber (&delay, 0);
|
||||
fputs (SKIP_CALLERS_UNIMP_P
|
||||
? "\treturn\t%i7+12\n"
|
||||
: "\treturn\t%i7+8\n", file);
|
||||
final_scan_insn (XEXP (current_function_epilogue_delay_list, 0), file, 1, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx insn = emit_jump_insn_after (gen_rtx_RETURN (VOIDmode),
|
||||
get_last_insn ());
|
||||
rtx src;
|
||||
|
||||
if (GET_CODE (delay) != SET)
|
||||
abort();
|
||||
|
||||
src = SET_SRC (delay);
|
||||
if (GET_CODE (src) == ASHIFT)
|
||||
{
|
||||
if (XEXP (src, 1) != const1_rtx)
|
||||
abort();
|
||||
SET_SRC (delay) = gen_rtx_PLUS (GET_MODE (src), XEXP (src, 0),
|
||||
XEXP (src, 0));
|
||||
}
|
||||
|
||||
PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode,
|
||||
gen_rtvec (2, delay, PATTERN (insn)));
|
||||
final_scan_insn (insn, file, 1, 0, 1);
|
||||
}
|
||||
}
|
||||
else if (TARGET_V9 && ! SKIP_CALLERS_UNIMP_P)
|
||||
fputs ("\treturn\t%i7+8\n\tnop\n", file);
|
||||
@ -4726,56 +4779,56 @@ output_v9branch (op, reg, label, reversed, annul, noop, insn)
|
||||
return string;
|
||||
}
|
||||
|
||||
/* Renumber registers in delay slot. Replace registers instead of
|
||||
renumbering because they may be shared.
|
||||
/* Return 1, if any of the registers of the instruction are %l[0-7] or %o[0-7].
|
||||
Such instructions cannot be used in the delay slot of return insn on v9.
|
||||
If TEST is 0, also rename all %i[0-7] registers to their %o[0-7] counterparts.
|
||||
*/
|
||||
|
||||
This does not handle instructions other than move. */
|
||||
|
||||
static void
|
||||
epilogue_renumber (where)
|
||||
rtx *where;
|
||||
static int
|
||||
epilogue_renumber (where, test)
|
||||
register rtx *where;
|
||||
int test;
|
||||
{
|
||||
rtx x = *where;
|
||||
enum rtx_code code = GET_CODE (x);
|
||||
register const char *fmt;
|
||||
register int i;
|
||||
register enum rtx_code code;
|
||||
|
||||
if (*where == 0)
|
||||
return 0;
|
||||
|
||||
code = GET_CODE (*where);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case MEM:
|
||||
*where = x = copy_rtx (x);
|
||||
epilogue_renumber (&XEXP (x, 0));
|
||||
return;
|
||||
|
||||
case REG:
|
||||
{
|
||||
int regno = REGNO (x);
|
||||
if (regno > 8 && regno < 24)
|
||||
abort ();
|
||||
if (regno >= 24 && regno < 32)
|
||||
*where = gen_rtx_REG (GET_MODE (x), regno - 16);
|
||||
return;
|
||||
}
|
||||
if (REGNO (*where) >= 8 && REGNO (*where) < 24) /* oX or lX */
|
||||
return 1;
|
||||
if (! test && REGNO (*where) >= 24 && REGNO (*where) < 32)
|
||||
*where = gen_rtx (REG, GET_MODE (*where), OUTGOING_REGNO (REGNO(*where)));
|
||||
case SCRATCH:
|
||||
case CC0:
|
||||
case PC:
|
||||
case CONST_INT:
|
||||
case CONST_DOUBLE:
|
||||
case CONST:
|
||||
case SYMBOL_REF:
|
||||
case LABEL_REF:
|
||||
return;
|
||||
|
||||
case IOR:
|
||||
case AND:
|
||||
case XOR:
|
||||
case PLUS:
|
||||
case MINUS:
|
||||
epilogue_renumber (&XEXP (x, 1));
|
||||
case NEG:
|
||||
case NOT:
|
||||
epilogue_renumber (&XEXP (x, 0));
|
||||
return;
|
||||
|
||||
default:
|
||||
debug_rtx (*where);
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
fmt = GET_RTX_FORMAT (code);
|
||||
|
||||
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
||||
{
|
||||
if (fmt[i] == 'E')
|
||||
{
|
||||
register int j;
|
||||
for (j = XVECLEN (*where, i) - 1; j >= 0; j--)
|
||||
if (epilogue_renumber (&(XVECEXP (*where, i, j)), test))
|
||||
return 1;
|
||||
}
|
||||
else if (fmt[i] == 'e'
|
||||
&& epilogue_renumber (&(XEXP (*where, i)), test))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Output assembler code to return from a function. */
|
||||
@ -4840,8 +4893,8 @@ output_return (operands)
|
||||
{
|
||||
if (delay)
|
||||
{
|
||||
epilogue_renumber (&SET_DEST (PATTERN (delay)));
|
||||
epilogue_renumber (&SET_SRC (PATTERN (delay)));
|
||||
epilogue_renumber (&SET_DEST (PATTERN (delay)), 0);
|
||||
epilogue_renumber (&SET_SRC (PATTERN (delay)), 0);
|
||||
}
|
||||
if (SKIP_CALLERS_UNIMP_P)
|
||||
return "return\t%%i7+12%#";
|
||||
|
@ -962,7 +962,7 @@ if (TARGET_ARCH64 \
|
||||
*/
|
||||
|
||||
#define FIXED_REGISTERS \
|
||||
{1, 0, 0, 0, 0, 0, 1, 1, \
|
||||
{1, 0, 2, 2, 2, 2, 1, 1, \
|
||||
0, 0, 0, 0, 0, 0, 1, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 1, 1, \
|
||||
@ -1015,10 +1015,12 @@ do \
|
||||
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
|
||||
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
|
||||
} \
|
||||
if (TARGET_ARCH32) \
|
||||
{ \
|
||||
fixed_regs[5] = 1; \
|
||||
} \
|
||||
/* If the user has passed -f{fixed,call-{used,saved}}-g5 */ \
|
||||
/* then honour it. */ \
|
||||
if (TARGET_ARCH32 && fixed_regs[5]) \
|
||||
fixed_regs[5] = 1; \
|
||||
else if (TARGET_ARCH64 && fixed_regs[5] == 2) \
|
||||
fixed_regs[5] = 0; \
|
||||
if (TARGET_LIVE_G0) \
|
||||
fixed_regs[0] = 0; \
|
||||
if (! TARGET_V9) \
|
||||
@ -1040,10 +1042,18 @@ do \
|
||||
for (regno = 32; regno < SPARC_LAST_V9_FCC_REG; regno++) \
|
||||
fixed_regs[regno] = 1; \
|
||||
} \
|
||||
/* Don't unfix g2-g4 if they were fixed with -ffixed-. */ \
|
||||
fixed_regs[2] |= ! TARGET_APP_REGS; \
|
||||
fixed_regs[3] |= ! TARGET_APP_REGS; \
|
||||
fixed_regs[4] |= ! TARGET_APP_REGS || TARGET_CM_EMBMEDANY; \
|
||||
/* If the user has passed -f{fixed,call-{used,saved}}-g2 */ \
|
||||
/* then honour it. Likewise with g3 and g4. */ \
|
||||
if (fixed_regs[2] == 2) \
|
||||
fixed_regs[2] = ! TARGET_APP_REGS; \
|
||||
if (fixed_regs[3] == 2) \
|
||||
fixed_regs[3] = ! TARGET_APP_REGS; \
|
||||
if (TARGET_ARCH32 && fixed_regs[4] == 2) \
|
||||
fixed_regs[4] = ! TARGET_APP_REGS; \
|
||||
else if (TARGET_CM_EMBMEDANY) \
|
||||
fixed_regs[4] = 1; \
|
||||
else if (fixed_regs[4] == 2) \
|
||||
fixed_regs[4] = 0; \
|
||||
if (TARGET_FLAT) \
|
||||
{ \
|
||||
/* Let the compiler believe the frame pointer is still \
|
||||
@ -1335,11 +1345,12 @@ extern enum reg_class sparc_regno_reg_class[];
|
||||
1, 4, 5, 6, 7, 0, 14, 30}
|
||||
|
||||
/* This is the order in which to allocate registers for
|
||||
leaf functions. If all registers can fit in the "i" registers,
|
||||
leaf functions. If all registers can fit in the "gi" registers,
|
||||
then we have the possibility of having a leaf function. */
|
||||
|
||||
#define REG_LEAF_ALLOC_ORDER \
|
||||
{ 2, 3, 24, 25, 26, 27, 28, 29, \
|
||||
4, 5, 6, 7, 1, \
|
||||
15, 8, 9, 10, 11, 12, 13, \
|
||||
16, 17, 18, 19, 20, 21, 22, 23, \
|
||||
34, 35, 36, 37, 38, 39, \
|
||||
@ -1352,8 +1363,8 @@ extern enum reg_class sparc_regno_reg_class[];
|
||||
88, 89, 90, 91, 92, 93, 94, 95, \
|
||||
32, 33, \
|
||||
96, 97, 98, 99, 100, \
|
||||
1, 4, 5, 6, 7, 0, 14, 30, 31}
|
||||
|
||||
0, 14, 30, 31}
|
||||
|
||||
#define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
|
||||
|
||||
/* ??? %g7 is not a leaf register to effectively #undef LEAF_REGISTERS when
|
||||
@ -1889,6 +1900,8 @@ do { \
|
||||
#define FUNCTION_BLOCK_PROFILER_EXIT(FILE) \
|
||||
sparc_function_block_profiler_exit(FILE)
|
||||
|
||||
#ifdef IN_LIBGCC2
|
||||
|
||||
/* The function `__bb_trace_func' is called in every basic block
|
||||
and is not allowed to change the machine state. Saving (restoring)
|
||||
the state can either be done in the BLOCK_PROFILER macro,
|
||||
@ -1908,12 +1921,18 @@ do { \
|
||||
On sparc it is sufficient to save the psw register to memory.
|
||||
Unfortunately the psw register can be read in supervisor mode only,
|
||||
so we read only the condition codes by using branch instructions
|
||||
and hope that this is enough. */
|
||||
and hope that this is enough.
|
||||
|
||||
On V9, life is much sweater: there is a user accessible %ccr
|
||||
register, but we use it for 64bit libraries only. */
|
||||
|
||||
#if TARGET_ARCH32
|
||||
|
||||
#define MACHINE_STATE_SAVE(ID) \
|
||||
int ms_flags, ms_saveret; \
|
||||
asm volatile( \
|
||||
"mov %%g0,%0\n\
|
||||
"mov %%g2,%1\n\
|
||||
mov %%g0,%0\n\
|
||||
be,a LFLGNZ"ID"\n\
|
||||
or %0,4,%0\n\
|
||||
LFLGNZ"ID":\n\
|
||||
@ -1925,10 +1944,20 @@ LFLGNC"ID":\n\
|
||||
LFLGNV"ID":\n\
|
||||
bneg,a LFLGNN"ID"\n\
|
||||
or %0,8,%0\n\
|
||||
LFLGNN"ID":\n\
|
||||
mov %%g2,%1" \
|
||||
LFLGNN"ID":" \
|
||||
: "=r"(ms_flags), "=r"(ms_saveret));
|
||||
|
||||
#else
|
||||
|
||||
#define MACHINE_STATE_SAVE(ID) \
|
||||
unsigned long ms_flags, ms_saveret; \
|
||||
asm volatile( \
|
||||
"mov %%g2,%1\n\ \
|
||||
rd %%ccr,%0" \
|
||||
: "=r"(ms_flags), "=r"(ms_saveret));
|
||||
|
||||
#endif
|
||||
|
||||
/* On sparc MACHINE_STATE_RESTORE restores the psw register from memory.
|
||||
The psw register can be written in supervisor mode only,
|
||||
which is true even for simple condition codes.
|
||||
@ -1937,6 +1966,8 @@ LFLGNN"ID":\n\
|
||||
be generated in this way. If this happens an unimplemented
|
||||
instruction will be executed to abort the program. */
|
||||
|
||||
#if TARGET_ARCH32
|
||||
|
||||
#define MACHINE_STATE_RESTORE(ID) \
|
||||
{ extern char flgtab[] __asm__("LFLGTAB"ID); \
|
||||
int scratch; \
|
||||
@ -1995,7 +2026,20 @@ LFLGRET"ID":\n\
|
||||
: "=r"(scratch) \
|
||||
: "r"(ms_flags*8), "r"(flgtab), "r"(-1), \
|
||||
"r"(0x80000000), "r"(ms_saveret) \
|
||||
: "cc", "%g2"); }
|
||||
: "cc", "g2"); }
|
||||
|
||||
#else
|
||||
|
||||
#define MACHINE_STATE_RESTORE(ID) \
|
||||
asm volatile ( \
|
||||
"wr %0,0,%%ccr\n\
|
||||
mov %1,%%g2" \
|
||||
: : "r"(ms_flags), "r"(ms_saveret) \
|
||||
: "cc", "g2");
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* IN_LIBGCC2 */
|
||||
|
||||
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
|
||||
the stack pointer does not matter. The value is tested only in
|
||||
|
@ -8191,6 +8191,24 @@
|
||||
}"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "*return_losum_si"
|
||||
[(set (match_operand:SI 0 "restore_operand" "")
|
||||
(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
|
||||
(match_operand:SI 2 "immediate_operand" "in")))
|
||||
(return)]
|
||||
"! TARGET_EPILOGUE && ! TARGET_LIVE_G0 && ! TARGET_CM_MEDMID"
|
||||
"*
|
||||
{
|
||||
if (! TARGET_ARCH64 && current_function_returns_struct)
|
||||
return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
|
||||
/* If operands are global or in registers, can use return */
|
||||
else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
|
||||
return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
|
||||
else
|
||||
return \"ret\;restore %r1, %%lo(%a2), %Y0\";
|
||||
}"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "*return_di"
|
||||
[(set (match_operand:DI 0 "restore_operand" "")
|
||||
(match_operand:DI 1 "arith_double_operand" "rHI"))
|
||||
@ -8208,6 +8226,15 @@
|
||||
"ret\;restore %r1, %2, %Y0"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "*return_losum_di"
|
||||
[(set (match_operand:DI 0 "restore_operand" "")
|
||||
(lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
|
||||
(match_operand:DI 2 "immediate_operand" "in")))
|
||||
(return)]
|
||||
"TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
|
||||
"ret\;restore %r1, %%lo(a2), %Y0"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
;; The following pattern is only generated by delayed-branch scheduling,
|
||||
;; when the insn winds up in the epilogue.
|
||||
(define_insn "*return_sf"
|
||||
|
Loading…
Reference in New Issue
Block a user