@@ -94,6 +94,7 @@ along with GCC; see the file COPYING3. If not see
#include "i386-builtins.h"
#include "i386-expand.h"
#include "asan.h"
+#include "function-abi.h"
/* Split one or more double-mode RTL references into pairs of half-mode
references. The RTL can be REG, offsettable MEM, integer constant, or
@@ -11329,17 +11330,6 @@ construct_plt_address (rtx symbol)
return tmp;
}
-/* Additional registers that are clobbered by SYSV calls. */
-
-static int const x86_64_ms_sysv_extra_clobbered_registers
- [NUM_X86_64_MS_CLOBBERED_REGS] =
-{
- SI_REG, DI_REG,
- XMM6_REG, XMM7_REG,
- XMM8_REG, XMM9_REG, XMM10_REG, XMM11_REG,
- XMM12_REG, XMM13_REG, XMM14_REG, XMM15_REG
-};
-
rtx_insn *
ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
rtx callarg2,
@@ -11349,7 +11339,6 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
rtx use = NULL, call;
unsigned int vec_len = 0;
tree fndecl;
- bool call_no_callee_saved_registers = false;
if (SYMBOL_REF_P (XEXP (fnaddr, 0)))
{
@@ -11359,26 +11348,13 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
if (lookup_attribute ("interrupt",
TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
error ("interrupt service routine cannot be called directly");
- else if (ix86_type_no_callee_saved_registers_p (TREE_TYPE (fndecl)))
- call_no_callee_saved_registers = true;
if (fndecl == current_function_decl
&& decl_binds_to_current_def_p (fndecl))
cfun->machine->recursive_function = true;
}
}
else
- {
- if (MEM_P (fnaddr))
- {
- tree mem_expr = MEM_EXPR (fnaddr);
- if (mem_expr != nullptr
- && TREE_CODE (mem_expr) == MEM_REF
- && ix86_type_no_callee_saved_registers_p (TREE_TYPE (mem_expr)))
- call_no_callee_saved_registers = true;
- }
-
- fndecl = NULL_TREE;
- }
+ fndecl = NULL_TREE;
if (pop == const0_rtx)
pop = NULL;
@@ -11515,62 +11491,26 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
vec[vec_len++] = pop;
}
- static const char ix86_call_used_regs[] = CALL_USED_REGISTERS;
-
- if ((cfun->machine->call_saved_registers
- == TYPE_NO_CALLER_SAVED_REGISTERS)
- && (!fndecl
- || (!TREE_THIS_VOLATILE (fndecl)
- && !lookup_attribute ("no_caller_saved_registers",
- TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))))
+ /* Set here, but it may get cleared later. */
+ if (TARGET_64BIT_MS_ABI
+ && (!callarg2 || INTVAL (callarg2) != -2)
+ && TARGET_CALL_MS2SYSV_XLOGUES)
{
- bool is_64bit_ms_abi = (TARGET_64BIT
- && ix86_function_abi (fndecl) == MS_ABI);
- char c_mask = CALL_USED_REGISTERS_MASK (is_64bit_ms_abi);
-
- /* If there are no caller-saved registers, add all registers
- that are clobbered by the call which returns. */
- for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (!fixed_regs[i]
- && (ix86_call_used_regs[i] == 1
- || (ix86_call_used_regs[i] & c_mask))
- && !STACK_REGNO_P (i)
- && !MMX_REGNO_P (i))
- clobber_reg (&use,
- gen_rtx_REG (GET_MODE (regno_reg_rtx[i]), i));
- }
- else if (TARGET_64BIT_MS_ABI
- && (!callarg2 || INTVAL (callarg2) != -2))
- {
- unsigned i;
+ if (!TARGET_SSE)
+ ;
- for (i = 0; i < NUM_X86_64_MS_CLOBBERED_REGS; i++)
- {
- int regno = x86_64_ms_sysv_extra_clobbered_registers[i];
- machine_mode mode = SSE_REGNO_P (regno) ? TImode : DImode;
+ /* Don't break hot-patched functions. */
+ else if (ix86_function_ms_hook_prologue (current_function_decl))
+ ;
- clobber_reg (&use, gen_rtx_REG (mode, regno));
- }
+ /* TODO: Cases not yet examined. */
+ else if (flag_split_stack)
+ warn_once_call_ms2sysv_xlogues ("-fsplit-stack");
- /* Set here, but it may get cleared later. */
- if (TARGET_CALL_MS2SYSV_XLOGUES)
+ else
{
- if (!TARGET_SSE)
- ;
-
- /* Don't break hot-patched functions. */
- else if (ix86_function_ms_hook_prologue (current_function_decl))
- ;
-
- /* TODO: Cases not yet examined. */
- else if (flag_split_stack)
- warn_once_call_ms2sysv_xlogues ("-fsplit-stack");
-
- else
- {
- gcc_assert (!reload_completed);
- cfun->machine->call_ms2sysv = true;
- }
+ gcc_assert (!reload_completed);
+ cfun->machine->call_ms2sysv = true;
}
}
@@ -11588,25 +11528,6 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
clobber_reg (&use, gen_rtx_REG (DImode, R10_REG));
}
- if (call_no_callee_saved_registers)
- {
- /* After calling a no_callee_saved_registers function, all
- registers may be clobbered. Clobber all registers that are
- not used by the callee. */
- bool is_64bit_ms_abi = (TARGET_64BIT
- && ix86_function_abi (fndecl) == MS_ABI);
- char c_mask = CALL_USED_REGISTERS_MASK (is_64bit_ms_abi);
- for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (!fixed_regs[i]
- && i != HARD_FRAME_POINTER_REGNUM
- && !(ix86_call_used_regs[i] == 1
- || (ix86_call_used_regs[i] & c_mask))
- && !STACK_REGNO_P (i)
- && !MMX_REGNO_P (i))
- clobber_reg (&use,
- gen_rtx_REG (GET_MODE (regno_reg_rtx[i]), i));
- }
-
if (vec_len > 1)
call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (vec_len, vec));
rtx_insn *call_insn = emit_call_insn (call);
@@ -4527,6 +4527,7 @@ ix86_place_single_tls_call (rtx dest, rtx val, x86_cse_kind kind,
symbol = XVECEXP (val, 0, 0);
tls = gen_tls_global_dynamic_64 (Pmode, rax, symbol, caddr, rdi);
+ CALL_INSN_ABI_ID (tls) = ix86_tls_get_addr_abi ().id ();
if (GET_MODE (symbol) != Pmode)
symbol = gen_rtx_ZERO_EXTEND (Pmode, symbol);
@@ -4539,6 +4540,7 @@ ix86_place_single_tls_call (rtx dest, rtx val, x86_cse_kind kind,
caddr = ix86_tls_get_addr ();
tls = gen_tls_local_dynamic_base_64 (Pmode, rax, caddr, rdi);
+ CALL_INSN_ABI_ID (tls) = ix86_tls_get_addr_abi ().id ();
/* Attach a unique REG_EQUAL to DEST, to allow the RTL optimizers
to share the LD_BASE result with other LD model accesses. */
@@ -3525,21 +3525,6 @@ ix86_set_current_function (tree fndecl)
}
ix86_previous_fndecl = fndecl;
- static call_saved_registers_type prev_call_saved_registers;
-
- /* 64-bit MS and SYSV ABI have different set of call used registers.
- Avoid expensive re-initialization of init_regs each time we switch
- function context. */
- if (TARGET_64BIT
- && (call_used_or_fixed_reg_p (SI_REG)
- == (cfun->machine->call_abi == MS_ABI)))
- reinit_regs ();
- /* Need to re-initialize init_regs if caller-saved registers are
- changed. */
- else if (prev_call_saved_registers
- != cfun->machine->call_saved_registers)
- reinit_regs ();
-
if (cfun->machine->func_type != TYPE_NORMAL
|| (cfun->machine->call_saved_registers
== TYPE_NO_CALLER_SAVED_REGISTERS))
@@ -3587,8 +3572,6 @@ ix86_set_current_function (tree fndecl)
= TYPE_DEFAULT_CALL_SAVED_REGISTERS;
}
}
-
- prev_call_saved_registers = cfun->machine->call_saved_registers;
}
/* Implement the TARGET_OFFLOAD_OPTIONS hook. */
@@ -286,7 +286,6 @@ extern tree ix86_valid_target_attribute_tree (tree, tree,
struct gcc_options *,
struct gcc_options *, bool);
extern unsigned int ix86_get_callcvt (const_tree);
-extern bool ix86_type_no_callee_saved_registers_p (const_tree);
#endif
@@ -295,6 +294,8 @@ extern bool ix86_gpr_tls_address_pattern_p (rtx);
extern bool ix86_tls_address_pattern_p (rtx);
extern rtx ix86_rewrite_tls_address (rtx);
extern rtx ix86_tls_get_addr (void);
+class predefined_function_abi;
+extern const predefined_function_abi & ix86_tls_get_addr_abi (void);
extern void ix86_expand_vector_init (bool, rtx, rtx);
extern void ix86_expand_vector_set (bool, rtx, rtx, int);
@@ -107,6 +107,7 @@ along with GCC; see the file COPYING3. If not see
static void ix86_print_operand_address_as (FILE *, rtx, addr_space_t, bool);
static void ix86_emit_restore_reg_using_pop (rtx, bool = false);
+static const predefined_function_abi & ix86_alternate_abi (void);
#ifndef CHECK_STACK_LIMIT
@@ -503,17 +504,6 @@ ix86_conditional_register_usage (void)
{
int i, c_mask;
- /* If there are no caller-saved registers, preserve all registers.
- except fixed_regs and registers used for function return value
- since aggregate_value_p checks call_used_regs[regno] on return
- value. */
- if (cfun
- && (cfun->machine->call_saved_registers
- == TYPE_NO_CALLER_SAVED_REGISTERS))
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (!fixed_regs[i] && !ix86_function_value_regno_p (i))
- call_used_regs[i] = 0;
-
/* For 32-bit targets, disable the REX registers. */
if (! TARGET_64BIT)
{
@@ -525,8 +515,10 @@ ix86_conditional_register_usage (void)
CLEAR_HARD_REG_BIT (accessible_reg_set, i);
}
- /* See the definition of CALL_USED_REGISTERS in i386.h. */
- c_mask = CALL_USED_REGISTERS_MASK (TARGET_64BIT_MS_ABI);
+ /* Set up the call-used registers based on the system ABI (ix86_abi).
+
+ See the definition of CALL_USED_REGISTERS in i386.h. */
+ c_mask = CALL_USED_REGISTERS_MASK (TARGET_64BIT && ix86_abi == MS_ABI);
CLEAR_HARD_REG_SET (reg_class_contents[(int)CLOBBERED_REGS]);
@@ -932,7 +924,7 @@ x86_64_elf_unique_section (tree decl, int reloc)
/* Return true if TYPE has no_callee_saved_registers or preserve_none
attribute. */
-bool
+static bool
ix86_type_no_callee_saved_registers_p (const_tree fntype)
{
auto type = ix86_fntype_call_saved_registers (fntype);
@@ -3871,10 +3863,10 @@ ix86_function_value_regno_p (const unsigned int regno)
/* Complex values are returned in %st(0)/%st(1) pair. */
case ST0_REG:
case ST1_REG:
- /* TODO: The function should depend on current function ABI but
- builtins.cc would need updating then. Therefore we use the
- default ABI. */
- if (TARGET_64BIT && ix86_cfun_abi () == MS_ABI)
+ /* TODO: An ABI identifier should be passed as a parameter.
+ For now, most callers, including those in builtins.cc,
+ expect us to use the default ABI. */
+ if (TARGET_64BIT && ix86_abi == MS_ABI)
return false;
return TARGET_FLOAT_RETURNS_IN_80387;
@@ -6796,8 +6788,6 @@ ix86_hard_regno_scratch_ok (unsigned int regno)
bool
ix86_save_reg (unsigned int regno, bool maybe_eh_return, bool ignore_outlined)
{
- rtx reg;
-
/* Save and restore DRAP register between prologue and epilogue so
that stack pointer can be restored. */
if (crtl->drap_reg
@@ -6805,41 +6795,12 @@ ix86_save_reg (unsigned int regno, bool maybe_eh_return, bool ignore_outlined)
&& !cfun->machine->no_drap_save_restore)
return true;
- switch (cfun->machine->call_saved_registers)
- {
- case TYPE_DEFAULT_CALL_SAVED_REGISTERS:
- break;
-
- case TYPE_NO_CALLER_SAVED_REGISTERS:
- /* If there are no caller-saved registers, we preserve all
- registers, except for MMX and x87 registers which aren't
- supported when saving and restoring registers. Don't
- explicitly save SP register since it is always preserved.
-
- Don't preserve registers used for function return value. */
- reg = crtl->return_rtx;
- if (reg)
- {
- unsigned int i = REGNO (reg);
- unsigned int nregs = REG_NREGS (reg);
- while (nregs-- > 0)
- if ((i + nregs) == regno)
- return false;
- }
-
- return (df_regs_ever_live_p (regno)
- && !fixed_regs[regno]
- && !STACK_REGNO_P (regno)
- && !MMX_REGNO_P (regno)
- && (regno != HARD_FRAME_POINTER_REGNUM
- || !frame_pointer_needed));
-
- case TYPE_NO_CALLEE_SAVED_REGISTERS:
- case TYPE_PRESERVE_NONE:
- if (regno != HARD_FRAME_POINTER_REGNUM)
- return false;
- break;
- }
+ /* ??? Treat no_callee_saved_registers as a special case in order
+ to cope with -mnoreturn-no-callee-saved-registers, which is not
+ reflected in crtl->abi. */
+ if (cfun->machine->call_saved_registers == TYPE_NO_CALLEE_SAVED_REGISTERS
+ && regno != HARD_FRAME_POINTER_REGNUM)
+ return false;
if (regno == REAL_PIC_OFFSET_TABLE_REGNUM
&& pic_offset_table_rtx)
@@ -12574,6 +12535,18 @@ ix86_tls_get_addr (void)
return ix86_tls_symbol;
}
+/* Return the descriptor of the function ABI type for the tls_get_addr
+ function. */
+
+const predefined_function_abi &
+ix86_tls_get_addr_abi (void)
+{
+ if (ix86_abi == SYSV_ABI)
+ return default_function_abi;
+ else
+ return ix86_alternate_abi ();
+}
+
/* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
static GTY(()) rtx ix86_tls_module_base_symbol;
@@ -12684,8 +12657,10 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
rtx_insn *insns;
start_sequence ();
- emit_call_insn
+ rtx_insn *call_insn = emit_call_insn
(gen_tls_global_dynamic_64 (Pmode, rax, x, caddr, rdi));
+ CALL_INSN_ABI_ID (call_insn)
+ = ix86_tls_get_addr_abi ().id ();
insns = end_sequence ();
if (GET_MODE (x) != Pmode)
@@ -12739,8 +12714,10 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
rtx eqv;
start_sequence ();
- emit_call_insn
+ rtx_insn *call_insn = emit_call_insn
(gen_tls_local_dynamic_base_64 (Pmode, rax, caddr, rdi));
+ CALL_INSN_ABI_ID (call_insn)
+ = ix86_tls_get_addr_abi ().id ();
insns = end_sequence ();
/* Attach a unique REG_EQUAL, to allow the RTL optimizers to
@@ -21738,6 +21715,243 @@ ix86_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
return false;
}
+/* Initialize function_abis[ABI_ID] with the set of register clobbers
+ in FULL_REG_CLOBBERS, adjusting for rules that apply to all ABIs. */
+
+static void
+ix86_initialize_abi (unsigned int abi_id, HARD_REG_SET full_reg_clobbers)
+{
+ /* The general rule is that fixed registers should be marked as
+ call-clobbered. This includes global registers, inaccessible
+ registers, the flags register, and the FPSR.
+
+ Handle the exceptions below. */
+ full_reg_clobbers |= fixed_reg_set;
+
+ /* Every ABI (even preserve_none) preserves EBP/RBP. */
+ CLEAR_HARD_REG_BIT (full_reg_clobbers, HARD_FRAME_POINTER_REGNUM);
+
+ /* Treat GCC's internal frame-related registers as call-preserved. */
+ CLEAR_HARD_REG_BIT (full_reg_clobbers, FRAME_POINTER_REGNUM);
+ CLEAR_HARD_REG_BIT (full_reg_clobbers, ARG_POINTER_REGNUM);
+
+ /* MMX registers aren't preserved. */
+ if (TARGET_MMX)
+ full_reg_clobbers |= reg_class_contents[MMX_REGS];
+
+ /* X87 registers aren't preserved. */
+ if (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387)
+ full_reg_clobbers |= reg_class_contents[FLOAT_REGS];
+
+ function_abis[abi_id].initialize (abi_id, full_reg_clobbers);
+}
+
+/* Return the descriptor of no_callee_saved_registers function type.
+ None of the enabled registers are preserved, except for the common
+ rules applied by ix86_initialize_abi. */
+
+static const predefined_function_abi &
+ix86_no_callee_saved_abi (void)
+{
+ auto &no_callee_saved_abi = function_abis[ABI_NO_CALLEE_SAVED];
+ if (!no_callee_saved_abi.initialized_p ())
+ ix86_initialize_abi (ABI_NO_CALLEE_SAVED, accessible_reg_set);
+ return no_callee_saved_abi;
+}
+
+/* Return the descriptor of the no_caller_saved_registers function type
+ with ABI identifier ABI_ID. All registers are preserved, except for:
+
+ - the return registers, which are enumerated in ABI_ID.
+
+ - the common rules applied by ix86_initialize_abi. */
+
+static const predefined_function_abi &
+ix86_no_caller_saved_abi (unsigned int abi_id)
+{
+ auto &abi = function_abis[abi_id];
+ if (!abi.initialized_p ())
+ {
+ HARD_REG_SET full_reg_clobbers = {};
+
+ switch (abi_id)
+ {
+ case ABI_NO_CALLER_SAVED_RETURN_VOID:
+ break;
+
+ case ABI_NO_CALLER_SAVED_RETURN_AX_DX:
+ SET_HARD_REG_BIT (full_reg_clobbers, DX_REG);
+ /* Fall through. */
+ case ABI_NO_CALLER_SAVED_RETURN_AX:
+ SET_HARD_REG_BIT (full_reg_clobbers, AX_REG);
+ break;
+
+ case ABI_NO_CALLER_SAVED_RETURN_AX_XMM0:
+ SET_HARD_REG_BIT (full_reg_clobbers, AX_REG);
+ SET_HARD_REG_BIT (full_reg_clobbers, XMM0_REG);
+ break;
+
+ case ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1:
+ SET_HARD_REG_BIT (full_reg_clobbers, XMM1_REG);
+ /* Fall through. */
+ case ABI_NO_CALLER_SAVED_RETURN_XMM0:
+ SET_HARD_REG_BIT (full_reg_clobbers, XMM0_REG);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ ix86_initialize_abi (abi_id, full_reg_clobbers);
+ }
+ return abi;
+}
+
+/* Return the descriptor of the standard function ABI type. If
+ ABI_TYPE == ABI_ALTERNATE, return the function alternate ABI type. */
+
+static const predefined_function_abi &
+ix86_standard_abi (int abi_type)
+{
+ static const char ix86_call_used_regs[] = CALL_USED_REGISTERS;
+ auto &standard_abi = function_abis[abi_type];
+ if (!standard_abi.initialized_p ())
+ {
+ HARD_REG_SET full_reg_clobbers = {};
+
+ /* Add all registers that are clobbered by the call. NB: If the
+ current ABI is SYSV_ABI, the alternate ABI is MS_ABI. */
+ bool is_64bit_ms_abi = (TARGET_64BIT
+ && ix86_abi == (abi_type == ABI_ALTERNATE
+ ? SYSV_ABI : MS_ABI));
+ char c_mask = CALL_USED_REGISTERS_MASK (is_64bit_ms_abi);
+ for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (ix86_call_used_regs[i] == 1
+ || (ix86_call_used_regs[i] & c_mask))
+ SET_HARD_REG_BIT (full_reg_clobbers, i);
+
+ ix86_initialize_abi (abi_type, full_reg_clobbers);
+ }
+ return standard_abi;
+}
+
+/* Return the descriptor of the function alternate ABI type. */
+
+static const predefined_function_abi &
+ix86_alternate_abi (void)
+{
+ return ix86_standard_abi (ABI_ALTERNATE);
+}
+
+/* Return the function ABI ID based on FNTYPE. */
+
+static int
+ix86_function_abi_id (const_tree fntype)
+{
+ auto call_saved_registers = ix86_fntype_call_saved_registers (fntype);
+ if (call_saved_registers == TYPE_PRESERVE_NONE
+ || call_saved_registers == TYPE_NO_CALLEE_SAVED_REGISTERS)
+ return ABI_NO_CALLEE_SAVED;
+
+ if (call_saved_registers == TYPE_NO_CALLER_SAVED_REGISTERS)
+ {
+ tree type = TREE_TYPE (fntype);
+ if (VOID_TYPE_P (type))
+ return ABI_NO_CALLER_SAVED_RETURN_VOID;
+ /* AX register contains the address of the return value location
+ passed in by the caller. */
+ else if (ix86_return_in_memory (type, fntype))
+ return ABI_NO_CALLER_SAVED_RETURN_AX;
+ rtx ret = ix86_function_value (type, fntype, false);
+ unsigned int nregs;
+ if (REG_P (ret))
+ {
+ unsigned int regno = REGNO (ret);
+ if (STACK_REGNO_P (regno) || MMX_REGNO_P (regno))
+ return ABI_NO_CALLER_SAVED_RETURN_VOID;
+ else
+ switch (regno)
+ {
+ case AX_REG:
+ nregs = REG_NREGS (ret);
+ if (nregs == 1)
+ return ABI_NO_CALLER_SAVED_RETURN_AX;
+ else if (nregs == 2)
+ return ABI_NO_CALLER_SAVED_RETURN_AX_DX;
+ gcc_unreachable ();
+ case XMM0_REG:
+ return ABI_NO_CALLER_SAVED_RETURN_XMM0;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ else if (GET_CODE (ret) == PARALLEL && XVECLEN (ret, 0) == 2)
+ {
+ rtx x0 = XVECEXP (ret, 0, 0);
+ rtx x1 = XVECEXP (ret, 0, 1);
+ if (GET_CODE (x0) == EXPR_LIST
+ && GET_CODE (x1) == EXPR_LIST)
+ {
+ x0 = XEXP (x0, 0);
+ x1 = XEXP (x1, 0);
+ if (REG_P (x0) && REGNO (x0) == AX_REG)
+ {
+ if (REG_P (x1) && REGNO (x1) == XMM0_REG)
+ return ABI_NO_CALLER_SAVED_RETURN_AX_XMM0;
+ }
+ if (REG_P (x0) && REGNO (x0) == XMM0_REG && REG_P (x1))
+ {
+ if (REGNO (x1) == AX_REG)
+ return ABI_NO_CALLER_SAVED_RETURN_AX_XMM0;
+ else if (REGNO (x1) == XMM1_REG)
+ return ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1;
+ }
+ }
+
+ gcc_unreachable ();
+ }
+ }
+
+ /* NB: This must be the last since other attributes change the
+ function ABI. */
+ if (ix86_function_type_abi (fntype) != ix86_abi)
+ return ABI_ALTERNATE;
+
+ return ABI_DEFAULT;
+}
+
+/* Implement TARGET_FNTYPE_ABI. */
+
+static const predefined_function_abi &
+ix86_fntype_abi (const_tree fntype)
+{
+ unsigned int abi_id = ix86_function_abi_id (fntype);
+ switch (abi_id)
+ {
+ case ABI_DEFAULT:
+ return default_function_abi;
+
+ case ABI_ALTERNATE:
+ return ix86_alternate_abi ();
+
+ case ABI_NO_CALLEE_SAVED:
+ return ix86_no_callee_saved_abi ();
+
+ case ABI_NO_CALLER_SAVED_RETURN_VOID:
+ case ABI_NO_CALLER_SAVED_RETURN_AX:
+ case ABI_NO_CALLER_SAVED_RETURN_AX_DX:
+ case ABI_NO_CALLER_SAVED_RETURN_AX_XMM0:
+ case ABI_NO_CALLER_SAVED_RETURN_XMM0:
+ case ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1:
+ return ix86_no_caller_saved_abi (abi_id);
+
+ default:
+ gcc_unreachable ();
+ }
+
+ return default_function_abi;
+}
+
/* Initialize function_abis with corresponding abi_id,
currently only handle vzeroupper. */
void
@@ -21776,12 +21990,38 @@ static bool
ix86_hard_regno_call_part_clobbered (unsigned int abi_id, unsigned int regno,
machine_mode mode)
{
- /* Special ABI for vzeroupper which only clobber higher part of sse regs. */
- if (abi_id == ABI_VZEROUPPER)
+ switch (abi_id)
+ {
+ case ABI_VZEROUPPER:
+ /* Special ABI for vzeroupper which only clobbers higher part of
+ SSE registers. */
return (GET_MODE_SIZE (mode) > 16
&& ((TARGET_64BIT && REX_SSE_REGNO_P (regno))
|| LEGACY_SSE_REGNO_P (regno)));
+ case ABI_DEFAULT:
+ case ABI_ALTERNATE:
+ case ABI_NO_CALLEE_SAVED:
+ break;
+
+ case ABI_NO_CALLER_SAVED_RETURN_VOID:
+ case ABI_NO_CALLER_SAVED_RETURN_AX:
+ case ABI_NO_CALLER_SAVED_RETURN_AX_DX:
+ /* These ABIs don't clobber SSE registers. */
+ return false;
+
+ case ABI_NO_CALLER_SAVED_RETURN_AX_XMM0:
+ case ABI_NO_CALLER_SAVED_RETURN_XMM0:
+ case ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1:
+ /* These ABIs return some values in SSE registers and preserve
+ the rest. The return value registers (XMM0 and possibly XMM1)
+ are fully rather than partially call-clobbered. */
+ return false;
+
+ default:
+ gcc_unreachable ();
+ }
+
return SSE_REGNO_P (regno) && GET_MODE_SIZE (mode) > 16;
}
@@ -28708,6 +28948,9 @@ ix86_libgcc_floating_mode_supported_p
#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
ix86_hard_regno_call_part_clobbered
+#undef TARGET_FNTYPE_ABI
+#define TARGET_FNTYPE_ABI ix86_fntype_abi
+
#undef TARGET_CAN_CHANGE_MODE_CLASS
#define TARGET_CAN_CHANGE_MODE_CLASS ix86_can_change_mode_class
@@ -513,9 +513,35 @@ (define_constants
;; Insn callee abi index.
(define_constants
- [(ABI_DEFAULT 0)
- (ABI_VZEROUPPER 1)
- (ABI_UNKNOWN 2)])
+ [;; The system ABI; that is, the ABI associated with ix86_abi, and the
+ ;; ABI that an undecorated "void foo()" would have.
+ (ABI_DEFAULT 0)
+ ;; An ABI that describes the effect of vzeroupper. vzeroupper is
+ ;; represented as a call because calls are the main mechanism for
+ ;; expression partial register clobbers.
+ (ABI_VZEROUPPER 1)
+ ;; ABI_ALTERNATE is the Windows function ABI if ix86_abi == SYSV_ABI
+ ;; and is the SYSV function ABI if ix86_abi == MS_ABI.
+ (ABI_ALTERNATE 2)
+ (ABI_NO_CALLEE_SAVED 3)
+ ;; Return void.
+ (ABI_NO_CALLER_SAVED_RETURN_VOID 4)
+ ;; Return char, short, int in 32-bit/64-bit.
+ ;; Return int64 and _Complex int in 64-bit.
+ ;; Return _Complex float in MS 32-bit/64-bit.
+ (ABI_NO_CALLER_SAVED_RETURN_AX 5)
+ ;; Return int64 and _Complex int in 32-bit.
+ ;; Return _Complex int64 in 64-bit.
+ (ABI_NO_CALLER_SAVED_RETURN_AX_DX 6)
+ ;; Return struct pair with int64 and double in 64-bit.
+ (ABI_NO_CALLER_SAVED_RETURN_AX_XMM0 7)
+ ;; Return float and double in 64-bit.
+ ;; Return _Complex float in SYSV 64-bit.
+ ;; Return int28, _Complex double in MS 64-bit.
+ (ABI_NO_CALLER_SAVED_RETURN_XMM0 8)
+ ;; Return _Complex double in SYSV 64-bit.
+ (ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1 9)
+ (ABI_UNKNOWN 10)])
;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
;; from i386.cc.
new file mode 100644
@@ -0,0 +1,21 @@
+/* { dg-do compile { target { ! x32 } } } */
+/* { dg-options "-O2 -masm=att -mno-mmx -mno-80387 -msse" } */
+
+extern void callee_clobbered () [[gnu::preserve_none]];
+extern void callee_preserved () [[gnu::no_caller_saved_registers]];
+extern void callee_sysv () [[gnu::sysv_abi]];
+extern void callee_ms () [[gnu::ms_abi]];
+
+#define TEST(PREFIX, ATTR) \
+ void PREFIX##_clobbered () [[ATTR]] { callee_clobbered (); } \
+ void PREFIX##_preserved () [[ATTR]] { callee_preserved (); } \
+ void PREFIX##_sysv () [[ATTR]] { callee_sysv (); } \
+ void PREFIX##_ms () [[ATTR]] { callee_ms (); }
+
+TEST (clobbered, gnu::preserve_none)
+TEST (preserved, gnu::no_caller_saved_registers)
+TEST (sysv, gnu::sysv_abi)
+TEST (ms, gnu::ms_abi)
+
+/* { dg-final { scan-assembler-not "%st" } } */
+/* { dg-final { scan-assembler "%xmm" } } */
new file mode 100644
@@ -0,0 +1,7 @@
+/* { dg-do compile { target { ! x32 } } } */
+/* { dg-options "-O2 -masm=att -mno-mmx -mno-80387 -mno-sse" } */
+
+#include "abi-mix-1.c"
+
+/* { dg-final { scan-assembler-not "%st" } } */
+/* { dg-final { scan-assembler-not "%xmm" } } */
@@ -19,7 +19,6 @@ foo (uintptr_t p)
/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */
/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)cx" } } */
/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)dx" } } */
-/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)bp" } } */
/* { dg-final { scan-assembler-times "pushl\[\\t \]*%esi" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-not "pushq\[\\t \]*%rsi" { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "pushl\[\\t \]*%edi" 1 { target ia32 } } } */
@@ -36,7 +35,6 @@ foo (uintptr_t p)
/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */
/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)cx" } } */
/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)dx" } } */
-/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)bp" } } */
/* { dg-final { scan-assembler-times "popl\[\\t \]*%esi" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-not "popq\[\\t \]*%rsi" { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "popl\[\\t \]*%edi" 1 { target ia32 } } } */
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { *-*-linux* && maybe_x32 } } } */
+/* { dg-do compile { target { *-*-linux* && { lp64 && maybe_x32 } } } } */
/* { dg-options "-O2 -mx32 -fno-pic -mtune=generic -msse2 -mno-avx -mno-mmx -mno-80387 -mno-apxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */
/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
@@ -52,15 +52,14 @@
** .cfi_startproc
** subl \$376, %esp
**...
-** movq %rax, 256\(%rsp\)
-** movq %rdx, 264\(%rsp\)
-** movq %rcx, 272\(%rsp\)
-** movq %rbx, 280\(%rsp\)
-** movq %rsi, 288\(%rsp\)
-** movq %rdi, 296\(%rsp\)
+** movq %rdi, 304\(%rsp\)
**...
** movl \$code\+4, %edi
-** movq %rbp, 304\(%rsp\)
+** movq %rax, 264\(%rsp\)
+** movq %rdx, 272\(%rsp\)
+** movq %rcx, 280\(%rsp\)
+** movq %rbx, 288\(%rsp\)
+** movq %rsi, 296\(%rsp\)
** movq %r8, 312\(%rsp\)
** movq %r9, 320\(%rsp\)
** movq %r10, 328\(%rsp\)
@@ -86,8 +85,8 @@
** movaps %xmm14, 224\(%rsp\)
** movaps %xmm15, 240\(%rsp\)
**...
-** movl code\(%rip\), %ebp
-** call \*%rbp
+** movl code\(%rip\), %eax
+** call \*%rax
** movaps \(%rsp\), %xmm0
** movaps 16\(%rsp\), %xmm1
** movaps 32\(%rsp\), %xmm2
@@ -104,13 +103,12 @@
** movaps 208\(%rsp\), %xmm13
** movaps 224\(%rsp\), %xmm14
** movaps 240\(%rsp\), %xmm15
-** movq 256\(%rsp\), %rax
-** movq 264\(%rsp\), %rdx
-** movq 272\(%rsp\), %rcx
-** movq 280\(%rsp\), %rbx
-** movq 288\(%rsp\), %rsi
-** movq 296\(%rsp\), %rdi
-** movq 304\(%rsp\), %rbp
+** movq 264\(%rsp\), %rax
+** movq 272\(%rsp\), %rdx
+** movq 280\(%rsp\), %rcx
+** movq 288\(%rsp\), %rbx
+** movq 296\(%rsp\), %rsi
+** movq 304\(%rsp\), %rdi
** movq 312\(%rsp\), %r8
** movq 320\(%rsp\), %r9
** movq 328\(%rsp\), %r10
@@ -50,14 +50,14 @@
** .cfi_startproc
** subq \$504, %rsp
**...
+** movq %rdi, 304\(%rsp\)
+**...
+** movl \$code\+8, %edi
** movq %rax, 264\(%rsp\)
** movq %rdx, 272\(%rsp\)
** movq %rcx, 280\(%rsp\)
** movq %rbx, 288\(%rsp\)
** movq %rsi, 296\(%rsp\)
-** movq %rdi, 304\(%rsp\)
-**...
-** movl \$code\+8, %edi
** movq %r8, 312\(%rsp\)
** movq %r9, 320\(%rsp\)
** movq %r10, 328\(%rsp\)
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { *-*-linux* && maybe_x32 } } } */
+/* { dg-do compile { target { *-*-linux* && { lp64 && maybe_x32 } } } } */
/* { dg-options "-O2 -mx32 -fno-pic -mtune=generic -msse2 -mno-avx -mno-mmx -mno-80387 -mapxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */
/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
@@ -52,15 +52,14 @@
** .cfi_startproc
** subl \$504, %esp
**...
-** movq %rax, 256\(%rsp\)
-** movq %rdx, 264\(%rsp\)
-** movq %rcx, 272\(%rsp\)
-** movq %rbx, 280\(%rsp\)
-** movq %rsi, 288\(%rsp\)
-** movq %rdi, 296\(%rsp\)
+** movq %rax, 264\(%rsp\)
+** movq %rdi, 304\(%rsp\)
**...
** movl \$code\+4, %edi
-** movq %rbp, 304\(%rsp\)
+** movq %rdx, 272\(%rsp\)
+** movq %rcx, 280\(%rsp\)
+** movq %rbx, 288\(%rsp\)
+** movq %rsi, 296\(%rsp\)
** movq %r8, 312\(%rsp\)
** movq %r9, 320\(%rsp\)
** movq %r10, 328\(%rsp\)
@@ -85,9 +84,8 @@
** movq %r29, 480\(%rsp\)
** movq %r30, 488\(%rsp\)
** movq %r31, 496\(%rsp\)
-**...
-** movl code\(%rip\), %ebp
** movaps %xmm0, \(%rsp\)
+** movl code\(%rip\), %eax
** movaps %xmm1, 16\(%rsp\)
** movaps %xmm2, 32\(%rsp\)
** movaps %xmm3, 48\(%rsp\)
@@ -104,7 +102,7 @@
** movaps %xmm14, 224\(%rsp\)
** movaps %xmm15, 240\(%rsp\)
**...
-** call \*%rbp
+** call \*%rax
** movaps \(%rsp\), %xmm0
** movaps 16\(%rsp\), %xmm1
** movaps 32\(%rsp\), %xmm2
@@ -121,13 +119,12 @@
** movaps 208\(%rsp\), %xmm13
** movaps 224\(%rsp\), %xmm14
** movaps 240\(%rsp\), %xmm15
-** movq 256\(%rsp\), %rax
-** movq 264\(%rsp\), %rdx
-** movq 272\(%rsp\), %rcx
-** movq 280\(%rsp\), %rbx
-** movq 288\(%rsp\), %rsi
-** movq 296\(%rsp\), %rdi
-** movq 304\(%rsp\), %rbp
+** movq 264\(%rsp\), %rax
+** movq 272\(%rsp\), %rdx
+** movq 280\(%rsp\), %rcx
+** movq 288\(%rsp\), %rbx
+** movq 296\(%rsp\), %rsi
+** movq 304\(%rsp\), %rdi
** movq 312\(%rsp\), %r8
** movq 320\(%rsp\), %r9
** movq 328\(%rsp\), %r10
@@ -26,7 +26,9 @@ foo (void *frame)
}
}
-/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */
-/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */
-/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*" 1 } } */
-/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*" 1 } } */
+/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bp" 1 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bp" 1 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*" 1 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*" 1 { target ia32 } } } */
+/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*" { target { ! ia32 } } } } */
new file mode 100644
@@ -0,0 +1,92 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -fno-pic -mgeneral-regs-only -mtune=generic -mtune-ctrl=prologue_using_move,epilogue_using_move" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+__attribute__((no_callee_saved_registers, noipa))
+void
+foo (void)
+{
+}
+
+/*
+**bar:
+**.LFB[0-9]+:
+** .cfi_startproc
+** subq \$376, %rsp
+**...
+** movq %rax, 264\(%rsp\)
+** movq %rdx, 272\(%rsp\)
+** movq %rcx, 280\(%rsp\)
+** movq %rbx, 288\(%rsp\)
+** movq %rsi, 296\(%rsp\)
+** movq %rdi, 304\(%rsp\)
+** movq %r8, 312\(%rsp\)
+** movq %r9, 320\(%rsp\)
+** movq %r10, 328\(%rsp\)
+** movq %r11, 336\(%rsp\)
+** movq %r12, 344\(%rsp\)
+** movq %r13, 352\(%rsp\)
+** movq %r14, 360\(%rsp\)
+** movq %r15, 368\(%rsp\)
+** movaps %xmm0, \(%rsp\)
+** movaps %xmm1, 16\(%rsp\)
+** movaps %xmm2, 32\(%rsp\)
+** movaps %xmm3, 48\(%rsp\)
+** movaps %xmm4, 64\(%rsp\)
+** movaps %xmm5, 80\(%rsp\)
+** movaps %xmm6, 96\(%rsp\)
+** movaps %xmm7, 112\(%rsp\)
+** movaps %xmm8, 128\(%rsp\)
+** movaps %xmm9, 144\(%rsp\)
+** movaps %xmm10, 160\(%rsp\)
+** movaps %xmm11, 176\(%rsp\)
+** movaps %xmm12, 192\(%rsp\)
+** movaps %xmm13, 208\(%rsp\)
+** movaps %xmm14, 224\(%rsp\)
+** movaps %xmm15, 240\(%rsp\)
+**...
+** call foo
+** movaps \(%rsp\), %xmm0
+** movaps 16\(%rsp\), %xmm1
+** movaps 32\(%rsp\), %xmm2
+** movaps 48\(%rsp\), %xmm3
+** movaps 64\(%rsp\), %xmm4
+** movaps 80\(%rsp\), %xmm5
+** movaps 96\(%rsp\), %xmm6
+** movaps 112\(%rsp\), %xmm7
+** movaps 128\(%rsp\), %xmm8
+** movaps 144\(%rsp\), %xmm9
+** movaps 160\(%rsp\), %xmm10
+** movaps 176\(%rsp\), %xmm11
+** movaps 192\(%rsp\), %xmm12
+** movaps 208\(%rsp\), %xmm13
+** movq 264\(%rsp\), %rax
+** movq 272\(%rsp\), %rdx
+** movq 280\(%rsp\), %rcx
+** movq 288\(%rsp\), %rbx
+** movq 296\(%rsp\), %rsi
+** movq 304\(%rsp\), %rdi
+** movq 312\(%rsp\), %r8
+** movq 320\(%rsp\), %r9
+** movq 328\(%rsp\), %r10
+** movq 336\(%rsp\), %r11
+** movq 344\(%rsp\), %r12
+** movq 352\(%rsp\), %r13
+** movq 360\(%rsp\), %r14
+** movq 368\(%rsp\), %r15
+** movaps 224\(%rsp\), %xmm14
+** movaps 240\(%rsp\), %xmm15
+** addq \$376, %rsp
+**...
+** ret
+** .cfi_endproc
+**...
+*/
+
+__attribute__((no_caller_saved_registers, target("sse2")))
+void
+bar (void)
+{
+ foo ();
+}
@@ -44,7 +44,7 @@ foo (void)
/* { dg-final { scan-assembler-not "popq\[\\t \]*%r9" { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-not "popq\[\\t \]*%r10" { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-not "popq\[\\t \]*%r11" { target { ! ia32 } } } } */
-/* { dg-final { scan-assembler-times "popq\[\\t \]*%r12" 1 { target { ! ia32 } } } } */
-/* { dg-final { scan-assembler-times "popq\[\\t \]*%r13" 1 { target { ! ia32 } } } } */
-/* { dg-final { scan-assembler-times "popq\[\\t \]*%r14" 1 { target { ! ia32 } } } } */
-/* { dg-final { scan-assembler-times "popq\[\\t \]*%r15" 1 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r12" 1 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r13" 1 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r14" 1 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r15" 1 { target { ! ia32 } } } } */
@@ -17,7 +17,6 @@ foo (fn_t bar)
/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */
/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)cx" } } */
/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)dx" } } */
-/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)bp" } } */
/* { dg-final { scan-assembler-times "pushl\[\\t \]*%esi" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-not "pushq\[\\t \]*%rsi" { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "pushl\[\\t \]*%edi" 1 { target ia32 } } } */
@@ -34,7 +33,6 @@ foo (fn_t bar)
/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */
/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)cx" } } */
/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)dx" } } */
-/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)bp" } } */
/* { dg-final { scan-assembler-times "popl\[\\t \]*%esi" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-not "popq\[\\t \]*%rsi" { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "popl\[\\t \]*%edi" 1 { target ia32 } } } */
@@ -43,7 +41,7 @@ foo (fn_t bar)
/* { dg-final { scan-assembler-not "popq\[\\t \]*%r9" { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-not "popq\[\\t \]*%r10" { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-not "popq\[\\t \]*%r11" { target { ! ia32 } } } } */
-/* { dg-final { scan-assembler-times "popq\[\\t \]*%r12" 1 { target { ! ia32 } } } } */
-/* { dg-final { scan-assembler-times "popq\[\\t \]*%r13" 1 { target { ! ia32 } } } } */
-/* { dg-final { scan-assembler-times "popq\[\\t \]*%r14" 1 { target { ! ia32 } } } } */
-/* { dg-final { scan-assembler-times "popq\[\\t \]*%r15" 1 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r12" 1 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r13" 1 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r14" 1 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "pushq\[\\t \]*%r15" 1 { target { ! ia32 } } } } */
new file mode 100644
@@ -0,0 +1,50 @@
+/* PR target/124798 */
+/* { dg-do compile { target { ! x32 } } } */
+/* { dg-options "-mabi=sysv -O2 -mtune=corei7 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer" } */
+
+extern void foo (void) __attribute__ ((no_caller_saved_registers, ms_abi));
+
+void
+qux (void)
+{
+ int a, b, c, d, e, f;
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ : "=r" (a), "=r" (b), "=r" (c), "=r" (d), "=r" (e), "=r" (f));
+#ifdef __x86_64__
+ int g, h, i, j, k, l, m, n, o, p;
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7 %8 %9"
+ : "=r" (g), "=r" (h), "=r" (i), "=r" (j), "=r" (k), "=r" (l), "=r" (m), "=r" (n), "=r" (o), "=r" (p));
+#endif
+ foo ();
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ :: "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f));
+#ifdef __x86_64__
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7 %8 %9"
+ : : "r" (g), "r" (h), "r" (i), "r" (j), "r" (k), "r" (l), "r" (m), "r" (n), "r" (o), "r" (p));
+#endif
+}
+
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%ecx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%esi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %ecx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %esi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r8d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r9d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r10d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r11d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r12d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r13d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r14d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r15d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r8d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r9d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r10d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r11d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r12d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r13d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r14d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r15d" { target { ! ia32 } } } } */
new file mode 100644
@@ -0,0 +1,46 @@
+/* PR target/124798 */
+/* { dg-do compile { target { ! x32 } } } */
+/* { dg-options "-mabi=ms -O2 -mtune=corei7 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer" } */
+
+extern void foo (void) __attribute__ ((no_caller_saved_registers, sysv_abi));
+
+void
+qux (void)
+{
+ int a, b, c, d, e, f;
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ : "=r" (a), "=r" (b), "=r" (c), "=r" (d), "=r" (e), "=r" (f));
+#ifdef __x86_64__
+ int g, h, i, j, k, l, m, n, o, p;
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7 %8 %9"
+ : "=r" (g), "=r" (h), "=r" (i), "=r" (j), "=r" (k), "=r" (l), "=r" (m), "=r" (n), "=r" (o), "=r" (p));
+#endif
+ foo ();
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ :: "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f));
+#ifdef __x86_64__
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7 %8 %9"
+ : : "r" (g), "r" (h), "r" (i), "r" (j), "r" (k), "r" (l), "r" (m), "r" (n), "r" (o), "r" (p));
+#endif
+}
+
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%ecx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %ecx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r8d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r9d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r10d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r11d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r12d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r13d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r14d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r15d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r8d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r9d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r10d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r11d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r12d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r13d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r14d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r15d" { target { ! ia32 } } } } */
new file mode 100644
@@ -0,0 +1,50 @@
+/* PR target/124798 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=corei7 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer" } */
+
+[[gnu::no_caller_saved_registers]] extern void foo (void);
+
+void
+qux (void)
+{
+ int a, b, c, d, e, f;
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ : "=r" (a), "=r" (b), "=r" (c), "=r" (d), "=r" (e), "=r" (f));
+#ifdef __x86_64__
+ int g, h, i, j, k, l, m, n, o, p;
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7 %8 %9"
+ : "=r" (g), "=r" (h), "=r" (i), "=r" (j), "=r" (k), "=r" (l), "=r" (m), "=r" (n), "=r" (o), "=r" (p));
+#endif
+ foo ();
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ :: "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f));
+#ifdef __x86_64__
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7 %8 %9"
+ : : "r" (g), "r" (h), "r" (i), "r" (j), "r" (k), "r" (l), "r" (m), "r" (n), "r" (o), "r" (p));
+#endif
+}
+
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%ecx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%esi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %ecx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %esi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r8d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r9d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r10d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r11d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r12d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r13d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r14d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r15d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r8d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r9d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r10d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r11d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r12d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r13d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r14d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r15d" { target { ! ia32 } } } } */
new file mode 100644
@@ -0,0 +1,17 @@
+/* Verify that no_caller_saved_registers calls still clobber x87 and MMX
+ registers. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att -mfpmath=387 -m80387 -mlong-double-80 -mno-sse -fomit-frame-pointer" } */
+
+typedef int v2si __attribute__ ((vector_size (8)));
+extern void foo (void) __attribute__ ((no_caller_saved_registers));
+
+long double
+bar_x87 (long double x, long double y)
+{
+ long double z = x + y;
+ foo ();
+ return z + 1.0L;
+}
+
+/* { dg-final { scan-assembler-times "fstpt\[ \t\]+" 1 } } */
new file mode 100644
@@ -0,0 +1,19 @@
+/* Verify that no_caller_saved_registers calls still clobber x87 and MMX
+ registers. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att -mmmx -mno-sse -fomit-frame-pointer" } */
+
+typedef int v2si __attribute__ ((vector_size (8)));
+extern void foo (void) __attribute__ ((no_caller_saved_registers));
+
+void
+bar_mmx (void)
+{
+ v2si x;
+ __asm__ volatile ("# %0" : "=y" (x));
+ foo ();
+ __asm__ volatile ("# %0" :: "y" (x));
+}
+
+/* { dg-final { scan-assembler-times "movq\[ \t\]+%mm\[0-7\], \[0-9\]*\\(%\[re\]?sp\\)" 1 } } */
+/* { dg-final { scan-assembler-times "movq\[ \t\]+\[0-9\]*\\(%\[re\]?sp\\), %mm\[0-7\]" 1 } } */
new file mode 100644
@@ -0,0 +1,49 @@
+/* PR target/124798 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=corei7 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer" } */
+
+[[gnu::no_caller_saved_registers]] extern int foo (void);
+
+int
+qux (void)
+{
+ int a, b, c, d, e, f;
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ : "=r" (a), "=r" (b), "=r" (c), "=r" (d), "=r" (e), "=r" (f));
+#ifdef __x86_64__
+ int g, h, i, j, k, l, m, n, o, p;
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7 %8 %9"
+ : "=r" (g), "=r" (h), "=r" (i), "=r" (j), "=r" (k), "=r" (l), "=r" (m), "=r" (n), "=r" (o), "=r" (p));
+#endif
+ int ret = foo ();
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ :: "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f));
+#ifdef __x86_64__
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7 %8 %9"
+ : : "r" (g), "r" (h), "r" (i), "r" (j), "r" (k), "r" (l), "r" (m), "r" (n), "r" (o), "r" (p));
+#endif
+
+ return ret;
+}
+
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%ecx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%esi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %ecx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %esi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r8d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r9d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r10d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r11d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r12d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r13d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r14d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r15d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r8d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r9d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r10d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r11d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r12d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r13d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r15d" { target { ! ia32 } } } } */
new file mode 100644
@@ -0,0 +1,49 @@
+/* PR target/124798 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=corei7 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer" } */
+
+[[gnu::no_caller_saved_registers]] extern long long foo (void);
+
+long long
+qux (void)
+{
+ int a, b, c, d, e, f;
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ : "=r" (a), "=r" (b), "=r" (c), "=r" (d), "=r" (e), "=r" (f));
+#ifdef __x86_64__
+ int g, h, i, j, k, l, m, n, o, p;
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7 %8 %9"
+ : "=r" (g), "=r" (h), "=r" (i), "=r" (j), "=r" (k), "=r" (l), "=r" (m), "=r" (n), "=r" (o), "=r" (p));
+#endif
+ long long ret = foo ();
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ :: "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f));
+#ifdef __x86_64__
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7 %8 %9"
+ : : "r" (g), "r" (h), "r" (i), "r" (j), "r" (k), "r" (l), "r" (m), "r" (n), "r" (o), "r" (p));
+#endif
+
+ return ret;
+}
+
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%ecx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%esi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %ecx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %esi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r8d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r9d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r10d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r11d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r12d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r13d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r14d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r15d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r8d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r9d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r10d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r11d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r12d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r13d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r15d" { target { ! ia32 } } } } */
new file mode 100644
@@ -0,0 +1,44 @@
+/* PR target/124798 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -mtune=corei7 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer" } */
+
+[[gnu::no_caller_saved_registers]] extern __int128 foo (void);
+
+__int128
+qux (void)
+{
+ int a, b, c, d, e, f;
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ : "=r" (a), "=r" (b), "=r" (c), "=r" (d), "=r" (e), "=r" (f));
+#ifdef __x86_64__
+ int g, h, i, j, k, l, m, n;
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7"
+ : "=r" (g), "=r" (h), "=r" (i), "=r" (j), "=r" (k), "=r" (l), "=r" (m), "=r" (n));
+#endif
+ __int128 ret = foo ();
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ :: "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f));
+#ifdef __x86_64__
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7"
+ : : "r" (g), "r" (h), "r" (i), "r" (j), "r" (k), "r" (l), "r" (m), "r" (n));
+#endif
+
+ return ret;
+}
+
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%ecx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%esi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %ecx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %esi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r8d, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r9d, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r10d, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r11d, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r8d" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r9d" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r10d" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r11d" } } */
new file mode 100644
@@ -0,0 +1,34 @@
+/* PR target/124798 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=corei7 -msse2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer" } */
+
+[[gnu::no_caller_saved_registers]] extern float foo (void);
+
+float
+qux (void)
+{
+ float a, b, c, d, e, f;
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ : "=v" (a), "=v" (b), "=v" (c), "=v" (d), "=v" (e), "=v" (f));
+#ifdef __x86_64__
+ float g, h, i, j, k, l, m, n, o, p;
+ asm volatile ("# %0 %1"
+ : "=v" (g), "=v" (h));
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7"
+ : "=v" (i), "=v" (j), "=v" (k), "=v" (l), "=v" (m), "=v" (n), "=v" (o), "=v" (p));
+#endif
+ float ret = foo ();
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ :: "v" (a), "v" (b), "v" (c), "v" (d), "v" (e), "v" (f));
+#ifdef __x86_64__
+ asm volatile ("# %0 %1"
+ :: "v" (g), "v" (h));
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7"
+ : : "v" (i), "v" (j), "v" (k), "v" (l), "v" (m), "v" (n), "v" (o), "v" (p));
+#endif
+
+ return ret;
+}
+
+/* { dg-final { scan-assembler-not "movss\[ \\t\]+%xmm\[0-9\]+, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %xmm\[0-9\]+" } } */
new file mode 100644
@@ -0,0 +1,34 @@
+/* PR target/124798 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=corei7 -msse2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer" } */
+
+[[gnu::no_caller_saved_registers]] extern _Complex double foo (void);
+
+_Complex double
+qux (void)
+{
+ double a, b, c, d, e, f;
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ : "=v" (a), "=v" (b), "=v" (c), "=v" (d), "=v" (e), "=v" (f));
+#ifdef __x86_64__
+ double g, h, i, j, k, l, m, n, o, p;
+ asm volatile ("# %0 %1"
+ : "=v" (g), "=v" (h));
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7"
+ : "=v" (i), "=v" (j), "=v" (k), "=v" (l), "=v" (m), "=v" (n), "=v" (o), "=v" (p));
+#endif
+ _Complex double ret = foo ();
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ :: "v" (a), "v" (b), "v" (c), "v" (d), "v" (e), "v" (f));
+#ifdef __x86_64__
+ asm volatile ("# %0 %1"
+ :: "v" (g), "v" (h));
+ asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7"
+ : : "v" (i), "v" (j), "v" (k), "v" (l), "v" (m), "v" (n), "v" (o), "v" (p));
+#endif
+
+ return ret;
+}
+
+/* { dg-final { scan-assembler-not "movss\[ \\t\]+%xmm\[0-9\]+, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %xmm\[0-9\]+" } } */
new file mode 100644
@@ -0,0 +1,49 @@
+/* PR target/124798 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=corei7 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer" } */
+
+typedef struct
+{
+ double d[16];
+} record;
+
+[[gnu::no_caller_saved_registers]] extern record foo (void);
+
+record
+qux (void)
+{
+ int a, b, c, d, e, f;
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ : "=r" (a), "=r" (b), "=r" (c), "=r" (d), "=r" (e), "=r" (f));
+#ifdef __x86_64__
+ int g, h, i, j;
+ asm volatile ("# %0 %1 %2 %3"
+ : "=r" (g), "=r" (h), "=r" (i), "=r" (j));
+#endif
+ record ret = foo ();
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ :: "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f));
+#ifdef __x86_64__
+ asm volatile ("# %0 %1 %2 %3"
+ :: "r" (g), "r" (h), "r" (i), "r" (j));
+#endif
+
+ return ret;
+}
+
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%ecx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%esi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %ecx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %esi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r8d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r9d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r10d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r11d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r8d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r9d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r10d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r11d" { target { ! ia32 } } } } */
new file mode 100644
@@ -0,0 +1,51 @@
+/* PR target/124798 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=corei7 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer" } */
+
+typedef struct
+{
+ long long i;
+ double d;
+} record;
+
+extern record foo (void)
+ __attribute__ ((no_caller_saved_registers, sysv_abi));
+
+record
+qux (void)
+{
+ int a, b, c, d, e, f;
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ : "=r" (a), "=r" (b), "=r" (c), "=r" (d), "=r" (e), "=r" (f));
+#ifdef __x86_64__
+ int g, h, i, j;
+ asm volatile ("# %0 %1 %2 %3"
+ : "=r" (g), "=r" (h), "=r" (i), "=r" (j));
+#endif
+ record ret = foo ();
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ :: "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f));
+#ifdef __x86_64__
+ asm volatile ("# %0 %1 %2 %3"
+ :: "r" (g), "r" (h), "r" (i), "r" (j));
+#endif
+
+ return ret;
+}
+
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%ecx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%esi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %ecx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %esi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r8d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r9d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r10d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r11d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r8d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r9d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r10d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r11d" { target { ! ia32 } } } } */
new file mode 100644
@@ -0,0 +1,51 @@
+/* PR target/124798 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=corei7 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer" } */
+
+typedef struct
+{
+ double d;
+ long long i;
+} record;
+
+extern record foo (void)
+ __attribute__ ((no_caller_saved_registers, sysv_abi));
+
+record
+qux (void)
+{
+ int a, b, c, d, e, f;
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ : "=r" (a), "=r" (b), "=r" (c), "=r" (d), "=r" (e), "=r" (f));
+#ifdef __x86_64__
+ int g, h, i, j;
+ asm volatile ("# %0 %1 %2 %3"
+ : "=r" (g), "=r" (h), "=r" (i), "=r" (j));
+#endif
+ record ret = foo ();
+ asm volatile ("# %0 %1 %2 %3 %4 %5"
+ :: "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f));
+#ifdef __x86_64__
+ asm volatile ("# %0 %1 %2 %3"
+ :: "r" (g), "r" (h), "r" (i), "r" (j));
+#endif
+
+ return ret;
+}
+
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%ecx, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%esi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%edi, \[0-9\]*\\(%\[re\]?sp\\)" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %ecx" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %esi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %edi" } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r8d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r9d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r10d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+%r11d, \[0-9\]*\\(%\[re\]?sp\\)" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r8d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r9d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r10d" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "mov(l|q)\[ \\t\]+\[0-9\]*\\(%\[re\]?sp\\), %r11d" { target { ! ia32 } } } } */
@@ -11,14 +11,12 @@
** .cfi_startproc
** subl \$248, %esp
**...
-** movq %rax, \(%rsp\)
-** movq %rdx, 8\(%rsp\)
-** movq %rcx, 16\(%rsp\)
-** movq %rbx, 24\(%rsp\)
-** movq %rsi, 32\(%rsp\)
-** movq %rdi, 40\(%rsp\)
-**...
-** movq %rbp, 48\(%rsp\)
+** movq %rax, 8\(%rsp\)
+** movq %rdx, 16\(%rsp\)
+** movq %rcx, 24\(%rsp\)
+** movq %rbx, 32\(%rsp\)
+** movq %rsi, 40\(%rsp\)
+** movq %rdi, 48\(%rsp\)
** movq %r8, 56\(%rsp\)
** movq %r9, 64\(%rsp\)
** movq %r10, 72\(%rsp\)
@@ -44,15 +42,14 @@
** movq %r30, 232\(%rsp\)
** movq %r31, 240\(%rsp\)
**...
-** movl code\(%rip\), %ebp
-** call \*%rbp
-** movq \(%rsp\), %rax
-** movq 8\(%rsp\), %rdx
-** movq 16\(%rsp\), %rcx
-** movq 24\(%rsp\), %rbx
-** movq 32\(%rsp\), %rsi
-** movq 40\(%rsp\), %rdi
-** movq 48\(%rsp\), %rbp
+** movl code\(%rip\), %eax
+** call \*%rax
+** movq 8\(%rsp\), %rax
+** movq 16\(%rsp\), %rdx
+** movq 24\(%rsp\), %rcx
+** movq 32\(%rsp\), %rbx
+** movq 40\(%rsp\), %rsi
+** movq 48\(%rsp\), %rdi
** movq 56\(%rsp\), %r8
** movq 64\(%rsp\), %r9
** movq 72\(%rsp\), %r10
@@ -61,8 +58,8 @@
** movq 96\(%rsp\), %r13
** movq 104\(%rsp\), %r14
** movq 112\(%rsp\), %r15
-** movq 120\(%rsp\), %r16
** movq 128\(%rsp\), %r17
+** movq 120\(%rsp\), %r16
** movq 136\(%rsp\), %r18
** movq 144\(%rsp\), %r19
** movq 152\(%rsp\), %r20
new file mode 100644
@@ -0,0 +1,130 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O1 -fPIC -mtls-dialect=gnu -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**ms_tls_access:
+**.LFB[0-9]+:
+** .cfi_startproc
+** pushq %rdi
+** .cfi_def_cfa_offset 16
+** .cfi_offset 5, -16
+** pushq %rsi
+** .cfi_def_cfa_offset 24
+** .cfi_offset 4, -24
+** pushq %rbx
+** .cfi_def_cfa_offset 32
+** .cfi_offset 3, -32
+** subq \$160, %rsp
+** .cfi_def_cfa_offset 192
+** movaps %xmm6, \(%rsp\)
+** movaps %xmm7, 16\(%rsp\)
+** movaps %xmm8, 32\(%rsp\)
+** movaps %xmm9, 48\(%rsp\)
+** movaps %xmm10, 64\(%rsp\)
+** movaps %xmm11, 80\(%rsp\)
+** movaps %xmm12, 96\(%rsp\)
+** movaps %xmm13, 112\(%rsp\)
+** movaps %xmm14, 128\(%rsp\)
+** movaps %xmm15, 144\(%rsp\)
+** .cfi_offset 23, -192
+** .cfi_offset 24, -176
+** .cfi_offset 25, -160
+** .cfi_offset 26, -144
+** .cfi_offset 27, -128
+** .cfi_offset 28, -112
+** .cfi_offset 29, -96
+** .cfi_offset 30, -80
+** .cfi_offset 31, -64
+** .cfi_offset 32, -48
+** movl %ecx, %ebx
+** leaq tls_instance@tlsld\(%rip\), %rdi
+** call __tls_get_addr@PLT
+** addl %ebx, tls_instance@dtpoff\(%rax\)
+** movaps \(%rsp\), %xmm6
+** movaps 16\(%rsp\), %xmm7
+** movaps 32\(%rsp\), %xmm8
+** movaps 48\(%rsp\), %xmm9
+** movaps 64\(%rsp\), %xmm10
+** movaps 80\(%rsp\), %xmm11
+** movaps 96\(%rsp\), %xmm12
+** movaps 112\(%rsp\), %xmm13
+** movaps 128\(%rsp\), %xmm14
+** movaps 144\(%rsp\), %xmm15
+** addq \$160, %rsp
+** .cfi_restore 32
+** .cfi_restore 31
+** .cfi_restore 30
+** .cfi_restore 29
+** .cfi_restore 28
+** .cfi_restore 27
+** .cfi_restore 26
+** .cfi_restore 25
+** .cfi_restore 24
+** .cfi_restore 23
+** .cfi_def_cfa_offset 32
+** popq %rbx
+** .cfi_restore 3
+** .cfi_def_cfa_offset 24
+** popq %rsi
+** .cfi_restore 4
+** .cfi_def_cfa_offset 16
+** popq %rdi
+** .cfi_restore 5
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+static volatile int magic_number = 0x12345678;
+
+static __thread int tls_instance = 0;
+
+__attribute__ ((ms_abi))
+void
+ms_tls_access (int i)
+{
+ tls_instance += i;
+}
+
+__attribute__ ((sysv_abi))
+int
+sysv_foo (int i)
+{
+ double A = magic_number;
+ double B = magic_number;
+ int a = magic_number;
+ int b = magic_number;
+ int c = magic_number;
+ int d = magic_number;
+ int e = magic_number;
+ int f = magic_number;
+ int g = magic_number;
+ int h = magic_number;
+
+ ms_tls_access (i);
+
+ return (a ^ b) ^ (c ^ d) ^ (e ^ f) ^ (g ^ h) + (int)(A - B);
+}
+
+__attribute__ ((ms_abi))
+int
+ms_foo (int i)
+{
+ double A = magic_number;
+ double B = magic_number;
+ int a = magic_number;
+ int b = magic_number;
+ int c = magic_number;
+ int d = magic_number;
+ int e = magic_number;
+ int f = magic_number;
+ int g = magic_number;
+ int h = magic_number;
+
+ ms_tls_access (i);
+
+ return a ^ b ^ c ^ d ^ e ^ f ^ g ^ h + (int)(A - B);
+}
new file mode 100644
@@ -0,0 +1,81 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O1 -fPIC -mabi=ms -mtls-dialect=gnu -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**ms_tls_access:
+**.LFB[0-9]+:
+** .cfi_startproc
+** pushq %rdi
+** .cfi_def_cfa_offset 16
+** .cfi_offset 5, -16
+** pushq %rsi
+** .cfi_def_cfa_offset 24
+** .cfi_offset 4, -24
+** pushq %rbx
+** .cfi_def_cfa_offset 32
+** .cfi_offset 3, -32
+** subq \$160, %rsp
+** .cfi_def_cfa_offset 192
+** movaps %xmm6, \(%rsp\)
+** movaps %xmm7, 16\(%rsp\)
+** movaps %xmm8, 32\(%rsp\)
+** movaps %xmm9, 48\(%rsp\)
+** movaps %xmm10, 64\(%rsp\)
+** movaps %xmm11, 80\(%rsp\)
+** movaps %xmm12, 96\(%rsp\)
+** movaps %xmm13, 112\(%rsp\)
+** movaps %xmm14, 128\(%rsp\)
+** movaps %xmm15, 144\(%rsp\)
+** .cfi_offset 23, -192
+** .cfi_offset 24, -176
+** .cfi_offset 25, -160
+** .cfi_offset 26, -144
+** .cfi_offset 27, -128
+** .cfi_offset 28, -112
+** .cfi_offset 29, -96
+** .cfi_offset 30, -80
+** .cfi_offset 31, -64
+** .cfi_offset 32, -48
+** movl %ecx, %ebx
+** leaq tls_instance@tlsld\(%rip\), %rdi
+** call __tls_get_addr@PLT
+** addl %ebx, tls_instance@dtpoff\(%rax\)
+** movaps \(%rsp\), %xmm6
+** movaps 16\(%rsp\), %xmm7
+** movaps 32\(%rsp\), %xmm8
+** movaps 48\(%rsp\), %xmm9
+** movaps 64\(%rsp\), %xmm10
+** movaps 80\(%rsp\), %xmm11
+** movaps 96\(%rsp\), %xmm12
+** movaps 112\(%rsp\), %xmm13
+** movaps 128\(%rsp\), %xmm14
+** movaps 144\(%rsp\), %xmm15
+** addq \$160, %rsp
+** .cfi_restore 32
+** .cfi_restore 31
+** .cfi_restore 30
+** .cfi_restore 29
+** .cfi_restore 28
+** .cfi_restore 27
+** .cfi_restore 26
+** .cfi_restore 25
+** .cfi_restore 24
+** .cfi_restore 23
+** .cfi_def_cfa_offset 32
+** popq %rbx
+** .cfi_restore 3
+** .cfi_def_cfa_offset 24
+** popq %rsi
+** .cfi_restore 4
+** .cfi_def_cfa_offset 16
+** popq %rdi
+** .cfi_restore 5
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+#include "pr125436-1a.c"
new file mode 100644
@@ -0,0 +1,132 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O1 -fPIC -mtls-dialect=gnu -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**ms_tls_access:
+**.LFB[0-9]+:
+** .cfi_startproc
+** pushq %rdi
+** .cfi_def_cfa_offset 16
+** .cfi_offset 5, -16
+** pushq %rsi
+** .cfi_def_cfa_offset 24
+** .cfi_offset 4, -24
+** pushq %rbx
+** .cfi_def_cfa_offset 32
+** .cfi_offset 3, -32
+** subq \$160, %rsp
+** .cfi_def_cfa_offset 192
+** movaps %xmm6, \(%rsp\)
+** movaps %xmm7, 16\(%rsp\)
+** movaps %xmm8, 32\(%rsp\)
+** movaps %xmm9, 48\(%rsp\)
+** movaps %xmm10, 64\(%rsp\)
+** movaps %xmm11, 80\(%rsp\)
+** movaps %xmm12, 96\(%rsp\)
+** movaps %xmm13, 112\(%rsp\)
+** movaps %xmm14, 128\(%rsp\)
+** movaps %xmm15, 144\(%rsp\)
+** .cfi_offset 23, -192
+** .cfi_offset 24, -176
+** .cfi_offset 25, -160
+** .cfi_offset 26, -144
+** .cfi_offset 27, -128
+** .cfi_offset 28, -112
+** .cfi_offset 29, -96
+** .cfi_offset 30, -80
+** .cfi_offset 31, -64
+** .cfi_offset 32, -48
+** movl %ecx, %ebx
+** data16 leaq tls_instance@tlsgd\(%rip\), %rdi
+** .value 0x6666
+** rex64
+** call __tls_get_addr@PLT
+** addl %ebx, \(%rax\)
+** movaps \(%rsp\), %xmm6
+** movaps 16\(%rsp\), %xmm7
+** movaps 32\(%rsp\), %xmm8
+** movaps 48\(%rsp\), %xmm9
+** movaps 64\(%rsp\), %xmm10
+** movaps 80\(%rsp\), %xmm11
+** movaps 96\(%rsp\), %xmm12
+** movaps 112\(%rsp\), %xmm13
+** movaps 128\(%rsp\), %xmm14
+** movaps 144\(%rsp\), %xmm15
+** addq \$160, %rsp
+** .cfi_restore 32
+** .cfi_restore 31
+** .cfi_restore 30
+** .cfi_restore 29
+** .cfi_restore 28
+** .cfi_restore 27
+** .cfi_restore 26
+** .cfi_restore 25
+** .cfi_restore 24
+** .cfi_restore 23
+** .cfi_def_cfa_offset 32
+** popq %rbx
+** .cfi_restore 3
+** .cfi_def_cfa_offset 24
+** popq %rsi
+** .cfi_restore 4
+** .cfi_def_cfa_offset 16
+** popq %rdi
+** .cfi_restore 5
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+static volatile int magic_number = 0x12345678;
+
+__thread int tls_instance = 0;
+
+__attribute__ ((ms_abi))
+void
+ms_tls_access (int i)
+{
+ tls_instance += i;
+}
+
+__attribute__ ((sysv_abi))
+int
+sysv_foo (int i)
+{
+ double A = magic_number;
+ double B = magic_number;
+ int a = magic_number;
+ int b = magic_number;
+ int c = magic_number;
+ int d = magic_number;
+ int e = magic_number;
+ int f = magic_number;
+ int g = magic_number;
+ int h = magic_number;
+
+ ms_tls_access (i);
+
+ return (a ^ b) ^ (c ^ d) ^ (e ^ f) ^ (g ^ h) + (int)(A - B);
+}
+
+__attribute__ ((ms_abi))
+int
+ms_foo (int i)
+{
+ double A = magic_number;
+ double B = magic_number;
+ int a = magic_number;
+ int b = magic_number;
+ int c = magic_number;
+ int d = magic_number;
+ int e = magic_number;
+ int f = magic_number;
+ int g = magic_number;
+ int h = magic_number;
+
+ ms_tls_access (i);
+
+ return a ^ b ^ c ^ d ^ e ^ f ^ g ^ h + (int)(A - B);
+}
new file mode 100644
@@ -0,0 +1,83 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O1 -fPIC -mabi=ms -mtls-dialect=gnu -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**ms_tls_access:
+**.LFB[0-9]+:
+** .cfi_startproc
+** pushq %rdi
+** .cfi_def_cfa_offset 16
+** .cfi_offset 5, -16
+** pushq %rsi
+** .cfi_def_cfa_offset 24
+** .cfi_offset 4, -24
+** pushq %rbx
+** .cfi_def_cfa_offset 32
+** .cfi_offset 3, -32
+** subq \$160, %rsp
+** .cfi_def_cfa_offset 192
+** movaps %xmm6, \(%rsp\)
+** movaps %xmm7, 16\(%rsp\)
+** movaps %xmm8, 32\(%rsp\)
+** movaps %xmm9, 48\(%rsp\)
+** movaps %xmm10, 64\(%rsp\)
+** movaps %xmm11, 80\(%rsp\)
+** movaps %xmm12, 96\(%rsp\)
+** movaps %xmm13, 112\(%rsp\)
+** movaps %xmm14, 128\(%rsp\)
+** movaps %xmm15, 144\(%rsp\)
+** .cfi_offset 23, -192
+** .cfi_offset 24, -176
+** .cfi_offset 25, -160
+** .cfi_offset 26, -144
+** .cfi_offset 27, -128
+** .cfi_offset 28, -112
+** .cfi_offset 29, -96
+** .cfi_offset 30, -80
+** .cfi_offset 31, -64
+** .cfi_offset 32, -48
+** movl %ecx, %ebx
+** data16 leaq tls_instance@tlsgd\(%rip\), %rdi
+** .value 0x6666
+** rex64
+** call __tls_get_addr@PLT
+** addl %ebx, \(%rax\)
+** movaps \(%rsp\), %xmm6
+** movaps 16\(%rsp\), %xmm7
+** movaps 32\(%rsp\), %xmm8
+** movaps 48\(%rsp\), %xmm9
+** movaps 64\(%rsp\), %xmm10
+** movaps 80\(%rsp\), %xmm11
+** movaps 96\(%rsp\), %xmm12
+** movaps 112\(%rsp\), %xmm13
+** movaps 128\(%rsp\), %xmm14
+** movaps 144\(%rsp\), %xmm15
+** addq \$160, %rsp
+** .cfi_restore 32
+** .cfi_restore 31
+** .cfi_restore 30
+** .cfi_restore 29
+** .cfi_restore 28
+** .cfi_restore 27
+** .cfi_restore 26
+** .cfi_restore 25
+** .cfi_restore 24
+** .cfi_restore 23
+** .cfi_def_cfa_offset 32
+** popq %rbx
+** .cfi_restore 3
+** .cfi_def_cfa_offset 24
+** popq %rsi
+** .cfi_restore 4
+** .cfi_def_cfa_offset 16
+** popq %rdi
+** .cfi_restore 5
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+#include "pr125436-2a.c"
new file mode 100644
@@ -0,0 +1,88 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O1 -fPIC -mtls-dialect=gnu -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**ms_tls_access:
+**.LFB[0-9]+:
+** .cfi_startproc
+** pushq %rdi
+** .cfi_def_cfa_offset 16
+** .cfi_offset 5, -16
+** pushq %rsi
+** .cfi_def_cfa_offset 24
+** .cfi_offset 4, -24
+** pushq %rbx
+** .cfi_def_cfa_offset 32
+** .cfi_offset 3, -32
+** subq \$160, %rsp
+** .cfi_def_cfa_offset 192
+** movaps %xmm6, \(%rsp\)
+** movaps %xmm7, 16\(%rsp\)
+** movaps %xmm8, 32\(%rsp\)
+** movaps %xmm9, 48\(%rsp\)
+** movaps %xmm10, 64\(%rsp\)
+** movaps %xmm11, 80\(%rsp\)
+** movaps %xmm12, 96\(%rsp\)
+** movaps %xmm13, 112\(%rsp\)
+** movaps %xmm14, 128\(%rsp\)
+** movaps %xmm15, 144\(%rsp\)
+** .cfi_offset 23, -192
+** .cfi_offset 24, -176
+** .cfi_offset 25, -160
+** .cfi_offset 26, -144
+** .cfi_offset 27, -128
+** .cfi_offset 28, -112
+** .cfi_offset 29, -96
+** .cfi_offset 30, -80
+** .cfi_offset 31, -64
+** .cfi_offset 32, -48
+** movl %ecx, %ebx
+** leaq tls_instance@tlsld\(%rip\), %rdi
+** call __tls_get_addr@PLT
+** addl %ebx, tls_instance@dtpoff\(%rax\)
+** movaps \(%rsp\), %xmm6
+** movaps 16\(%rsp\), %xmm7
+** movaps 32\(%rsp\), %xmm8
+** movaps 48\(%rsp\), %xmm9
+** movaps 64\(%rsp\), %xmm10
+** movaps 80\(%rsp\), %xmm11
+** movaps 96\(%rsp\), %xmm12
+** movaps 112\(%rsp\), %xmm13
+** movaps 128\(%rsp\), %xmm14
+** movaps 144\(%rsp\), %xmm15
+** addq \$160, %rsp
+** .cfi_restore 32
+** .cfi_restore 31
+** .cfi_restore 30
+** .cfi_restore 29
+** .cfi_restore 28
+** .cfi_restore 27
+** .cfi_restore 26
+** .cfi_restore 25
+** .cfi_restore 24
+** .cfi_restore 23
+** .cfi_def_cfa_offset 32
+** popq %rbx
+** .cfi_restore 3
+** .cfi_def_cfa_offset 24
+** popq %rsi
+** .cfi_restore 4
+** .cfi_def_cfa_offset 16
+** popq %rdi
+** .cfi_restore 5
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+static __thread int tls_instance = 0;
+
+__attribute__ ((ms_abi))
+void
+ms_tls_access (int i)
+{
+ tls_instance += i;
+}
new file mode 100644
@@ -0,0 +1,88 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O1 -fPIC -mabi=ms -mtls-dialect=gnu -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**ms_tls_access:
+**.LFB[0-9]+:
+** .cfi_startproc
+** pushq %rdi
+** .cfi_def_cfa_offset 16
+** .cfi_offset 5, -16
+** pushq %rsi
+** .cfi_def_cfa_offset 24
+** .cfi_offset 4, -24
+** pushq %rbx
+** .cfi_def_cfa_offset 32
+** .cfi_offset 3, -32
+** subq \$160, %rsp
+** .cfi_def_cfa_offset 192
+** movaps %xmm6, \(%rsp\)
+** movaps %xmm7, 16\(%rsp\)
+** movaps %xmm8, 32\(%rsp\)
+** movaps %xmm9, 48\(%rsp\)
+** movaps %xmm10, 64\(%rsp\)
+** movaps %xmm11, 80\(%rsp\)
+** movaps %xmm12, 96\(%rsp\)
+** movaps %xmm13, 112\(%rsp\)
+** movaps %xmm14, 128\(%rsp\)
+** movaps %xmm15, 144\(%rsp\)
+** .cfi_offset 23, -192
+** .cfi_offset 24, -176
+** .cfi_offset 25, -160
+** .cfi_offset 26, -144
+** .cfi_offset 27, -128
+** .cfi_offset 28, -112
+** .cfi_offset 29, -96
+** .cfi_offset 30, -80
+** .cfi_offset 31, -64
+** .cfi_offset 32, -48
+** movl %ecx, %ebx
+** leaq tls_instance@tlsld\(%rip\), %rdi
+** call __tls_get_addr@PLT
+** addl %ebx, tls_instance@dtpoff\(%rax\)
+** movaps \(%rsp\), %xmm6
+** movaps 16\(%rsp\), %xmm7
+** movaps 32\(%rsp\), %xmm8
+** movaps 48\(%rsp\), %xmm9
+** movaps 64\(%rsp\), %xmm10
+** movaps 80\(%rsp\), %xmm11
+** movaps 96\(%rsp\), %xmm12
+** movaps 112\(%rsp\), %xmm13
+** movaps 128\(%rsp\), %xmm14
+** movaps 144\(%rsp\), %xmm15
+** addq \$160, %rsp
+** .cfi_restore 32
+** .cfi_restore 31
+** .cfi_restore 30
+** .cfi_restore 29
+** .cfi_restore 28
+** .cfi_restore 27
+** .cfi_restore 26
+** .cfi_restore 25
+** .cfi_restore 24
+** .cfi_restore 23
+** .cfi_def_cfa_offset 32
+** popq %rbx
+** .cfi_restore 3
+** .cfi_def_cfa_offset 24
+** popq %rsi
+** .cfi_restore 4
+** .cfi_def_cfa_offset 16
+** popq %rdi
+** .cfi_restore 5
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+static __thread int tls_instance = 0;
+
+__attribute__ ((ms_abi))
+void
+ms_tls_access (int i)
+{
+ tls_instance += i;
+}
@@ -17,7 +17,6 @@ foo (fn_t bar)
/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */
/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)cx" } } */
/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)dx" } } */
-/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)bp" } } */
/* { dg-final { scan-assembler-times "pushl\[\\t \]*%esi" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-not "pushq\[\\t \]*%rsi" { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "pushl\[\\t \]*%edi" 1 { target ia32 } } } */
@@ -34,7 +33,6 @@ foo (fn_t bar)
/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */
/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)cx" } } */
/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)dx" } } */
-/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)bp" } } */
/* { dg-final { scan-assembler-times "popl\[\\t \]*%esi" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-not "popq\[\\t \]*%rsi" { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "popl\[\\t \]*%edi" 1 { target ia32 } } } */
@@ -19,7 +19,6 @@ foo (uintptr_t p)
/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */
/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)cx" } } */
/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)dx" } } */
-/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*%(?:e|r)bp" } } */
/* { dg-final { scan-assembler-times "pushl\[\\t \]*%esi" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-not "pushq\[\\t \]*%rsi" { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "pushl\[\\t \]*%edi" 1 { target ia32 } } } */
@@ -36,7 +35,6 @@ foo (uintptr_t p)
/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bx" 1 } } */
/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)cx" } } */
/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)dx" } } */
-/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*%(?:e|r)bp" } } */
/* { dg-final { scan-assembler-times "popl\[\\t \]*%esi" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-not "popq\[\\t \]*%rsi" { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "popl\[\\t \]*%edi" 1 { target ia32 } } } */
@@ -26,7 +26,9 @@ foo (void *frame)
}
}
-/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */
-/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bp" 1 } } */
-/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*" 1 } } */
-/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*" 1 } } */
+/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*%(?:e|r)bp" 1 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*%(?:e|r)bp" 1 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "push(?:l|q)\[\\t \]*" 1 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "pop(?:l|q)\[\\t \]*" 1 { target ia32 } } } */
+/* { dg-final { scan-assembler-not "push(?:l|q)\[\\t \]*" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "pop(?:l|q)\[\\t \]*" { target { ! ia32 } } } } */