On Mon, Jul 20, 2026 at 5:30 PM Hongtao Liu <[email protected]> wrote:
>
> On Mon, Jul 20, 2026 at 4:03 PM H.J. Lu <[email protected]> wrote:
> >
> > On Mon, Jul 20, 2026 at 3:41 PM Hongtao Liu <[email protected]> wrote:
> > >
> > > On Fri, Jul 10, 2026 at 2:51 PM H.J. Lu <[email protected]> wrote:
> > > >
> > > > 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.
> > >
> > > Ok.
> >
> > I found an issue with the v3 patch.   Here is the v4 patch with
> > the fix:
> >
> > @@ -1665,10 +1668,18 @@ 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)))
> > +          && ((TARGET_64BIT
> > +               && lookup_attribute ("preserve_none",             <<<<
> > This is added.
> > +                                    TYPE_ATTRIBUTES (fntype)))
> > +              || lookup_attribute ("sysv_abi",
> > +                                   TYPE_ATTRIBUTES (fntype))))
> >      abi = SYSV_ABI;
> >
> >    return abi;
>
> Routing everything through ix86_function_type_abi means a
> preserve_none function under -mabi=ms now flips all
> MS-vs-SYSV-keyed behavior to SYSV, not just argument registers:
>
> - ix86_function_value / ix86_return_in_memory → SYSV return conventions
> - STACK_BOUNDARY (via TARGET_64BIT_MS_ABI) → 64 instead of 128
>
> Do they make sense?
>
> +  return !cum->preserve_none_abi && cum->call_abi == MS_ABI;
>
> Also !cum->preserve_none_abi seems redundant if we set abi  to
> SYSV_ABI whenever preserve_none_abi exists.
>

Given the differences between MS ABI and SYSV ABI,  it's better to treat
preserve_none attribute the same way as no_callee_saved_registers
attribute for MS ABI functions.   Here is the v5 patch to implement it.  Tested
on Linux/x86-64.

H.J.
---
In 64-bit mode, preserve_none attribute uses the same number of integer
parameters passed in registers as SYSV ABI, but with a different set of
6 registers, by setting cum->preserve_none_abi to true.  Don't set
cum->preserve_none_abi to true for MS ABI functions with preserve_none
attribute to keep the number of integer parameters passed in registers
unchanged as 4.  This treats preserve_none attribute the same way as
no_callee_saved_registers attribute for MS ABI functions.

gcc/

PR target/125297
* config/i386/i386.cc (init_cumulative_args): Don't set
cum->preserve_none_abi to true for MS ABI functions.
* doc/extend.texi: Update x86-64 preserve_none attribute
documentation.

gcc/testsuite/

PR target/125297
* gcc.target/i386/preserve-none-1.c: Skip llp64 target.
* gcc.target/i386/preserve-none-31a.c: New test.
* gcc.target/i386/preserve-none-31b.c: Likewise.
* gcc.target/i386/preserve-none-32.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.
* gcc.target/i386/preserve-none-37h.c: Likewise.
* gcc.target/i386/preserve-none-37i.c: Likewise.
* gcc.target/i386/preserve-none-37j.c: Likewise.
From 05baf87fe89a98943e9f50542b0fb1b946121c53 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <[email protected]>
Date: Wed, 13 May 2026 08:27:50 +0800
Subject: [PATCH v5] x86: Don't set cum->preserve_none_abi for x86-64 MS calls

In 64-bit mode, preserve_none attribute uses the same number of integer
parameters passed in registers as SYSV ABI, but with a different set of
6 registers, by setting cum->preserve_none_abi to true.  Don't set
cum->preserve_none_abi to true for MS ABI functions with preserve_none
attribute to keep the number of integer parameters passed in registers
unchanged as 4.  This treats preserve_none attribute the same way as
no_callee_saved_registers attribute for MS ABI functions.

gcc/

	PR target/125297
	* config/i386/i386.cc (init_cumulative_args): Don't set
	cum->preserve_none_abi to true for MS ABI functions.
	* doc/extend.texi: Update x86-64 preserve_none attribute
	documentation.

gcc/testsuite/

	PR target/125297
	* gcc.target/i386/preserve-none-1.c: Skip llp64 target.
	* gcc.target/i386/preserve-none-31a.c: New test.
	* gcc.target/i386/preserve-none-31b.c: Likewise.
	* gcc.target/i386/preserve-none-32.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.
	* gcc.target/i386/preserve-none-37h.c: Likewise.
	* gcc.target/i386/preserve-none-37i.c: Likewise.
	* gcc.target/i386/preserve-none-37j.c: Likewise.

Signed-off-by: H.J. Lu <[email protected]>
---
 gcc/config/i386/i386.cc                       |  3 +
 gcc/doc/extend.texi                           |  9 ++-
 .../gcc.target/i386/preserve-none-1.c         |  2 +-
 .../gcc.target/i386/preserve-none-31a.c       | 33 ++++++++
 .../gcc.target/i386/preserve-none-31b.c       | 22 +++++
 .../gcc.target/i386/preserve-none-32.c        | 20 +++++
 .../gcc.target/i386/preserve-none-33a.c       | 34 ++++++++
 .../gcc.target/i386/preserve-none-33b.c       | 22 +++++
 .../gcc.target/i386/preserve-none-34a.c       | 34 ++++++++
 .../gcc.target/i386/preserve-none-34b.c       | 12 +++
 .../gcc.target/i386/preserve-none-35a.c       | 60 ++++++++++++++
 .../gcc.target/i386/preserve-none-35b.c       | 39 +++++++++
 .../gcc.target/i386/preserve-none-35c.c       | 39 +++++++++
 .../gcc.target/i386/preserve-none-35d.c       | 80 +++++++++++++++++++
 .../gcc.target/i386/preserve-none-35e.c       | 80 +++++++++++++++++++
 .../gcc.target/i386/preserve-none-35f.c       | 80 +++++++++++++++++++
 .../gcc.target/i386/preserve-none-35g.c       | 80 +++++++++++++++++++
 .../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       | 30 +++++++
 .../gcc.target/i386/preserve-none-36f.c       | 30 +++++++
 .../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       | 18 +++++
 .../gcc.target/i386/preserve-none-37g.c       | 18 +++++
 .../gcc.target/i386/preserve-none-37h.c       | 27 +++++++
 .../gcc.target/i386/preserve-none-37i.c       | 27 +++++++
 .../gcc.target/i386/preserve-none-37j.c       | 18 +++++
 34 files changed, 1049 insertions(+), 5 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-32.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
 create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-37h.c
 create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-37i.c
 create mode 100644 gcc/testsuite/gcc.target/i386/preserve-none-37j.c

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index dc24eaa13de..fd16dd441c1 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -1898,8 +1898,11 @@ init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
       cum->call_abi = ix86_function_type_abi (fntype);
       preserve_none_type = fntype;
     }
+
+  /* For MS ABI functions, parameter passing scheme is unchanged.  */
   cum->preserve_none_abi
     = (preserve_none_type
+       && cum->call_abi != MS_ABI
        && (lookup_attribute ("preserve_none",
 			     TYPE_ATTRIBUTES (preserve_none_type))
 	   != nullptr));
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 4056c559c53..74cfec0b43d 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -8903,10 +8903,11 @@ interrupt.
 @item preserve_none
 This attribute applies to functions.
 
-It is similar to @code{no_callee_saved_registers}, except
-on x86-64, r12, r13, r14, r15, rdi and rsi registers are used for
-integer parameter passing and this calling convention is subject to
-change.
+It is similar to @code{no_callee_saved_registers}, except on x86-64
+with the SysV ABI, r12, r13, r14, r15, rdi and rsi registers are used
+for integer parameter passing and this calling convention is subject to
+change.  For the Microsoft ABI, this attribute is treated the same as
+@code{no_callee_saved_registers}.
 
 @atindex @code{no_caller_saved_registers}, x86
 @item no_caller_saved_registers
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-1.c b/gcc/testsuite/gcc.target/i386/preserve-none-1.c
index 25c6494610d..fff0f5d7779 100644
--- a/gcc/testsuite/gcc.target/i386/preserve-none-1.c
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-do compile { target { { ! ia32 } && { ! llp64 } } } } */
 /* { dg-options "-O2 -fomit-frame-pointer" } */
 
 extern void boring(void);
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..ae991b96f9f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-31a.c
@@ -0,0 +1,33 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mabi=ms -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?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.cfi_startproc
+**	subq	\$72, %rsp
+**	.cfi_def_cfa_offset 80
+**	movl	120\(%rsp\), %eax
+**	movl	\$-559038737, 48\(%rsp\)
+**	movl	%eax, 40\(%rsp\)
+**	movl	112\(%rsp\), %eax
+**	movl	%eax, 32\(%rsp\)
+**	call	continuation
+**	addq	\$72, %rsp
+**	.cfi_def_cfa_offset 8
+**	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..df8da5aeab8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-31b.c
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { llp64 } } } */
+/* { dg-options "-O2 -mabi=ms -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.seh_endprologue').  */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**	subq	\$72, %rsp
+**	.seh_stackalloc	72
+**	.seh_endprologue
+**	movl	120\(%rsp\), %eax
+**	movl	%eax, 40\(%rsp\)
+**	movl	112\(%rsp\), %eax
+**	movl	\$-559038737, 48\(%rsp\)
+**	movl	%eax, 32\(%rsp\)
+**	call	continuation
+**	nop
+**	addq	\$72, %rsp
+**	ret
+*/
+
+#include "preserve-none-31a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-32.c b/gcc/testsuite/gcc.target/i386/preserve-none-32.c
new file mode 100644
index 00000000000..fa8ecccb97a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-32.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target { llp64 } } } */
+/* { dg-options "-O2 -mabi=ms -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.seh_endprologue').  */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**	.seh_endprologue
+**	jmp	continuation
+*/
+
+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-33a.c b/gcc/testsuite/gcc.target/i386/preserve-none-33a.c
new file mode 100644
index 00000000000..7073760a005
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-33a.c
@@ -0,0 +1,34 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -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?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.cfi_startproc
+**	subq	\$72, %rsp
+**	.cfi_def_cfa_offset 80
+**	movl	%r9d, 40\(%rsp\)
+**	movl	%ecx, %r9d
+**	movl	%edi, %ecx
+**	movl	%r8d, 32\(%rsp\)
+**	movl	%edx, %r8d
+**	movl	%esi, %edx
+**	movl	\$-559038737, 48\(%rsp\)
+**	call	continuation
+**	addq	\$72, %rsp
+**	.cfi_def_cfa_offset 8
+**	ret
+**...
+*/
+
+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..7af72863493
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-33b.c
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { llp64 } } } */
+/* { dg-options "-O2 -mabi=ms -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.seh_endprologue').  */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**	subq	\$72, %rsp
+**	.seh_stackalloc	72
+**	.seh_endprologue
+**	movl	120\(%rsp\), %eax
+**	movl	%eax, 40\(%rsp\)
+**	movl	112\(%rsp\), %eax
+**	movl	\$-559038737, 48\(%rsp\)
+**	movl	%eax, 32\(%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..add7927518d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-34a.c
@@ -0,0 +1,34 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -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?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.cfi_startproc
+**	subq	\$72, %rsp
+**	.cfi_def_cfa_offset 80
+**	movl	%r9d, 48\(%rsp\)
+**	movl	%edx, %r9d
+**	movl	%edi, %edx
+**	movl	%r8d, 40\(%rsp\)
+**	movl	%esi, %r8d
+**	movl	%ecx, 32\(%rsp\)
+**	call	continuation
+**	addq	\$72, %rsp
+**	.cfi_def_cfa_offset 8
+**	ret
+**	.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..28c3d23119f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-34b.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { llp64 } } } */
+/* { dg-options "-O2 -mabi=ms -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -mtune=generic" } */
+/* Keep labels and directives ('.seh_endprologue').  */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**entry:
+**	.seh_endprologue
+**	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..177bf8730e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-35a.c
@@ -0,0 +1,60 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -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?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.cfi_startproc
+**	subq	\$88, %rsp
+**	.cfi_def_cfa_offset 96
+**	leaq	96\(%rsp\), %rax
+**	movq	%r13, 40\(%rsp\)
+**	movl	40\(%rsp\), %r13d
+**	movq	%r14, 48\(%rsp\)
+**	movl	48\(%rsp\), %r14d
+**	movq	%r15, 56\(%rsp\)
+**	movl	56\(%rsp\), %r15d
+**	movq	%rdi, 64\(%rsp\)
+**	movl	64\(%rsp\), %edi
+**	movq	%rsi, 72\(%rsp\)
+**	movl	72\(%rsp\), %esi
+**	movq	%rax, 8\(%rsp\)
+**	leaq	32\(%rsp\), %rax
+**	movq	%rax, 16\(%rsp\)
+**	xorl	%eax, %eax
+**	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..76ee7f79c93
--- /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 -mno-push-args -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	%edi, %r12d
+**	leaq	96\(%rsp\), %rax
+**	movq	%rsi, 40\(%rsp\)
+**	movl	40\(%rsp\), %r13d
+**	movq	%rdx, 48\(%rsp\)
+**	movl	48\(%rsp\), %r14d
+**	movq	%rcx, 56\(%rsp\)
+**	movl	56\(%rsp\), %r15d
+**	movq	%r8, 64\(%rsp\)
+**	movl	64\(%rsp\), %edi
+**	movq	%r9, 72\(%rsp\)
+**	movl	72\(%rsp\), %esi
+**	movq	%rax, 8\(%rsp\)
+**	leaq	32\(%rsp\), %rax
+**	movq	%rax, 16\(%rsp\)
+**	xorl	%eax, %eax
+**	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..8a307207693
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-35c.c
@@ -0,0 +1,39 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -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?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.cfi_startproc
+**	subq	\$88, %rsp
+**	.cfi_def_cfa_offset 96
+**	leaq	96\(%rsp\), %rax
+**	movq	%rsi, 40\(%rsp\)
+**	movl	40\(%rsp\), %esi
+**	movq	%rdx, 48\(%rsp\)
+**	movl	48\(%rsp\), %edx
+**	movq	%rcx, 56\(%rsp\)
+**	movl	56\(%rsp\), %ecx
+**	movq	%r8, 64\(%rsp\)
+**	movl	64\(%rsp\), %r8d
+**	movq	%r9, 72\(%rsp\)
+**	movl	72\(%rsp\), %r9d
+**	movq	%rax, 8\(%rsp\)
+**	leaq	32\(%rsp\), %rax
+**	movq	%rax, 16\(%rsp\)
+**	xorl	%eax, %eax
+**	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..4a362233587
--- /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 -mno-push-args -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..510281c7a79
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-35e.c
@@ -0,0 +1,80 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -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?\.}  } } */
+
+/*
+**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\), %esi
+**	cmpl	\$47, %edx
+**	ja	.L18
+**	leal	16\(%rax\), %edi
+**	movl	\(%edx\), %r8d
+**	cmpl	\$47, %edi
+**	ja	.L19
+**	leal	24\(%rax\), %edx
+**	movl	\(%edi\), %r9d
+**	cmpl	\$47, %edx
+**	ja	.L20
+**	addl	\$32, %eax
+**	movl	\(%edx\), %edi
+**	cmpl	\$47, %eax
+**	movl	%eax, %edx
+**	movl	\$0, %eax
+**	cmovbe	%rdx, %rax
+**.L9:
+**	movl	\(%rax\), %eax
+**	movl	%edi, 32\(%rsp\)
+**	movl	%esi, %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, %esi
+**	movl	8, %r8d
+**	movl	\$16, %eax
+**.L5:
+**	movl	\(%rax\), %r9d
+**	leaq	8\(%rax\), %rdx
+**.L7:
+**	movl	\(%rdx\), %edi
+**	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__ ((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..301a357a3cf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-35f.c
@@ -0,0 +1,80 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -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?\.}  } } */
+
+/*
+**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\), %esi
+**	cmpl	\$47, %edx
+**	ja	.L18
+**	leal	16\(%rax\), %edi
+**	movl	\(%edx\), %r8d
+**	cmpl	\$47, %edi
+**	ja	.L19
+**	leal	24\(%rax\), %edx
+**	movl	\(%edi\), %r9d
+**	cmpl	\$47, %edx
+**	ja	.L20
+**	addl	\$32, %eax
+**	movl	\(%edx\), %edi
+**	cmpl	\$47, %eax
+**	movl	%eax, %edx
+**	movl	\$0, %eax
+**	cmovbe	%rdx, %rax
+**.L9:
+**	movl	\(%rax\), %eax
+**	movl	%edi, 32\(%rsp\)
+**	movl	%esi, %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, %esi
+**	movl	8, %r8d
+**	movl	\$16, %eax
+**.L5:
+**	movl	\(%rax\), %r9d
+**	leaq	8\(%rax\), %rdx
+**.L7:
+**	movl	\(%rdx\), %edi
+**	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__ ((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..3057456c630
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-35g.c
@@ -0,0 +1,80 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -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?\.}  } } */
+
+/*
+**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\), %esi
+**	cmpl	\$47, %edx
+**	ja	.L18
+**	leal	16\(%rax\), %edi
+**	movl	\(%edx\), %r8d
+**	cmpl	\$47, %edi
+**	ja	.L19
+**	leal	24\(%rax\), %edx
+**	movl	\(%edi\), %r9d
+**	cmpl	\$47, %edx
+**	ja	.L20
+**	addl	\$32, %eax
+**	movl	\(%edx\), %edi
+**	cmpl	\$47, %eax
+**	movl	%eax, %edx
+**	movl	\$0, %eax
+**	cmovbe	%rdx, %rax
+**.L9:
+**	movl	\(%rax\), %eax
+**	movl	%edi, 32\(%rsp\)
+**	movl	%esi, %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, %esi
+**	movl	8, %r8d
+**	movl	\$16, %eax
+**.L5:
+**	movl	\(%rax\), %r9d
+**	leaq	8\(%rax\), %rdx
+**.L7:
+**	movl	\(%rdx\), %edi
+**	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__ ((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..71b526ff435
--- /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 -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?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.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..022bfba6089
--- /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 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.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..caecf5d37fb
--- /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 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.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..efab3a74b9a
--- /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 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* 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
+**	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..76a5e83a6ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-36e.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* 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
+**	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__ ((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..64bc9390ed3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-36f.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* 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
+**	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__ ((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..e63e3d3e011
--- /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 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* 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
+**	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__ ((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..c0894752b03
--- /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 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.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..9129d6b606f
--- /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 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.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..e3ea3b12ee5
--- /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 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.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..bd9601d17ae
--- /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 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.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..339370a4ae2
--- /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 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.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..32afd5bdad3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-37f.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.cfi_startproc
+**	jmp	continuation
+**	.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..ad0180c370a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-37g.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.cfi_startproc
+**	jmp	continuation
+**	.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"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-37h.c b/gcc/testsuite/gcc.target/i386/preserve-none-37h.c
new file mode 100644
index 00000000000..b3906e09173
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-37h.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mabi=ms -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* 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__ ((preserve_none))
+#define CALLER_ATTRIBUTE __attribute__ ((preserve_none, sysv_abi))
+
+#include "preserve-none-37a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-37i.c b/gcc/testsuite/gcc.target/i386/preserve-none-37i.c
new file mode 100644
index 00000000000..d0270475e1c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-37i.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mabi=ms -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* 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, sysv_abi))
+#define CALLER_ATTRIBUTE __attribute__ ((preserve_none))
+
+#include "preserve-none-37a.c"
diff --git a/gcc/testsuite/gcc.target/i386/preserve-none-37j.c b/gcc/testsuite/gcc.target/i386/preserve-none-37j.c
new file mode 100644
index 00000000000..9a7f9bb4556
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/preserve-none-37j.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -mabi=ms -mtune-ctrl=^prologue_using_move,^epilogue_using_move -mno-push-args -fomit-frame-pointer -march=x86-64" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.}  } } */
+
+/*
+**entry:
+**.LFB0:
+**	.cfi_startproc
+**	jmp	continuation
+**	.cfi_endproc
+**...
+*/
+
+#define CALLEE_ATTRIBUTE __attribute__ ((preserve_none))
+#define CALLER_ATTRIBUTE __attribute__ ((preserve_none))
+
+#include "preserve-none-37a.c"
-- 
2.55.0

Reply via email to