On Thu, Jul 9, 2026 at 2:42 PM Hongtao Liu <[email protected]> wrote:
>
> On Thu, Jul 9, 2026 at 9:41 AM H.J. Lu <[email protected]> wrote:
> >
> > In 64-bit mode, preserve_none attribute uses a different calling
> > convention. Ignore MS ABI with preserve_none attribute to always
> > use the preserve_none calling convention with preserve_none
> > attribute.
> >
> > gcc/
> >
>
> >
> > It has 8 registers. Tests show that
> > x86_64_preserve_none_int_parameter_registers
> > is used for functions with __attribute__ ((preserve_none, ms_abi)).
> I mean for sse registers, init_cumulative_args sets the integer count
> via the new predicate but leaves the SSE count keyed on the raw ABI
> (i386.cc:1940):
Fixed with tests in the v3 patch.
> 927 /* Set up the number of registers to use for passing arguments. */
> 928 cum->nregs = ix86_regparm;
> 929 if (TARGET_64BIT)
> 930 {
> 931 cum->nregs = (x86_64_cumulative_ms_abi_p (cum)
> 932 ? X86_64_MS_REGPARM_MAX
> 933 : X86_64_REGPARM_MAX);
> 934 }
> 935 if (TARGET_SSE)
> 936 {
> 937 cum->sse_nregs = SSE_REGPARM_MAX;
> 938 if (TARGET_64BIT)
> 939 {
> 940 cum->sse_nregs = (cum->call_abi == SYSV_ABI
> 941 ? X86_64_SSE_REGPARM_MAX
> 942 : X86_64_MS_SSE_REGPARM_MAX);
> 943 }
> 944 }
>
>
> if -mabi=ms is in the command line, with plain preserve_none in the
> attribute, only 4 sse registers is used for parameter passing
> But with __attribute__ ((preserve_none, ms_abi)), 8 sse registers are
> used for parameter passing.
>
> .i.e
> void bar(double,double,double,double,double,double)
> __attribute__((preserve_none));
>
> void
> entry (long a1, long a2, long a3, long a4, long a5, long a6)
> {
> bar (a1, a2, a3, a4, a5, a6);
> }
>
Fixed with tests in the v3 patch.
Here is the v3 patch.
Thanks.
--
H.J.
---
In 64-bit mode, preserve_none attribute uses a different calling
convention. Ignore MS ABI with preserve_none attribute to always
use the preserve_none calling convention with preserve_none
attribute.
gcc/
PR target/125297
* config/i386/i386.cc (ix86_function_arg_regno_p): Use
x86_64_preserve_none_int_parameter_registers for
TYPE_PRESERVE_NONE.
(ix86_function_type_abi): In 64-bit mode, ignore ms_abi
attribute with preserve_none attribute.
(x86_64_cumulative_ms_abi_p): New function.
(init_cumulative_args): Call x86_64_cumulative_ms_abi_p to
decide if MS_ABI is used.
(ix86_function_arg_advance): Likewise.
(ix86_function_arg): Likewise.
(ix86_pass_by_reference): Likewise.
(ix86_setup_incoming_varargs): Likewise.
gcc/testsuite/
PR target/125297
* gcc.target/i386/preserve-none-31a.c: New test.
* gcc.target/i386/preserve-none-31b.c: Likewise.
* gcc.target/i386/preserve-none-32a.c: Likewise.
* gcc.target/i386/preserve-none-32b.c: Likewise.
* gcc.target/i386/preserve-none-33a.c: Likewise.
* gcc.target/i386/preserve-none-33b.c: Likewise.
* gcc.target/i386/preserve-none-34a.c: Likewise.
* gcc.target/i386/preserve-none-34b.c: Likewise.
* gcc.target/i386/preserve-none-35a.c: Likewise.
* gcc.target/i386/preserve-none-35b.c: Likewise.
* gcc.target/i386/preserve-none-35c.c: Likewise.
* gcc.target/i386/preserve-none-35d.c: Likewise.
* gcc.target/i386/preserve-none-35e.c: Likewise.
* gcc.target/i386/preserve-none-35f.c: Likewise.
* gcc.target/i386/preserve-none-35g.c: Likewise.
* gcc.target/i386/preserve-none-36a.c: Likewise.
* gcc.target/i386/preserve-none-36b.c: Likewise.
* gcc.target/i386/preserve-none-36c.c: Likewise.
* gcc.target/i386/preserve-none-36d.c: Likewise.
* gcc.target/i386/preserve-none-36e.c: Likewise.
* gcc.target/i386/preserve-none-36f.c: Likewise.
* gcc.target/i386/preserve-none-36g.c: Likewise.
* gcc.target/i386/preserve-none-37a.c: Likewise.
* gcc.target/i386/preserve-none-37b.c: Likewise.
* gcc.target/i386/preserve-none-37c.c: Likewise.
* gcc.target/i386/preserve-none-37d.c: Likewise.
* gcc.target/i386/preserve-none-37e.c: Likewise.
* gcc.target/i386/preserve-none-37f.c: Likewise.
* gcc.target/i386/preserve-none-37g.c: Likewise.
From 8f27b2bdf7facbc423666f0df4d6d4fdba560559 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <[email protected]>
Date: Wed, 13 May 2026 08:27:50 +0800
Subject: [PATCH v3] x86: Honor preserve_none ABI for x86-64 MS calls
In 64-bit mode, preserve_none attribute uses a different calling
convention. Ignore MS ABI with preserve_none attribute to always
use the preserve_none calling convention with preserve_none
attribute.
gcc/
PR target/125297
* config/i386/i386.cc (ix86_function_arg_regno_p): Use
x86_64_preserve_none_int_parameter_registers for
TYPE_PRESERVE_NONE.
(ix86_function_type_abi): In 64-bit mode, ignore ms_abi
attribute with preserve_none attribute.
(x86_64_cumulative_ms_abi_p): New function.
(init_cumulative_args): Call x86_64_cumulative_ms_abi_p to
decide if MS_ABI is used.
(ix86_function_arg_advance): Likewise.
(ix86_function_arg): Likewise.
(ix86_pass_by_reference): Likewise.
(ix86_setup_incoming_varargs): Likewise.
gcc/testsuite/
PR target/125297
* gcc.target/i386/preserve-none-31a.c: New test.
* gcc.target/i386/preserve-none-31b.c: Likewise.
* gcc.target/i386/preserve-none-32a.c: Likewise.
* gcc.target/i386/preserve-none-32b.c: Likewise.
* gcc.target/i386/preserve-none-33a.c: Likewise.
* gcc.target/i386/preserve-none-33b.c: Likewise.
* gcc.target/i386/preserve-none-34a.c: Likewise.
* gcc.target/i386/preserve-none-34b.c: Likewise.
* gcc.target/i386/preserve-none-35a.c: Likewise.
* gcc.target/i386/preserve-none-35b.c: Likewise.
* gcc.target/i386/preserve-none-35c.c: Likewise.
* gcc.target/i386/preserve-none-35d.c: Likewise.
* gcc.target/i386/preserve-none-35e.c: Likewise.
* gcc.target/i386/preserve-none-35f.c: Likewise.
* gcc.target/i386/preserve-none-35g.c: Likewise.
* gcc.target/i386/preserve-none-36a.c: Likewise.
* gcc.target/i386/preserve-none-36b.c: Likewise.
* gcc.target/i386/preserve-none-36c.c: Likewise.
* gcc.target/i386/preserve-none-36d.c: Likewise.
* gcc.target/i386/preserve-none-36e.c: Likewise.
* gcc.target/i386/preserve-none-36f.c: Likewise.
* gcc.target/i386/preserve-none-36g.c: Likewise.
* gcc.target/i386/preserve-none-37a.c: Likewise.
* gcc.target/i386/preserve-none-37b.c: Likewise.
* gcc.target/i386/preserve-none-37c.c: Likewise.
* gcc.target/i386/preserve-none-37d.c: Likewise.
* gcc.target/i386/preserve-none-37e.c: Likewise.
* gcc.target/i386/preserve-none-37f.c: Likewise.
* gcc.target/i386/preserve-none-37g.c: Likewise.
Signed-off-by: H.J. Lu <[email protected]>
---
gcc/config/i386/i386.cc | 50 +++++++----
.../gcc.target/i386/preserve-none-31a.c | 36 ++++++++
.../gcc.target/i386/preserve-none-31b.c | 25 ++++++
.../gcc.target/i386/preserve-none-32a.c | 29 +++++++
.../gcc.target/i386/preserve-none-32b.c | 18 ++++
.../gcc.target/i386/preserve-none-33a.c | 36 ++++++++
.../gcc.target/i386/preserve-none-33b.c | 25 ++++++
.../gcc.target/i386/preserve-none-34a.c | 29 +++++++
.../gcc.target/i386/preserve-none-34b.c | 18 ++++
.../gcc.target/i386/preserve-none-35a.c | 55 ++++++++++++
.../gcc.target/i386/preserve-none-35b.c | 39 +++++++++
.../gcc.target/i386/preserve-none-35c.c | 34 ++++++++
.../gcc.target/i386/preserve-none-35d.c | 80 +++++++++++++++++
.../gcc.target/i386/preserve-none-35e.c | 34 ++++++++
.../gcc.target/i386/preserve-none-35f.c | 44 ++++++++++
.../gcc.target/i386/preserve-none-35g.c | 85 +++++++++++++++++++
.../gcc.target/i386/preserve-none-36a.c | 33 +++++++
.../gcc.target/i386/preserve-none-36b.c | 22 +++++
.../gcc.target/i386/preserve-none-36c.c | 18 ++++
.../gcc.target/i386/preserve-none-36d.c | 30 +++++++
.../gcc.target/i386/preserve-none-36e.c | 18 ++++
.../gcc.target/i386/preserve-none-36f.c | 35 ++++++++
.../gcc.target/i386/preserve-none-36g.c | 30 +++++++
.../gcc.target/i386/preserve-none-37a.c | 33 +++++++
.../gcc.target/i386/preserve-none-37b.c | 17 ++++
.../gcc.target/i386/preserve-none-37c.c | 18 ++++
.../gcc.target/i386/preserve-none-37d.c | 18 ++++
.../gcc.target/i386/preserve-none-37e.c | 18 ++++
.../gcc.target/i386/preserve-none-37f.c | 27 ++++++
.../gcc.target/i386/preserve-none-37g.c | 27 ++++++
30 files changed, 963 insertions(+), 18 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-31a.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-31b.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-32a.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-32b.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-33a.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-33b.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-34a.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-34b.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-35a.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-35b.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-35c.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-35d.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-35e.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-35f.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-35g.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-36a.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-36b.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-36c.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-36d.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-36e.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-36f.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-36g.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-37a.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-37b.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-37c.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-37d.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-37e.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-37f.c
create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-37g.c
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 1b8c03fecb9..b611a70cf2a 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -1591,16 +1591,19 @@ ix86_function_arg_regno_p (int regno)
if (call_abi == SYSV_ABI && regno == AX_REG)
return true;
+ int regparm_max = X86_64_REGPARM_MAX;
if (cfun
&& cfun->machine->call_saved_registers == TYPE_PRESERVE_NONE)
parm_regs = x86_64_preserve_none_int_parameter_registers;
else if (call_abi == MS_ABI)
- parm_regs = x86_64_ms_abi_int_parameter_registers;
+ {
+ parm_regs = x86_64_ms_abi_int_parameter_registers;
+ regparm_max = X86_64_MS_REGPARM_MAX;
+ }
else
parm_regs = x86_64_int_parameter_registers;
- for (i = 0; i < (call_abi == MS_ABI
- ? X86_64_MS_REGPARM_MAX : X86_64_REGPARM_MAX); i++)
+ for (i = 0; i < regparm_max; i++)
if (regno == parm_regs[i])
return true;
return false;
@@ -1665,7 +1668,11 @@ ix86_function_type_abi (const_tree fntype)
warned = 1;
}
- abi = MS_ABI;
+ /* NB: preserve_none attribute overrides ms_abi in 64-bit mode. */
+ if (!TARGET_64BIT
+ || !lookup_attribute ("preserve_none",
+ TYPE_ATTRIBUTES (fntype)))
+ abi = MS_ABI;
}
else if (abi == MS_ABI
&& lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)))
@@ -1856,6 +1863,17 @@ ix86_init_pic_reg (void)
commit_one_edge_insertion (entry_edge);
}
+/* Return true if x86-64 CUM is MS_ABI. */
+
+static bool
+x86_64_cumulative_ms_abi_p (CUMULATIVE_ARGS *cum)
+{
+ if (!cum)
+ return ix86_abi == MS_ABI;
+
+ return !cum->preserve_none_abi && cum->call_abi == MS_ABI;
+}
+
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0. */
@@ -1910,18 +1928,18 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
cum->nregs = ix86_regparm;
if (TARGET_64BIT)
{
- cum->nregs = (cum->call_abi == SYSV_ABI
- ? X86_64_REGPARM_MAX
- : X86_64_MS_REGPARM_MAX);
+ cum->nregs = (x86_64_cumulative_ms_abi_p (cum)
+ ? X86_64_MS_REGPARM_MAX
+ : X86_64_REGPARM_MAX);
}
if (TARGET_SSE)
{
cum->sse_nregs = SSE_REGPARM_MAX;
if (TARGET_64BIT)
{
- cum->sse_nregs = (cum->call_abi == SYSV_ABI
- ? X86_64_SSE_REGPARM_MAX
- : X86_64_MS_SSE_REGPARM_MAX);
+ cum->sse_nregs = (x86_64_cumulative_ms_abi_p (cum)
+ ? X86_64_MS_SSE_REGPARM_MAX
+ : X86_64_SSE_REGPARM_MAX);
}
}
if (TARGET_MMX)
@@ -3262,9 +3280,7 @@ ix86_function_arg_advance (cumulative_args_t cum_v,
if (TARGET_64BIT)
{
- enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
-
- if (call_abi == MS_ABI)
+ if (x86_64_cumulative_ms_abi_p (cum))
nregs = function_arg_advance_ms_64 (cum, bytes, words);
else
nregs = function_arg_advance_64 (cum, mode, arg.type, words,
@@ -3593,7 +3609,7 @@ ix86_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
if (TARGET_64BIT)
{
- if (cum->call_abi == MS_ABI)
+ if (x86_64_cumulative_ms_abi_p (cum))
reg = function_arg_ms_64 (cum, mode, arg.mode, arg.named,
arg.type, bytes);
else
@@ -3622,10 +3638,8 @@ ix86_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
if (TARGET_64BIT)
{
- enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
-
/* See Windows x64 Software Convention. */
- if (call_abi == MS_ABI)
+ if (x86_64_cumulative_ms_abi_p (cum))
{
HOST_WIDE_INT msize = GET_MODE_SIZE (arg.mode);
@@ -4796,7 +4810,7 @@ ix86_setup_incoming_varargs (cumulative_args_t cum_v,
&& stdarg_p (fntype))
ix86_function_arg_advance (pack_cumulative_args (&next_cum), arg);
- if (cum->call_abi == MS_ABI)
+ if (x86_64_cumulative_ms_abi_p (cum))
setup_incoming_varargs_ms_64 (&next_cum);
else
setup_incoming_varargs_64 (&next_cum);
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-31a.c b/gcc/testsuite/gcc.target/i386/preserve-none-31a.c
new file mode 100644
index 00000000000..b24499cfb8f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-31a.c
@@ -0,0 +1,36 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic -mabi=ms" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** subq \$72, %rsp
+**...
+** movl %ecx, %r12d
+** movl %edx, %r13d
+** movl %r9d, %r15d
+** movl 120\(%rsp\), %esi
+** movl 112\(%rsp\), %edi
+** movl %r8d, %r14d
+** xorl %eax, %eax
+** movl \$-559038737, 48\(%rsp\)
+** call continuation
+** addq \$72, %rsp
+**...
+** ret
+** .cfi_endproc
+**...
+*/
+
+extern void continuation (int, int, int, int, int, int, ...)
+ __attribute__ ((preserve_none));
+
+__attribute__ ((no_callee_saved_registers))
+void
+entry (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6)
+{
+ continuation (arg1, arg2, arg3, arg4, arg5, arg6, 0xdeadbeef);
+}
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-31b.c b/gcc/testsuite/gcc.target/i386/preserve-none-31b.c
new file mode 100644
index 00000000000..9b6ad95c36f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-31b.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target { llp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic -mabi=ms" } */
+/* Keep labels and directives ('.seh_endprologue'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+** subq \$72, %rsp
+** .seh_stackalloc 72
+** .seh_endprologue
+** xorl %eax, %eax
+** movl 120\(%rsp\), %esi
+** movl 112\(%rsp\), %edi
+** movl %ecx, %r12d
+** movl %edx, %r13d
+** movl %r9d, %r15d
+** movl %r8d, %r14d
+** movl \$-559038737, 48\(%rsp\)
+** call continuation
+** nop
+** addq \$72, %rsp
+** ret
+*/
+
+#include "preserve-none-31a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-32a.c b/gcc/testsuite/gcc.target/i386/preserve-none-32a.c
new file mode 100644
index 00000000000..1928491a4f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-32a.c
@@ -0,0 +1,29 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic -mabi=ms" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movl 56\(%rsp\), %esi
+** movl 48\(%rsp\), %edi
+** movl %edx, %r12d
+** movl %r9d, %r14d
+** movl 40\(%rsp\), %r15d
+** movl %r8d, %r13d
+** jmp continuation
+** .cfi_endproc
+**...
+*/
+
+extern void continuation (double, int, int, int, int, int, int)
+ __attribute__ ((preserve_none));
+
+__attribute__ ((no_callee_saved_registers))
+void
+entry (double fp, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6)
+{
+ continuation (fp, arg1, arg2, arg3, arg4, arg5, arg6);
+}
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-32b.c b/gcc/testsuite/gcc.target/i386/preserve-none-32b.c
new file mode 100644
index 00000000000..3de4322fef7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-32b.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { llp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic -mabi=ms" } */
+/* Keep labels and directives ('.seh_endprologue'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+** .seh_endprologue
+** movl 56\(%rsp\), %esi
+** movl 48\(%rsp\), %edi
+** movl 40\(%rsp\), %r15d
+** movl %edx, %r12d
+** movl %r9d, %r14d
+** movl %r8d, %r13d
+** jmp continuation
+*/
+
+#include "preserve-none-32a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-33a.c b/gcc/testsuite/gcc.target/i386/preserve-none-33a.c
new file mode 100644
index 00000000000..086df3681ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-33a.c
@@ -0,0 +1,36 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic -mabi=sysv" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** subq \$24, %rsp
+**...
+** movl %edi, %r12d
+** movl %esi, %r13d
+** movl %edx, %r14d
+** movl \$-559038737, \(%rsp\)
+** movl %ecx, %r15d
+** movl %r9d, %esi
+** movl %r8d, %edi
+** xorl %eax, %eax
+** call continuation
+** addq \$24, %rsp
+**...
+** ret
+** .cfi_endproc
+**...
+*/
+
+extern void continuation (int, int, int, int, int, int, ...)
+ __attribute__ ((preserve_none, ms_abi));
+
+__attribute__ ((no_callee_saved_registers))
+void
+entry (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6)
+{
+ continuation (arg1, arg2, arg3, arg4, arg5, arg6, 0xdeadbeef);
+}
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-33b.c b/gcc/testsuite/gcc.target/i386/preserve-none-33b.c
new file mode 100644
index 00000000000..b82f790d645
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-33b.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target { llp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic -mabi=ms" } */
+/* Keep labels and directives ('.seh_endprologue'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+** subq \$72, %rsp
+** .seh_stackalloc 72
+** .seh_endprologue
+** xorl %eax, %eax
+** movl 120\(%rsp\), %esi
+** movl 112\(%rsp\), %edi
+** movl %ecx, %r12d
+** movl %edx, %r13d
+** movl %r9d, %r15d
+** movl %r8d, %r14d
+** movl \$-559038737, 48\(%rsp\)
+** call continuation
+** nop
+** addq \$72, %rsp
+** ret
+*/
+
+#include "preserve-none-33a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-34a.c b/gcc/testsuite/gcc.target/i386/preserve-none-34a.c
new file mode 100644
index 00000000000..dbc36e9a21b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-34a.c
@@ -0,0 +1,29 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic -mabi=sysv" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movl %edi, %r12d
+** movl %esi, %r13d
+** movl %edx, %r14d
+** movl %ecx, %r15d
+** movl %r9d, %esi
+** movl %r8d, %edi
+** jmp continuation
+** .cfi_endproc
+**...
+*/
+
+extern void continuation (double, int, int, int, int, int, int)
+ __attribute__ ((preserve_none, ms_abi));
+
+__attribute__ ((no_callee_saved_registers))
+void
+entry (double fp, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6)
+{
+ continuation (fp, arg1, arg2, arg3, arg4, arg5, arg6);
+}
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-34b.c b/gcc/testsuite/gcc.target/i386/preserve-none-34b.c
new file mode 100644
index 00000000000..75323ad7863
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-34b.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { llp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic -mabi=ms" } */
+/* Keep labels and directives ('.seh_endprologue'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+** .seh_endprologue
+** movl 56\(%rsp\), %esi
+** movl 48\(%rsp\), %edi
+** movl 40\(%rsp\), %r15d
+** movl %edx, %r12d
+** movl %r9d, %r14d
+** movl %r8d, %r13d
+** jmp continuation
+*/
+
+#include "preserve-none-34a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-35a.c b/gcc/testsuite/gcc.target/i386/preserve-none-35a.c
new file mode 100644
index 00000000000..0bba3bfffef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-35a.c
@@ -0,0 +1,55 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** subq \$88, %rsp
+** .cfi_def_cfa_offset 96
+** leaq 96\(%rsp\), %rax
+** movq %r13, 40\(%rsp\)
+** movq %rax, 8\(%rsp\)
+** leaq 32\(%rsp\), %rax
+** movq %rax, 16\(%rsp\)
+** xorl %eax, %eax
+** movq %r14, 48\(%rsp\)
+** movq %r15, 56\(%rsp\)
+** movq %rdi, 64\(%rsp\)
+** movq %rsi, 72\(%rsp\)
+** movl \$8, \(%rsp\)
+** call continuation
+** addq \$88, %rsp
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+#include <stdarg.h>
+
+#ifndef CALLEE_ATTRIBUTE
+#define CALLEE_ATTRIBUTE __attribute__ ((preserve_none, sysv_abi))
+#endif
+
+#ifndef CALLER_ATTRIBUTE
+#define CALLER_ATTRIBUTE __attribute__ ((preserve_none, sysv_abi))
+#endif
+
+extern void continuation (int, ...) CALLEE_ATTRIBUTE;
+
+CALLER_ATTRIBUTE
+void
+entry (int i, ...)
+{
+ va_list argp;
+ va_start (argp, i);
+ int arg1 = va_arg (argp, int);
+ int arg2 = va_arg (argp, int);
+ int arg3 = va_arg (argp, int);
+ int arg4 = va_arg (argp, int);
+ int arg5 = va_arg (argp, int);
+ continuation (i, arg1, arg2, arg3, arg4, arg5);
+}
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-35b.c b/gcc/testsuite/gcc.target/i386/preserve-none-35b.c
new file mode 100644
index 00000000000..6d473e2e66b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-35b.c
@@ -0,0 +1,39 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** subq \$88, %rsp
+** .cfi_def_cfa_offset 96
+** movl %edi, %r12d
+** movl %ecx, %r15d
+** movl %r8d, %edi
+** leaq 96\(%rsp\), %rax
+** movq %rsi, 40\(%rsp\)
+** movl %edx, %r14d
+** movl %r9d, %esi
+** movq %rax, 8\(%rsp\)
+** movl 40\(%rsp\), %r13d
+** leaq 32\(%rsp\), %rax
+** movq %rax, 16\(%rsp\)
+** xorl %eax, %eax
+** movq %rdx, 48\(%rsp\)
+** movq %rcx, 56\(%rsp\)
+** movq %r8, 64\(%rsp\)
+** movq %r9, 72\(%rsp\)
+** movl \$8, \(%rsp\)
+** call continuation
+** addq \$88, %rsp
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define CALLER_ATTRIBUTE __attribute__ ((no_callee_saved_registers, sysv_abi))
+
+#include "preserve-none-35a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-35c.c b/gcc/testsuite/gcc.target/i386/preserve-none-35c.c
new file mode 100644
index 00000000000..d05e68f0f17
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-35c.c
@@ -0,0 +1,34 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** subq \$88, %rsp
+** .cfi_def_cfa_offset 96
+** leaq 96\(%rsp\), %rax
+** movq %rsi, 40\(%rsp\)
+** movq %rax, 8\(%rsp\)
+** leaq 32\(%rsp\), %rax
+** movq %rax, 16\(%rsp\)
+** xorl %eax, %eax
+** movq %rdx, 48\(%rsp\)
+** movq %rcx, 56\(%rsp\)
+** movq %r8, 64\(%rsp\)
+** movq %r9, 72\(%rsp\)
+** movl \$8, \(%rsp\)
+** call continuation
+** addq \$88, %rsp
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((sysv_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((sysv_abi))
+
+#include "preserve-none-35a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-35d.c b/gcc/testsuite/gcc.target/i386/preserve-none-35d.c
new file mode 100644
index 00000000000..6493158cfab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-35d.c
@@ -0,0 +1,80 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB0:
+** .cfi_startproc
+** subq \$88, %rsp
+** .cfi_def_cfa_offset 96
+** leaq 104\(%rsp\), %rax
+** movq %rdx, 104\(%rsp\)
+** movq %r8, 112\(%rsp\)
+** movq %r9, 120\(%rsp\)
+** movq \$0, 56\(%rsp\)
+** movq \$0, 64\(%rsp\)
+** movq %rax, 48\(%rsp\)
+** cmpl \$47, %eax
+** ja .L2
+** leal 8\(%rax\), %edx
+** movl \(%eax\), %r10d
+** cmpl \$47, %edx
+** ja .L18
+** leal 16\(%rax\), %r9d
+** movl \(%edx\), %r8d
+** cmpl \$47, %r9d
+** ja .L19
+** leal 24\(%rax\), %edx
+** movl \(%r9d\), %r9d
+** cmpl \$47, %edx
+** ja .L20
+** addl \$32, %eax
+** movl \(%edx\), %r11d
+** cmpl \$47, %eax
+** movl %eax, %edx
+** movl \$0, %eax
+** cmovbe %rdx, %rax
+**.L9:
+** movl \(%rax\), %eax
+** movl %r11d, 32\(%rsp\)
+** movl %r10d, %edx
+** movl %eax, 40\(%rsp\)
+** call continuation
+** addq \$88, %rsp
+** .cfi_remember_state
+** .cfi_def_cfa_offset 8
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L2:
+** .cfi_restore_state
+** movl 0, %r10d
+** movl 8, %r8d
+** movl \$16, %eax
+**.L5:
+** movl \(%rax\), %r9d
+** leaq 8\(%rax\), %rdx
+**.L7:
+** movl \(%rdx\), %r11d
+** leaq 8\(%rdx\), %rax
+** jmp .L9
+**.L18:
+** movl 0, %r8d
+** movl \$8, %eax
+** jmp .L5
+**.L20:
+** xorl %edx, %edx
+** jmp .L7
+**.L19:
+** xorl %eax, %eax
+** jmp .L5
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((ms_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((ms_abi))
+
+#include "preserve-none-35a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-35e.c b/gcc/testsuite/gcc.target/i386/preserve-none-35e.c
new file mode 100644
index 00000000000..d1f0209b854
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-35e.c
@@ -0,0 +1,34 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** subq \$88, %rsp
+** .cfi_def_cfa_offset 96
+** leaq 96\(%rsp\), %rax
+** movq %r13, 40\(%rsp\)
+** movq %rax, 8\(%rsp\)
+** leaq 32\(%rsp\), %rax
+** movq %rax, 16\(%rsp\)
+** xorl %eax, %eax
+** movq %r14, 48\(%rsp\)
+** movq %r15, 56\(%rsp\)
+** movq %rdi, 64\(%rsp\)
+** movq %rsi, 72\(%rsp\)
+** movl \$8, \(%rsp\)
+** call continuation
+** addq \$88, %rsp
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((preserve_none, ms_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((preserve_none, ms_abi))
+
+#include "preserve-none-35a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-35f.c b/gcc/testsuite/gcc.target/i386/preserve-none-35f.c
new file mode 100644
index 00000000000..f50af4737ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-35f.c
@@ -0,0 +1,44 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB0:
+** .cfi_startproc
+** subq \$88, %rsp
+** .cfi_def_cfa_offset 96
+** movl %r12d, %ecx
+** leaq 96\(%rsp\), %rax
+** movq %rsi, 72\(%rsp\)
+** movq %rax, 8\(%rsp\)
+** leaq 32\(%rsp\), %rax
+** movq %rax, 16\(%rsp\)
+** movq %r13, 40\(%rsp\)
+** movq %r14, 48\(%rsp\)
+** movq %r15, 56\(%rsp\)
+** movq %rdi, 64\(%rsp\)
+** movl \$8, \(%rsp\)
+** pushq %rsi
+** .cfi_def_cfa_offset 104
+** movl 72\(%rsp\), %eax
+** pushq %rax
+** .cfi_def_cfa_offset 112
+** subq \$32, %rsp
+** .cfi_def_cfa_offset 144
+** movl 104\(%rsp\), %r9d
+** movl 96\(%rsp\), %r8d
+** movl 88\(%rsp\), %edx
+** call continuation
+** addq \$136, %rsp
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((no_callee_saved_registers, ms_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((preserve_none, ms_abi))
+
+#include "preserve-none-35a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-35g.c b/gcc/testsuite/gcc.target/i386/preserve-none-35g.c
new file mode 100644
index 00000000000..300f806414a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-35g.c
@@ -0,0 +1,85 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB0:
+** .cfi_startproc
+** subq \$40, %rsp
+** .cfi_def_cfa_offset 48
+** movl %ecx, %r12d
+** leaq 56\(%rsp\), %rax
+** movq %rdx, 56\(%rsp\)
+** movq %r8, 64\(%rsp\)
+** movq %r9, 72\(%rsp\)
+** movq \$0, 8\(%rsp\)
+** movq \$0, 16\(%rsp\)
+** movq %rax, \(%rsp\)
+** cmpl \$47, %eax
+** ja .L2
+** leal 8\(%rax\), %edx
+** movl \(%eax\), %r13d
+** cmpl \$47, %edx
+** ja .L18
+** leal 16\(%rax\), %ecx
+** movl \(%edx\), %r14d
+** cmpl \$47, %ecx
+** ja .L19
+** leal 24\(%rax\), %edx
+** movl \(%ecx\), %r15d
+** cmpl \$47, %edx
+** ja .L20
+** addl \$32, %eax
+** movl \(%edx\), %edi
+** cmpl \$47, %eax
+** movl %eax, %edx
+** movl \$0, %eax
+** cmovbe %rdx, %rax
+** movl \(%rax\), %esi
+** xorl %eax, %eax
+** call continuation
+** addq \$40, %rsp
+** .cfi_remember_state
+** .cfi_def_cfa_offset 8
+** ret
+** .p2align 4,,10
+** .p2align 3
+**.L2:
+** .cfi_restore_state
+** movl 0, %r13d
+** movl 8, %r14d
+** movl \$16, %eax
+**.L5:
+** movl \(%rax\), %r15d
+** leaq 8\(%rax\), %rdx
+**.L7:
+** movl 8\(%rdx\), %esi
+** movl \(%rdx\), %edi
+** leaq 8\(%rdx\), %rax
+** xorl %eax, %eax
+** call continuation
+** addq \$40, %rsp
+** .cfi_remember_state
+** .cfi_def_cfa_offset 8
+** ret
+**.L18:
+** .cfi_restore_state
+** movl 0, %r14d
+** movl \$8, %eax
+** jmp .L5
+**.L20:
+** xorl %edx, %edx
+** jmp .L7
+**.L19:
+** xorl %eax, %eax
+** jmp .L5
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((preserve_none, ms_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((no_callee_saved_registers, ms_abi))
+
+#include "preserve-none-35a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-36a.c b/gcc/testsuite/gcc.target/i386/preserve-none-36a.c
new file mode 100644
index 00000000000..bf5fe5196f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-36a.c
@@ -0,0 +1,33 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -march=x86-64 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** jmp continuation
+** .cfi_endproc
+**...
+*/
+
+#ifndef CALLEE_ATTRIBUTE
+#define CALLEE_ATTRIBUTE __attribute__ ((preserve_none, sysv_abi))
+#endif
+
+#ifndef CALLER_ATTRIBUTE
+#define CALLER_ATTRIBUTE __attribute__ ((preserve_none, sysv_abi))
+#endif
+
+typedef float v4sf __attribute__((vector_size(16)));
+
+extern void continuation (long, long, long, long, long, v4sf)
+ CALLEE_ATTRIBUTE;
+
+CALLER_ATTRIBUTE
+void
+entry (long arg1, long arg2, long arg3, long arg4, long arg5, v4sf arg6)
+{
+ continuation (arg1, arg2, arg3, arg4, arg5, arg6);
+}
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-36b.c b/gcc/testsuite/gcc.target/i386/preserve-none-36b.c
new file mode 100644
index 00000000000..9a110b309ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-36b.c
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -march=x86-64 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** movq %rdi, %r12
+** movq %rsi, %r13
+** movq %rdx, %r14
+** movq %rcx, %r15
+** movq %r8, %rdi
+** jmp continuation
+** .cfi_endproc
+**...
+*/
+
+#define CALLER_ATTRIBUTE __attribute__ ((no_callee_saved_registers, sysv_abi))
+
+#include "preserve-none-36a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-36c.c b/gcc/testsuite/gcc.target/i386/preserve-none-36c.c
new file mode 100644
index 00000000000..200aeb9b579
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-36c.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -march=x86-64 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** jmp continuation
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((sysv_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((sysv_abi))
+
+#include "preserve-none-36a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-36d.c b/gcc/testsuite/gcc.target/i386/preserve-none-36d.c
new file mode 100644
index 00000000000..edf840f9d07
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-36d.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -march=x86-64 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** subq \$72, %rsp
+** .cfi_def_cfa_offset 80
+** movq 120\(%rsp\), %rax
+** movaps \(%rax\), %xmm0
+** leaq 48\(%rsp\), %rax
+** movq %rax, 40\(%rsp\)
+** movq 112\(%rsp\), %rax
+** movaps %xmm0, 48\(%rsp\)
+** movq %rax, 32\(%rsp\)
+** call continuation
+** addq \$72, %rsp
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((ms_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((ms_abi))
+
+#include "preserve-none-36a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-36e.c b/gcc/testsuite/gcc.target/i386/preserve-none-36e.c
new file mode 100644
index 00000000000..87cb8e763bd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-36e.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -march=x86-64 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** jmp continuation
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((preserve_none, ms_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((preserve_none, ms_abi))
+
+#include "preserve-none-36a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-36f.c b/gcc/testsuite/gcc.target/i386/preserve-none-36f.c
new file mode 100644
index 00000000000..6b2dbc1e1ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-36f.c
@@ -0,0 +1,35 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -march=x86-64 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB0:
+** .cfi_startproc
+** subq \$24, %rsp
+** .cfi_def_cfa_offset 32
+** movq %r14, %r8
+** movq %r15, %r9
+** movq %r13, %rdx
+** movq %rsp, %rax
+** movaps %xmm0, \(%rsp\)
+** movq %r12, %rcx
+** pushq %rax
+** .cfi_def_cfa_offset 40
+** pushq %rdi
+** .cfi_def_cfa_offset 48
+** subq \$32, %rsp
+** .cfi_def_cfa_offset 80
+** call continuation
+** addq \$72, %rsp
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((no_callee_saved_registers, ms_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((preserve_none, ms_abi))
+
+#include "preserve-none-36a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-36g.c b/gcc/testsuite/gcc.target/i386/preserve-none-36g.c
new file mode 100644
index 00000000000..b0f801bd5da
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-36g.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -march=x86-64 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB0:
+** .cfi_startproc
+** subq \$8, %rsp
+** .cfi_def_cfa_offset 16
+** movq %rcx, %r12
+** movq %rdx, %r13
+** movq %r9, %r15
+** movq 56\(%rsp\), %rax
+** movq 48\(%rsp\), %rdi
+** movq %r8, %r14
+** movaps \(%rax\), %xmm0
+** call continuation
+** addq \$8, %rsp
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((preserve_none, ms_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((no_callee_saved_registers, ms_abi))
+
+#include "preserve-none-36a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-37a.c b/gcc/testsuite/gcc.target/i386/preserve-none-37a.c
new file mode 100644
index 00000000000..cb8550aa934
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-37a.c
@@ -0,0 +1,33 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -march=x86-64 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** jmp continuation
+** .cfi_endproc
+**...
+*/
+
+#ifndef CALLEE_ATTRIBUTE
+#define CALLEE_ATTRIBUTE __attribute__ ((preserve_none, sysv_abi))
+#endif
+
+#ifndef CALLER_ATTRIBUTE
+#define CALLER_ATTRIBUTE __attribute__ ((preserve_none, sysv_abi))
+#endif
+
+extern void continuation (double, double, double, double,
+ double, double, double, double)
+ CALLEE_ATTRIBUTE;
+
+CALLER_ATTRIBUTE
+void
+entry (double arg1, double arg2, double arg3, double arg4,
+ double arg5, double arg6, double arg7, double arg8)
+{
+ continuation (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+}
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-37b.c b/gcc/testsuite/gcc.target/i386/preserve-none-37b.c
new file mode 100644
index 00000000000..2f465e2cd9a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-37b.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -march=x86-64 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** jmp continuation
+** .cfi_endproc
+**...
+*/
+
+#define CALLER_ATTRIBUTE __attribute__ ((no_callee_saved_registers, sysv_abi))
+
+#include "preserve-none-37a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-37c.c b/gcc/testsuite/gcc.target/i386/preserve-none-37c.c
new file mode 100644
index 00000000000..33f6de28ac7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-37c.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -march=x86-64 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** jmp continuation
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((sysv_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((sysv_abi))
+
+#include "preserve-none-37a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-37d.c b/gcc/testsuite/gcc.target/i386/preserve-none-37d.c
new file mode 100644
index 00000000000..86fb3a1d172
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-37d.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -march=x86-64 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** jmp continuation
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((ms_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((ms_abi))
+
+#include "preserve-none-37a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-37e.c b/gcc/testsuite/gcc.target/i386/preserve-none-37e.c
new file mode 100644
index 00000000000..d089b51555e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-37e.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -march=x86-64 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB[0-9]+:
+** .cfi_startproc
+** jmp continuation
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((preserve_none, ms_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((preserve_none, ms_abi))
+
+#include "preserve-none-37a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-37f.c b/gcc/testsuite/gcc.target/i386/preserve-none-37f.c
new file mode 100644
index 00000000000..015aa7f113e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-37f.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -march=x86-64 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB0:
+** .cfi_startproc
+** subq \$72, %rsp
+** .cfi_def_cfa_offset 80
+** movsd %xmm7, 56\(%rsp\)
+** movsd %xmm6, 48\(%rsp\)
+** movsd %xmm5, 40\(%rsp\)
+** movsd %xmm4, 32\(%rsp\)
+** call continuation
+** addq \$72, %rsp
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((no_callee_saved_registers, ms_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((preserve_none, ms_abi))
+
+#include "preserve-none-37a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-37g.c b/gcc/testsuite/gcc.target/i386/preserve-none-37g.c
new file mode 100644
index 00000000000..17a3123eefa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-37g.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -march=x86-64 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**.LFB0:
+** .cfi_startproc
+** subq \$8, %rsp
+** .cfi_def_cfa_offset 16
+** movsd 72\(%rsp\), %xmm7
+** movsd 64\(%rsp\), %xmm6
+** movsd 56\(%rsp\), %xmm5
+** movsd 48\(%rsp\), %xmm4
+** call continuation
+** addq \$8, %rsp
+** .cfi_def_cfa_offset 8
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((preserve_none, ms_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((no_callee_saved_registers, ms_abi))
+
+#include "preserve-none-37a.c"
--
2.55.0