Commit ac2e563f by Richard Henderson Committed by Richard Henderson

re PR target/38900 (ICE: unable to find a register to spill)

	PR target/38900
	* config/i386/i386.h (CONDITIONAL_REGISTER_USAGE): Move to i386.c.
	(enum reg_class): Add CLOBBERED_REGS.
	(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Likewise.
	* config/i386/i386.c (ix86_conditional_register_usage): Moved
	from CONDITIONAL_REGISTER_USAGE; build CLOBBERED_REGS for 64-bit.
	(ix86_function_ok_for_sibcall): Tidy.  Disallow MS->SYSV sibcalls.
	(ix86_expand_call): Use sibcall_insn_operand when needed.  Don't
	force 64-bit sibcalls into R11.
	* config/i386/constraints.md (U): New constraint.
	* config/i386/i386.md (sibcall_1, sibcall_value_1): Use it.
	(sibcall_1_rex64, sibcall_value_1_rex64): Likewise.
	(sibcall_1_rex64_v, sibcall_value_1_rex64_v): Remove.

From-SVN: r149373
parent acb78844
2009-07-08 Richard Henderson <rth@redhat.com>
PR target/38900
* config/i386/i386.h (CONDITIONAL_REGISTER_USAGE): Move to i386.c.
(enum reg_class): Add CLOBBERED_REGS.
(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Likewise.
* config/i386/i386.c (ix86_conditional_register_usage): Moved
from CONDITIONAL_REGISTER_USAGE; build CLOBBERED_REGS for 64-bit.
(ix86_function_ok_for_sibcall): Tidy. Disallow MS->SYSV sibcalls.
(ix86_expand_call): Use sibcall_insn_operand when needed. Don't
force 64-bit sibcalls into R11.
* config/i386/constraints.md (U): New constraint.
* config/i386/i386.md (sibcall_1, sibcall_value_1): Use it.
(sibcall_1_rex64, sibcall_value_1_rex64): Likewise.
(sibcall_1_rex64_v, sibcall_value_1_rex64_v): Remove.
2009-07-08 Shujing Zhao <pearly.zhao@oracle.com> 2009-07-08 Shujing Zhao <pearly.zhao@oracle.com>
* basic-block.h (dump_regset, debug_regset): Remove duplicate * basic-block.h (dump_regset, debug_regset): Remove duplicate
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
;; <http://www.gnu.org/licenses/>. ;; <http://www.gnu.org/licenses/>.
;;; Unused letters: ;;; Unused letters:
;;; B H TU W ;;; B H T W
;;; h jk vw z ;;; h jk vw z
;; Integer register constraints. ;; Integer register constraints.
...@@ -62,6 +62,9 @@ ...@@ -62,6 +62,9 @@
"The @code{a} and @code{d} registers, as a pair (for instructions "The @code{a} and @code{d} registers, as a pair (for instructions
that return half the result in one and half in the other).") that return half the result in one and half in the other).")
(define_register_constraint "U" "CLOBBERED_REGS"
"The call-clobbered integer registers.")
;; Floating-point register constraints. ;; Floating-point register constraints.
(define_register_constraint "f" (define_register_constraint "f"
"TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 ? FLOAT_REGS : NO_REGS" "TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 ? FLOAT_REGS : NO_REGS"
......
...@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
/* Functions in i386.c */ /* Functions in i386.c */
extern void override_options (bool); extern void override_options (bool);
extern void optimization_options (int, int); extern void optimization_options (int, int);
extern void ix86_conditional_register_usage (void);
extern int ix86_can_use_return_insn_p (void); extern int ix86_can_use_return_insn_p (void);
extern void ix86_setup_frame_addresses (void); extern void ix86_setup_frame_addresses (void);
......
...@@ -3418,6 +3418,79 @@ override_options (bool main_args_p) ...@@ -3418,6 +3418,79 @@ override_options (bool main_args_p)
target_option_default_node = target_option_current_node target_option_default_node = target_option_current_node
= build_target_option_node (); = build_target_option_node ();
} }
/* Update register usage after having seen the compiler flags. */
void
ix86_conditional_register_usage (void)
{
int i;
unsigned int j;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
if (fixed_regs[i] > 1)
fixed_regs[i] = (fixed_regs[i] == (TARGET_64BIT ? 3 : 2));
if (call_used_regs[i] > 1)
call_used_regs[i] = (call_used_regs[i] == (TARGET_64BIT ? 3 : 2));
}
/* The PIC register, if it exists, is fixed. */
j = PIC_OFFSET_TABLE_REGNUM;
if (j != INVALID_REGNUM)
fixed_regs[j] = call_used_regs[j] = 1;
/* The MS_ABI changes the set of call-used registers. */
if (TARGET_64BIT && ix86_cfun_abi () == MS_ABI)
{
call_used_regs[SI_REG] = 0;
call_used_regs[DI_REG] = 0;
call_used_regs[XMM6_REG] = 0;
call_used_regs[XMM7_REG] = 0;
for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
call_used_regs[i] = 0;
}
/* The default setting of CLOBBERED_REGS is for 32-bit; add in the
other call-clobbered regs for 64-bit. */
if (TARGET_64BIT)
{
CLEAR_HARD_REG_SET (reg_class_contents[(int)CLOBBERED_REGS]);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (reg_class_contents[(int)GENERAL_REGS], i)
&& call_used_regs[i])
SET_HARD_REG_BIT (reg_class_contents[(int)CLOBBERED_REGS], i);
}
/* If MMX is disabled, squash the registers. */
if (! TARGET_MMX)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (reg_class_contents[(int)MMX_REGS], i))
fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
/* If SSE is disabled, squash the registers. */
if (! TARGET_SSE)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (reg_class_contents[(int)SSE_REGS], i))
fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
/* If the FPU is disabled, squash the registers. */
if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (reg_class_contents[(int)FLOAT_REGS], i))
fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
/* If 32-bit, squash the 64-bit registers. */
if (! TARGET_64BIT)
{
for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++)
reg_names[i] = "";
for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
reg_names[i] = "";
}
}
/* Save the current options */ /* Save the current options */
...@@ -4193,7 +4266,7 @@ optimization_options (int level, int size ATTRIBUTE_UNUSED) ...@@ -4193,7 +4266,7 @@ optimization_options (int level, int size ATTRIBUTE_UNUSED)
static bool static bool
ix86_function_ok_for_sibcall (tree decl, tree exp) ix86_function_ok_for_sibcall (tree decl, tree exp)
{ {
tree func; tree type, decl_or_type;
rtx a, b; rtx a, b;
/* If we are generating position-independent code, we cannot sibcall /* If we are generating position-independent code, we cannot sibcall
...@@ -4202,13 +4275,23 @@ ix86_function_ok_for_sibcall (tree decl, tree exp) ...@@ -4202,13 +4275,23 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
if (!TARGET_64BIT && flag_pic && (!decl || !targetm.binds_local_p (decl))) if (!TARGET_64BIT && flag_pic && (!decl || !targetm.binds_local_p (decl)))
return false; return false;
/* If we need to align the outgoing stack, then sibcalling would
unalign the stack, which may break the called function. */
if (ix86_incoming_stack_boundary < PREFERRED_STACK_BOUNDARY)
return false;
if (decl) if (decl)
func = decl; {
decl_or_type = decl;
type = TREE_TYPE (decl);
}
else else
{ {
func = TREE_TYPE (CALL_EXPR_FN (exp)); /* We're looking at the CALL_EXPR, we need the type of the function. */
if (POINTER_TYPE_P (func)) type = CALL_EXPR_FN (exp); /* pointer expression */
func = TREE_TYPE (func); type = TREE_TYPE (type); /* pointer type */
type = TREE_TYPE (type); /* function type */
decl_or_type = type;
} }
/* Check that the return value locations are the same. Like /* Check that the return value locations are the same. Like
...@@ -4220,7 +4303,7 @@ ix86_function_ok_for_sibcall (tree decl, tree exp) ...@@ -4220,7 +4303,7 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
differences in the return value ABI. Note that it is ok for one differences in the return value ABI. Note that it is ok for one
of the functions to have void return type as long as the return of the functions to have void return type as long as the return
value of the other is passed in a register. */ value of the other is passed in a register. */
a = ix86_function_value (TREE_TYPE (exp), func, false); a = ix86_function_value (TREE_TYPE (exp), decl_or_type, false);
b = ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)), b = ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
cfun->decl, false); cfun->decl, false);
if (STACK_REG_P (a) || STACK_REG_P (b)) if (STACK_REG_P (a) || STACK_REG_P (b))
...@@ -4233,38 +4316,32 @@ ix86_function_ok_for_sibcall (tree decl, tree exp) ...@@ -4233,38 +4316,32 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
else if (!rtx_equal_p (a, b)) else if (!rtx_equal_p (a, b))
return false; return false;
/* If this call is indirect, we'll need to be able to use a call-clobbered if (TARGET_64BIT)
register for the address of the target function. Make sure that all
such registers are not used for passing parameters. */
if (!decl && !TARGET_64BIT)
{ {
tree type; /* The SYSV ABI has more call-clobbered registers;
disallow sibcalls from MS to SYSV. */
/* We're looking at the CALL_EXPR, we need the type of the function. */ if (cfun->machine->call_abi == MS_ABI
type = CALL_EXPR_FN (exp); /* pointer expression */ && ix86_function_type_abi (type) == SYSV_ABI)
type = TREE_TYPE (type); /* pointer type */ return false;
type = TREE_TYPE (type); /* function type */ }
else
if (ix86_function_regparm (type, NULL) >= 3) {
/* If this call is indirect, we'll need to be able to use a
call-clobbered register for the address of the target function.
Make sure that all such registers are not used for passing
parameters. Note that DLLIMPORT functions are indirect. */
if (!decl
|| (TARGET_DLLIMPORT_DECL_ATTRIBUTES && DECL_DLLIMPORT_P (decl)))
{ {
/* ??? Need to count the actual number of registers to be used, if (ix86_function_regparm (type, NULL) >= 3)
not the possible number of registers. Fix later. */ {
return false; /* ??? Need to count the actual number of registers to be used,
not the possible number of registers. Fix later. */
return false;
}
} }
} }
/* Dllimport'd functions are also called indirectly. */
if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
&& !TARGET_64BIT
&& decl && DECL_DLLIMPORT_P (decl)
&& ix86_function_regparm (TREE_TYPE (decl), NULL) >= 3)
return false;
/* If we need to align the outgoing stack, then sibcalling would
unalign the stack, which may break the called function. */
if (ix86_incoming_stack_boundary < PREFERRED_STACK_BOUNDARY)
return false;
/* Otherwise okay. That also includes certain types of indirect calls. */ /* Otherwise okay. That also includes certain types of indirect calls. */
return true; return true;
} }
...@@ -4321,7 +4398,8 @@ ix86_handle_cconv_attribute (tree *node, tree name, ...@@ -4321,7 +4398,8 @@ ix86_handle_cconv_attribute (tree *node, tree name,
if (TARGET_64BIT) if (TARGET_64BIT)
{ {
/* Do not warn when emulating the MS ABI. */ /* Do not warn when emulating the MS ABI. */
if (TREE_CODE (*node) != FUNCTION_TYPE || ix86_function_type_abi (*node)!=MS_ABI) if (TREE_CODE (*node) != FUNCTION_TYPE
|| ix86_function_type_abi (*node) != MS_ABI)
warning (OPT_Wattributes, "%qE attribute ignored", warning (OPT_Wattributes, "%qE attribute ignored",
name); name);
*no_add_attrs = true; *no_add_attrs = true;
...@@ -4790,7 +4868,8 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */ ...@@ -4790,7 +4868,8 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
/* Set up the number of registers to use for passing arguments. */ /* Set up the number of registers to use for passing arguments. */
if (cum->call_abi == MS_ABI && !ACCUMULATE_OUTGOING_ARGS) if (cum->call_abi == MS_ABI && !ACCUMULATE_OUTGOING_ARGS)
sorry ("ms_abi attribute require -maccumulate-outgoing-args or subtarget optimization implying it"); sorry ("ms_abi attribute requires -maccumulate-outgoing-args "
"or subtarget optimization implying it");
cum->nregs = ix86_regparm; cum->nregs = ix86_regparm;
if (TARGET_64BIT) if (TARGET_64BIT)
{ {
...@@ -7933,7 +8012,8 @@ ix86_compute_frame_layout (struct ix86_frame *frame) ...@@ -7933,7 +8012,8 @@ ix86_compute_frame_layout (struct ix86_frame *frame)
|| (TARGET_64BIT && frame->to_allocate >= (HOST_WIDE_INT) 0x80000000)) || (TARGET_64BIT && frame->to_allocate >= (HOST_WIDE_INT) 0x80000000))
frame->save_regs_using_mov = false; frame->save_regs_using_mov = false;
if (!TARGET_64BIT_MS_ABI && TARGET_RED_ZONE && current_function_sp_is_unchanging if (!TARGET_64BIT_MS_ABI && TARGET_RED_ZONE
&& current_function_sp_is_unchanging
&& current_function_is_leaf && current_function_is_leaf
&& !ix86_current_function_calls_tls_descriptor) && !ix86_current_function_calls_tls_descriptor)
{ {
...@@ -19151,20 +19231,13 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, ...@@ -19151,20 +19231,13 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
&& GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
&& !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode)) && !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode))
fnaddr = gen_rtx_MEM (QImode, construct_plt_address (XEXP (fnaddr, 0))); fnaddr = gen_rtx_MEM (QImode, construct_plt_address (XEXP (fnaddr, 0)));
else if (! call_insn_operand (XEXP (fnaddr, 0), Pmode)) else if (sibcall
? !sibcall_insn_operand (XEXP (fnaddr, 0), Pmode)
: !call_insn_operand (XEXP (fnaddr, 0), Pmode))
{ {
fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0)); fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
fnaddr = gen_rtx_MEM (QImode, fnaddr); fnaddr = gen_rtx_MEM (QImode, fnaddr);
} }
if (sibcall && TARGET_64BIT
&& !constant_call_address_operand (XEXP (fnaddr, 0), Pmode))
{
rtx addr;
addr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
fnaddr = gen_rtx_REG (Pmode, R11_REG);
emit_move_insn (fnaddr, addr);
fnaddr = gen_rtx_MEM (QImode, fnaddr);
}
call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1); call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
if (retval) if (retval)
......
...@@ -960,52 +960,7 @@ enum target_cpu_default ...@@ -960,52 +960,7 @@ enum target_cpu_default
#define OVERRIDE_ABI_FORMAT(FNDECL) ix86_call_abi_override (FNDECL) #define OVERRIDE_ABI_FORMAT(FNDECL) ix86_call_abi_override (FNDECL)
/* Macro to conditionally modify fixed_regs/call_used_regs. */ /* Macro to conditionally modify fixed_regs/call_used_regs. */
#define CONDITIONAL_REGISTER_USAGE \ #define CONDITIONAL_REGISTER_USAGE ix86_conditional_register_usage ()
do { \
int i; \
unsigned int j; \
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) \
{ \
if (fixed_regs[i] > 1) \
fixed_regs[i] = (fixed_regs[i] == (TARGET_64BIT ? 3 : 2)); \
if (call_used_regs[i] > 1) \
call_used_regs[i] = (call_used_regs[i] \
== (TARGET_64BIT ? 3 : 2)); \
} \
j = PIC_OFFSET_TABLE_REGNUM; \
if (j != INVALID_REGNUM) \
fixed_regs[j] = call_used_regs[j] = 1; \
if (TARGET_64BIT \
&& ((cfun && cfun->machine->call_abi == MS_ABI) \
|| (!cfun && ix86_abi == MS_ABI))) \
{ \
call_used_regs[SI_REG] = 0; \
call_used_regs[DI_REG] = 0; \
call_used_regs[XMM6_REG] = 0; \
call_used_regs[XMM7_REG] = 0; \
for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++) \
call_used_regs[i] = 0; \
} \
if (! TARGET_MMX) \
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) \
if (TEST_HARD_REG_BIT (reg_class_contents[(int)MMX_REGS], i)) \
fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; \
if (! TARGET_SSE) \
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) \
if (TEST_HARD_REG_BIT (reg_class_contents[(int)SSE_REGS], i)) \
fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; \
if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387)) \
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) \
if (TEST_HARD_REG_BIT (reg_class_contents[(int)FLOAT_REGS], i)) \
fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; \
if (! TARGET_64BIT) \
{ \
for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++) \
reg_names[i] = ""; \
for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++) \
reg_names[i] = ""; \
} \
} while (0)
/* Return number of consecutive hard regs needed starting at reg REGNO /* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE. to hold something of mode MODE.
...@@ -1225,6 +1180,7 @@ enum reg_class ...@@ -1225,6 +1180,7 @@ enum reg_class
NO_REGS, NO_REGS,
AREG, DREG, CREG, BREG, SIREG, DIREG, AREG, DREG, CREG, BREG, SIREG, DIREG,
AD_REGS, /* %eax/%edx for DImode */ AD_REGS, /* %eax/%edx for DImode */
CLOBBERED_REGS, /* call-clobbered integers */
Q_REGS, /* %eax %ebx %ecx %edx */ Q_REGS, /* %eax %ebx %ecx %edx */
NON_Q_REGS, /* %esi %edi %ebp %esp */ NON_Q_REGS, /* %esi %edi %ebp %esp */
INDEX_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp */ INDEX_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp */
...@@ -1273,6 +1229,7 @@ enum reg_class ...@@ -1273,6 +1229,7 @@ enum reg_class
"AREG", "DREG", "CREG", "BREG", \ "AREG", "DREG", "CREG", "BREG", \
"SIREG", "DIREG", \ "SIREG", "DIREG", \
"AD_REGS", \ "AD_REGS", \
"CLOBBERED_REGS", \
"Q_REGS", "NON_Q_REGS", \ "Q_REGS", "NON_Q_REGS", \
"INDEX_REGS", \ "INDEX_REGS", \
"LEGACY_REGS", \ "LEGACY_REGS", \
...@@ -1290,9 +1247,11 @@ enum reg_class ...@@ -1290,9 +1247,11 @@ enum reg_class
"FLOAT_INT_SSE_REGS", \ "FLOAT_INT_SSE_REGS", \
"ALL_REGS" } "ALL_REGS" }
/* Define which registers fit in which classes. /* Define which registers fit in which classes. This is an initializer
This is an initializer for a vector of HARD_REG_SET for a vector of HARD_REG_SET of length N_REG_CLASSES.
of length N_REG_CLASSES. */
Note that the default setting of CLOBBERED_REGS is for 32-bit; this
is adjusted by CONDITIONAL_REGISTER_USAGE for the 64-bit ABI in effect. */
#define REG_CLASS_CONTENTS \ #define REG_CLASS_CONTENTS \
{ { 0x00, 0x0 }, \ { { 0x00, 0x0 }, \
...@@ -1300,6 +1259,7 @@ enum reg_class ...@@ -1300,6 +1259,7 @@ enum reg_class
{ 0x04, 0x0 }, { 0x08, 0x0 }, /* CREG, BREG */ \ { 0x04, 0x0 }, { 0x08, 0x0 }, /* CREG, BREG */ \
{ 0x10, 0x0 }, { 0x20, 0x0 }, /* SIREG, DIREG */ \ { 0x10, 0x0 }, { 0x20, 0x0 }, /* SIREG, DIREG */ \
{ 0x03, 0x0 }, /* AD_REGS */ \ { 0x03, 0x0 }, /* AD_REGS */ \
{ 0x07, 0x0 }, /* CLOBBERED_REGS */ \
{ 0x0f, 0x0 }, /* Q_REGS */ \ { 0x0f, 0x0 }, /* Q_REGS */ \
{ 0x1100f0, 0x1fe0 }, /* NON_Q_REGS */ \ { 0x1100f0, 0x1fe0 }, /* NON_Q_REGS */ \
{ 0x7f, 0x1fe0 }, /* INDEX_REGS */ \ { 0x7f, 0x1fe0 }, /* INDEX_REGS */ \
......
...@@ -15536,14 +15536,12 @@ ...@@ -15536,14 +15536,12 @@
[(set_attr "type" "call")]) [(set_attr "type" "call")])
(define_insn "*sibcall_1" (define_insn "*sibcall_1"
[(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a")) [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
(match_operand 1 "" ""))] (match_operand 1 "" ""))]
"SIBLING_CALL_P (insn) && !TARGET_64BIT" "SIBLING_CALL_P (insn) && !TARGET_64BIT"
{ "@
if (constant_call_address_operand (operands[0], Pmode)) jmp\t%P0
return "jmp\t%P0"; jmp\t%A0"
return "jmp\t%A0";
}
[(set_attr "type" "call")]) [(set_attr "type" "call")])
(define_insn "*call_1_rex64" (define_insn "*call_1_rex64"
...@@ -15590,22 +15588,15 @@ ...@@ -15590,22 +15588,15 @@
[(set_attr "type" "call")]) [(set_attr "type" "call")])
(define_insn "*sibcall_1_rex64" (define_insn "*sibcall_1_rex64"
[(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" "")) [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
(match_operand 1 "" ""))] (match_operand 1 "" ""))]
"SIBLING_CALL_P (insn) && TARGET_64BIT" "SIBLING_CALL_P (insn) && TARGET_64BIT"
"jmp\t%P0" "@
[(set_attr "type" "call")]) jmp\t%P0
jmp\t%A0"
(define_insn "*sibcall_1_rex64_v"
[(call (mem:QI (reg:DI R11_REG))
(match_operand 0 "" ""))]
"SIBLING_CALL_P (insn) && TARGET_64BIT"
"jmp\t{*%%}r11"
[(set_attr "type" "call")]) [(set_attr "type" "call")])
;; Call subroutine, returning value in operand 0 ;; Call subroutine, returning value in operand 0
(define_expand "call_value_pop" (define_expand "call_value_pop"
[(parallel [(set (match_operand 0 "" "") [(parallel [(set (match_operand 0 "" "")
(call (match_operand:QI 1 "" "") (call (match_operand:QI 1 "" "")
...@@ -22183,14 +22174,12 @@ ...@@ -22183,14 +22174,12 @@
(define_insn "*sibcall_value_1" (define_insn "*sibcall_value_1"
[(set (match_operand 0 "" "") [(set (match_operand 0 "" "")
(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a")) (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
(match_operand:SI 2 "" "")))] (match_operand:SI 2 "" "")))]
"SIBLING_CALL_P (insn) && !TARGET_64BIT" "SIBLING_CALL_P (insn) && !TARGET_64BIT"
{ "@
if (constant_call_address_operand (operands[1], Pmode)) jmp\t%P1
return "jmp\t%P1"; jmp\t%A1"
return "jmp\t%A1";
}
[(set_attr "type" "callv")]) [(set_attr "type" "callv")])
(define_insn "*call_value_1_rex64" (define_insn "*call_value_1_rex64"
...@@ -22241,18 +22230,12 @@ ...@@ -22241,18 +22230,12 @@
(define_insn "*sibcall_value_1_rex64" (define_insn "*sibcall_value_1_rex64"
[(set (match_operand 0 "" "") [(set (match_operand 0 "" "")
(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
(match_operand:DI 2 "" "")))] (match_operand:DI 2 "" "")))]
"SIBLING_CALL_P (insn) && TARGET_64BIT" "SIBLING_CALL_P (insn) && TARGET_64BIT"
"jmp\t%P1" "@
[(set_attr "type" "callv")]) jmp\t%P1
jmp\t%A1"
(define_insn "*sibcall_value_1_rex64_v"
[(set (match_operand 0 "" "")
(call (mem:QI (reg:DI R11_REG))
(match_operand:DI 1 "" "")))]
"SIBLING_CALL_P (insn) && TARGET_64BIT"
"jmp\t{*%%}r11"
[(set_attr "type" "callv")]) [(set_attr "type" "callv")])
;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
......
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