public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] x86: Update user interrupt handler stack frame
@ 2020-12-10 21:20 H.J. Lu
  2020-12-10 21:57 ` Uros Bizjak
  0 siblings, 1 reply; 3+ messages in thread
From: H.J. Lu @ 2020-12-10 21:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: Uros Bizjak

User interrupt handler stack frame is similar to exception interrupt
handler stack frame.  Instead of error code, the second argument is
user interrupt request register vector.

gcc/

	PR target/98219
	* config/i386/uintrintrin.h (__uintr_frame): Remove uirrv.

gcc/testsuite/

	PR target/98219
	* gcc.dg/guality/pr98219-1.c: New test.
	* gcc.dg/guality/pr98219-2.c: Likewise.
	* gcc.dg/torture/pr98219-1.c: Likewise.
	* gcc.dg/torture/pr98219-2.c: Likewise.
	* gcc.target/i386/uintr-2.c: Scan "add[lq] $8, %[er]sp".
	(foo): Add an unsigned long long argument.
	(UINTR_hanlder): Likewise.
	* gcc.target/i386/uintr-3.c: Scan "add[lq] $8, %[er]sp".
	(UINTR_hanlder): Add an unsigned long long argument.
	* gcc.target/i386/uintr-4.c (UINTR_hanlder): Likewise.
	* gcc.target/i386/uintr-5.c (UINTR_hanlder): Likewise.
---
 gcc/config/i386/uintrintrin.h            |  3 --
 gcc/testsuite/gcc.dg/guality/pr98219-1.c | 48 ++++++++++++++++++
 gcc/testsuite/gcc.dg/guality/pr98219-2.c | 63 ++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/pr98219-1.c | 44 +++++++++++++++++
 gcc/testsuite/gcc.dg/torture/pr98219-2.c | 59 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/uintr-2.c  |  5 +-
 gcc/testsuite/gcc.target/i386/uintr-3.c  |  4 +-
 gcc/testsuite/gcc.target/i386/uintr-4.c  |  4 +-
 gcc/testsuite/gcc.target/i386/uintr-5.c  |  2 +-
 9 files changed, 223 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/guality/pr98219-1.c
 create mode 100644 gcc/testsuite/gcc.dg/guality/pr98219-2.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr98219-1.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr98219-2.c

diff --git a/gcc/config/i386/uintrintrin.h b/gcc/config/i386/uintrintrin.h
index 991f6427971..4606caf8582 100644
--- a/gcc/config/i386/uintrintrin.h
+++ b/gcc/config/i386/uintrintrin.h
@@ -38,9 +38,6 @@
 
 struct __uintr_frame
 {
-  /* The position of the most significant bit set in user-interrupt
-     request register.  */
-  unsigned long long uirrv;
   /* RIP of the interrupted user process.  */
   unsigned long long rip;
   /* RFLAGS of the interrupted user process.  */
diff --git a/gcc/testsuite/gcc.dg/guality/pr98219-1.c b/gcc/testsuite/gcc.dg/guality/pr98219-1.c
new file mode 100644
index 00000000000..8d695080fd8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr98219-1.c
@@ -0,0 +1,48 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } */
+/* { dg-options "-g -muintr -mgeneral-regs-only" } */
+
+#include <x86gprintrin.h>
+
+extern void exit (int);
+
+#define UIRRV		0x12345670
+#define RIP		0x12345671
+#define RFLAGS		0x12345672
+#define RSP		0x12345673
+
+#define STRING(x)	XSTRING(x)
+#define XSTRING(x)	#x
+#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
+
+__attribute__((interrupt, used))
+void
+fn (struct __uintr_frame *frame, unsigned long long uirrv)
+{
+  if (UIRRV != uirrv)		/* BREAK */
+    __builtin_abort ();
+  if (RIP != frame->rip)
+    __builtin_abort ();
+  if (RFLAGS != frame->rflags)
+    __builtin_abort ();
+  if (RSP != frame->rsp)
+    __builtin_abort ();
+
+  exit (0);
+}
+
+int
+main ()
+{
+  asm ("push	$" STRING (RSP) ";		\
+	push	$" STRING (RFLAGS) ";		\
+	push	$" STRING (RIP) ";		\
+	push	$" STRING (UIRRV) ";		\
+	jmp	" ASMNAME ("fn"));
+  return 0;
+}
+
+/* { dg-final { gdb-test 22 "uirrv" "0x12345670" } } */
+/* { dg-final { gdb-test 22 "frame->rip" "0x12345671" } } */
+/* { dg-final { gdb-test 22 "frame->rflags" "0x12345672" } } */
+/* { dg-final { gdb-test 22 "frame->rsp" "0x12345673" } } */
diff --git a/gcc/testsuite/gcc.dg/guality/pr98219-2.c b/gcc/testsuite/gcc.dg/guality/pr98219-2.c
new file mode 100644
index 00000000000..c0e48c981de
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr98219-2.c
@@ -0,0 +1,63 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } */
+/* { dg-options "-g -muintr -mgeneral-regs-only" } */
+
+#include <x86gprintrin.h>
+
+extern void exit (int);
+typedef int aligned __attribute__((aligned(64)));
+
+#define UIRRV		0x12345670
+#define RIP		0x12345671
+#define RFLAGS		0x12345672
+#define RSP		0x12345673
+
+#define STRING(x)	XSTRING(x)
+#define XSTRING(x)	#x
+#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
+
+int
+check_int (int *i, int align)
+{
+  *i = 20;
+  if ((((ptrdiff_t) i) & (align - 1)) != 0)
+    __builtin_abort ();
+  return *i;
+}
+
+__attribute__((interrupt, used))
+__attribute__((interrupt, used))
+void
+fn (struct __uintr_frame *frame, unsigned long long uirrv)
+{
+  aligned i;
+  if (check_int (&i, __alignof__(i)) != i)
+    __builtin_abort ();
+
+  if (UIRRV != uirrv)		/* BREAK */
+    __builtin_abort ();
+  if (RIP != frame->rip)
+    __builtin_abort ();
+  if (RFLAGS != frame->rflags)
+    __builtin_abort ();
+  if (RSP != frame->rsp)
+    __builtin_abort ();
+
+  exit (0);
+}
+
+int
+main ()
+{
+  asm ("push	$" STRING (RSP) ";		\
+	push	$" STRING (RFLAGS) ";		\
+	push	$" STRING (RIP) ";		\
+	push	$" STRING (UIRRV) ";		\
+	jmp	" ASMNAME ("fn"));
+  return 0;
+}
+
+/* { dg-final { gdb-test 34 "uirrv" "0x12345670" } } */
+/* { dg-final { gdb-test 34 "frame->rip" "0x12345671" } } */
+/* { dg-final { gdb-test 34 "frame->rflags" "0x12345672" } } */
+/* { dg-final { gdb-test 34 "frame->rsp" "0x12345673" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr98219-1.c b/gcc/testsuite/gcc.dg/torture/pr98219-1.c
new file mode 100644
index 00000000000..c78495cc1c0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr98219-1.c
@@ -0,0 +1,44 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } */
+/* { dg-skip-if "PR81210 sp not aligned to 16 bytes" { *-*-darwin* } } */
+/* { dg-options "-muintr -mgeneral-regs-only" } */
+
+#include <x86gprintrin.h>
+
+extern void exit (int);
+
+#define UIRRV		0x12345670
+#define RIP		0x12345671
+#define RFLAGS		0x12345672
+#define RSP		0x12345673
+
+#define STRING(x)	XSTRING(x)
+#define XSTRING(x)	#x
+#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
+
+__attribute__((interrupt, used))
+void
+fn (struct __uintr_frame *frame, unsigned long long uirrv)
+{
+  if (UIRRV != uirrv)
+    __builtin_abort ();
+  if (RIP != frame->rip)
+    __builtin_abort ();
+  if (RFLAGS != frame->rflags)
+    __builtin_abort ();
+  if (RSP != frame->rsp)
+    __builtin_abort ();
+
+  exit (0);
+}
+
+int
+main ()
+{
+  asm ("push	$" STRING (RSP) ";		\
+	push	$" STRING (RFLAGS) ";		\
+	push	$" STRING (RIP) ";		\
+	push	$" STRING (UIRRV) ";		\
+	jmp	" ASMNAME ("fn"));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr98219-2.c b/gcc/testsuite/gcc.dg/torture/pr98219-2.c
new file mode 100644
index 00000000000..176fb78e42e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr98219-2.c
@@ -0,0 +1,59 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } */
+/* { dg-skip-if "PR81210 sp not aligned to 16 bytes" { *-*-darwin* } } */
+/* { dg-options "-muintr -mgeneral-regs-only" } */
+
+#include <x86gprintrin.h>
+
+extern void exit (int);
+typedef int aligned __attribute__((aligned(64)));
+
+#define UIRRV		0x12345670
+#define RIP		0x12345671
+#define RFLAGS		0x12345672
+#define RSP		0x12345673
+
+#define STRING(x)	XSTRING(x)
+#define XSTRING(x)	#x
+#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
+
+int
+check_int (int *i, int align)
+{
+  *i = 20;
+  if ((((ptrdiff_t) i) & (align - 1)) != 0)
+    __builtin_abort ();
+  return *i;
+}
+
+__attribute__((interrupt, used))
+__attribute__((interrupt, used))
+void
+fn (struct __uintr_frame *frame, unsigned long long uirrv)
+{
+  aligned i;
+  if (check_int (&i, __alignof__(i)) != i)
+    __builtin_abort ();
+
+  if (UIRRV != uirrv)
+    __builtin_abort ();
+  if (RIP != frame->rip)
+    __builtin_abort ();
+  if (RFLAGS != frame->rflags)
+    __builtin_abort ();
+  if (RSP != frame->rsp)
+    __builtin_abort ();
+
+  exit (0);
+}
+
+int
+main ()
+{
+  asm ("push	$" STRING (RSP) ";		\
+	push	$" STRING (RFLAGS) ";		\
+	push	$" STRING (RIP) ";		\
+	push	$" STRING (UIRRV) ";		\
+	jmp	" ASMNAME ("fn"));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/uintr-2.c b/gcc/testsuite/gcc.target/i386/uintr-2.c
index e705732c1bd..2ff32640827 100644
--- a/gcc/testsuite/gcc.target/i386/uintr-2.c
+++ b/gcc/testsuite/gcc.target/i386/uintr-2.c
@@ -1,17 +1,18 @@
 /* { dg-do compile { target { ! ia32 } } } */
 /* { dg-options "-O2 -muintr -mgeneral-regs-only" } */
 /* { dg-final { scan-assembler-times "uiret" "2" } } */
+/* { dg-final { scan-assembler-times "add\[lq]\[ \t]\+\\\$8, %\[er\]sp" "2" } } */
 
 #include <x86gprintrin.h>
 
 void
 __attribute__((interrupt))
-foo (void *frame)
+foo (void *frame, unsigned long long uirrv)
 {
 }
 
 void
 __attribute__((interrupt))
-UINTR_hanlder (struct __uintr_frame *frame)
+UINTR_hanlder (struct __uintr_frame *frame, unsigned long long uirrv)
 {
 }
diff --git a/gcc/testsuite/gcc.target/i386/uintr-3.c b/gcc/testsuite/gcc.target/i386/uintr-3.c
index d2843495158..0b925066668 100644
--- a/gcc/testsuite/gcc.target/i386/uintr-3.c
+++ b/gcc/testsuite/gcc.target/i386/uintr-3.c
@@ -1,9 +1,11 @@
 /* { dg-do compile { target { ! ia32 } } } */
 /* { dg-options "-O2 -muintr" } */
 /* { dg-final { scan-assembler "uiret" } } */
+/* { dg-final { scan-assembler "add\[lq]\[ \t]\+\\\$8, %\[er\]sp" } } */
+
 #include <x86gprintrin.h>
 
 void __attribute__ ((target("general-regs-only"), interrupt))
-UINTR_handler (struct __uintr_frame *p)
+UINTR_handler (struct __uintr_frame *p, unsigned long long uirrv)
 {
 }
diff --git a/gcc/testsuite/gcc.target/i386/uintr-4.c b/gcc/testsuite/gcc.target/i386/uintr-4.c
index f3b371b4231..60478b126a7 100644
--- a/gcc/testsuite/gcc.target/i386/uintr-4.c
+++ b/gcc/testsuite/gcc.target/i386/uintr-4.c
@@ -4,6 +4,6 @@
 #include <x86gprintrin.h>
 
 void __attribute__ ((interrupt))
-UINTR_handler (struct __uintr_frame *p)
-{ /* { dg-message "SSE instructions aren't allowed in an interrupt service routine" }  */
+UINTR_handler (struct __uintr_frame *p, unsigned long long uirrv)
+{ /* { dg-message "SSE instructions aren't allowed in an exception service routine" }  */
 }
diff --git a/gcc/testsuite/gcc.target/i386/uintr-5.c b/gcc/testsuite/gcc.target/i386/uintr-5.c
index ac44be0a706..d49e54d3134 100644
--- a/gcc/testsuite/gcc.target/i386/uintr-5.c
+++ b/gcc/testsuite/gcc.target/i386/uintr-5.c
@@ -5,6 +5,6 @@
 #include <x86gprintrin.h>
 
 void
-UINTR_hanlder (struct __uintr_frame *frame)
+UINTR_hanlder (struct __uintr_frame *frame, unsigned long long uirrv)
 {
 }
-- 
2.29.2


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] x86: Update user interrupt handler stack frame
  2020-12-10 21:20 [PATCH] x86: Update user interrupt handler stack frame H.J. Lu
@ 2020-12-10 21:57 ` Uros Bizjak
  2020-12-11 14:55   ` V2 " H.J. Lu
  0 siblings, 1 reply; 3+ messages in thread
From: Uros Bizjak @ 2020-12-10 21:57 UTC (permalink / raw)
  To: H.J. Lu; +Cc: gcc-patches

On Thu, Dec 10, 2020 at 10:20 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> User interrupt handler stack frame is similar to exception interrupt
> handler stack frame.  Instead of error code, the second argument is
> user interrupt request register vector.
>
> gcc/
>
>         PR target/98219
>         * config/i386/uintrintrin.h (__uintr_frame): Remove uirrv.
>
> gcc/testsuite/
>
>         PR target/98219
>         * gcc.dg/guality/pr98219-1.c: New test.
>         * gcc.dg/guality/pr98219-2.c: Likewise.
>         * gcc.dg/torture/pr98219-1.c: Likewise.
>         * gcc.dg/torture/pr98219-2.c: Likewise.
>         * gcc.target/i386/uintr-2.c: Scan "add[lq] $8, %[er]sp".
>         (foo): Add an unsigned long long argument.
>         (UINTR_hanlder): Likewise.
>         * gcc.target/i386/uintr-3.c: Scan "add[lq] $8, %[er]sp".
>         (UINTR_hanlder): Add an unsigned long long argument.
>         * gcc.target/i386/uintr-4.c (UINTR_hanlder): Likewise.
>         * gcc.target/i386/uintr-5.c (UINTR_hanlder): Likewise.

OK with the fixes, described inline.

Thanks,
Uros.

> ---
>  gcc/config/i386/uintrintrin.h            |  3 --
>  gcc/testsuite/gcc.dg/guality/pr98219-1.c | 48 ++++++++++++++++++
>  gcc/testsuite/gcc.dg/guality/pr98219-2.c | 63 ++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/pr98219-1.c | 44 +++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/pr98219-2.c | 59 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/i386/uintr-2.c  |  5 +-
>  gcc/testsuite/gcc.target/i386/uintr-3.c  |  4 +-
>  gcc/testsuite/gcc.target/i386/uintr-4.c  |  4 +-
>  gcc/testsuite/gcc.target/i386/uintr-5.c  |  2 +-
>  9 files changed, 223 insertions(+), 9 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/guality/pr98219-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/guality/pr98219-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/torture/pr98219-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/torture/pr98219-2.c
>
> diff --git a/gcc/config/i386/uintrintrin.h b/gcc/config/i386/uintrintrin.h
> index 991f6427971..4606caf8582 100644
> --- a/gcc/config/i386/uintrintrin.h
> +++ b/gcc/config/i386/uintrintrin.h
> @@ -38,9 +38,6 @@
>
>  struct __uintr_frame
>  {
> -  /* The position of the most significant bit set in user-interrupt
> -     request register.  */
> -  unsigned long long uirrv;
>    /* RIP of the interrupted user process.  */
>    unsigned long long rip;
>    /* RFLAGS of the interrupted user process.  */
> diff --git a/gcc/testsuite/gcc.dg/guality/pr98219-1.c b/gcc/testsuite/gcc.dg/guality/pr98219-1.c
> new file mode 100644
> index 00000000000..8d695080fd8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/guality/pr98219-1.c
> @@ -0,0 +1,48 @@
> +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } */

No need for extra curly braces after !, so:

... & { ! ia32 } ...

here and in other tests.

> +/* { dg-options "-g -muintr -mgeneral-regs-only" } */
> +
> +#include <x86gprintrin.h>
> +
> +extern void exit (int);
> +
> +#define UIRRV          0x12345670
> +#define RIP            0x12345671
> +#define RFLAGS         0x12345672
> +#define RSP            0x12345673
> +
> +#define STRING(x)      XSTRING(x)
> +#define XSTRING(x)     #x
> +#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
> +#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
> +
> +__attribute__((interrupt, used))
> +void
> +fn (struct __uintr_frame *frame, unsigned long long uirrv)

Please define and use

typedef unsigned int uword_t __attribute__ ((mode (__word__)));

as is the case in interrupt-3.c. Also, the convention is:

void
__attribute_((...))
fn (...)

Please also fix in other tests.

> +{
> +  if (UIRRV != uirrv)          /* BREAK */
> +    __builtin_abort ();
> +  if (RIP != frame->rip)
> +    __builtin_abort ();
> +  if (RFLAGS != frame->rflags)
> +    __builtin_abort ();
> +  if (RSP != frame->rsp)
> +    __builtin_abort ();
> +
> +  exit (0);
> +}
> +
> +int
> +main ()
> +{
> +  asm ("push   $" STRING (RSP) ";              \
> +       push    $" STRING (RFLAGS) ";           \
> +       push    $" STRING (RIP) ";              \
> +       push    $" STRING (UIRRV) ";            \
> +       jmp     " ASMNAME ("fn"));
> +  return 0;
> +}
> +
> +/* { dg-final { gdb-test 22 "uirrv" "0x12345670" } } */
> +/* { dg-final { gdb-test 22 "frame->rip" "0x12345671" } } */
> +/* { dg-final { gdb-test 22 "frame->rflags" "0x12345672" } } */
> +/* { dg-final { gdb-test 22 "frame->rsp" "0x12345673" } } */
> diff --git a/gcc/testsuite/gcc.dg/guality/pr98219-2.c b/gcc/testsuite/gcc.dg/guality/pr98219-2.c
> new file mode 100644
> index 00000000000..c0e48c981de
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/guality/pr98219-2.c
> @@ -0,0 +1,63 @@
> +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } */
> +/* { dg-options "-g -muintr -mgeneral-regs-only" } */
> +
> +#include <x86gprintrin.h>
> +
> +extern void exit (int);
> +typedef int aligned __attribute__((aligned(64)));
> +
> +#define UIRRV          0x12345670
> +#define RIP            0x12345671
> +#define RFLAGS         0x12345672
> +#define RSP            0x12345673
> +
> +#define STRING(x)      XSTRING(x)
> +#define XSTRING(x)     #x
> +#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
> +#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
> +
> +int
> +check_int (int *i, int align)
> +{
> +  *i = 20;
> +  if ((((ptrdiff_t) i) & (align - 1)) != 0)
> +    __builtin_abort ();
> +  return *i;
> +}
> +
> +__attribute__((interrupt, used))
> +__attribute__((interrupt, used))

Two __attribute__s? Also, please follow convention as suggested above.

> +void
> +fn (struct __uintr_frame *frame, unsigned long long uirrv)
> +{
> +  aligned i;
> +  if (check_int (&i, __alignof__(i)) != i)
> +    __builtin_abort ();
> +
> +  if (UIRRV != uirrv)          /* BREAK */
> +    __builtin_abort ();
> +  if (RIP != frame->rip)
> +    __builtin_abort ();
> +  if (RFLAGS != frame->rflags)
> +    __builtin_abort ();
> +  if (RSP != frame->rsp)
> +    __builtin_abort ();
> +
> +  exit (0);
> +}
> +
> +int
> +main ()
> +{
> +  asm ("push   $" STRING (RSP) ";              \
> +       push    $" STRING (RFLAGS) ";           \
> +       push    $" STRING (RIP) ";              \
> +       push    $" STRING (UIRRV) ";            \
> +       jmp     " ASMNAME ("fn"));
> +  return 0;
> +}
> +
> +/* { dg-final { gdb-test 34 "uirrv" "0x12345670" } } */
> +/* { dg-final { gdb-test 34 "frame->rip" "0x12345671" } } */
> +/* { dg-final { gdb-test 34 "frame->rflags" "0x12345672" } } */
> +/* { dg-final { gdb-test 34 "frame->rsp" "0x12345673" } } */
> diff --git a/gcc/testsuite/gcc.dg/torture/pr98219-1.c b/gcc/testsuite/gcc.dg/torture/pr98219-1.c
> new file mode 100644
> index 00000000000..c78495cc1c0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/pr98219-1.c
> @@ -0,0 +1,44 @@
> +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } */
> +/* { dg-skip-if "PR81210 sp not aligned to 16 bytes" { *-*-darwin* } } */
> +/* { dg-options "-muintr -mgeneral-regs-only" } */
> +
> +#include <x86gprintrin.h>
> +
> +extern void exit (int);
> +
> +#define UIRRV          0x12345670
> +#define RIP            0x12345671
> +#define RFLAGS         0x12345672
> +#define RSP            0x12345673
> +
> +#define STRING(x)      XSTRING(x)
> +#define XSTRING(x)     #x
> +#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
> +#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
> +
> +__attribute__((interrupt, used))
> +void
> +fn (struct __uintr_frame *frame, unsigned long long uirrv)
> +{
> +  if (UIRRV != uirrv)
> +    __builtin_abort ();
> +  if (RIP != frame->rip)
> +    __builtin_abort ();
> +  if (RFLAGS != frame->rflags)
> +    __builtin_abort ();
> +  if (RSP != frame->rsp)
> +    __builtin_abort ();
> +
> +  exit (0);
> +}
> +
> +int
> +main ()
> +{
> +  asm ("push   $" STRING (RSP) ";              \
> +       push    $" STRING (RFLAGS) ";           \
> +       push    $" STRING (RIP) ";              \
> +       push    $" STRING (UIRRV) ";            \
> +       jmp     " ASMNAME ("fn"));
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.dg/torture/pr98219-2.c b/gcc/testsuite/gcc.dg/torture/pr98219-2.c
> new file mode 100644
> index 00000000000..176fb78e42e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/pr98219-2.c
> @@ -0,0 +1,59 @@
> +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } */
> +/* { dg-skip-if "PR81210 sp not aligned to 16 bytes" { *-*-darwin* } } */
> +/* { dg-options "-muintr -mgeneral-regs-only" } */
> +
> +#include <x86gprintrin.h>
> +
> +extern void exit (int);
> +typedef int aligned __attribute__((aligned(64)));
> +
> +#define UIRRV          0x12345670
> +#define RIP            0x12345671
> +#define RFLAGS         0x12345672
> +#define RSP            0x12345673
> +
> +#define STRING(x)      XSTRING(x)
> +#define XSTRING(x)     #x
> +#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
> +#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
> +
> +int
> +check_int (int *i, int align)
> +{
> +  *i = 20;
> +  if ((((ptrdiff_t) i) & (align - 1)) != 0)
> +    __builtin_abort ();
> +  return *i;
> +}
> +
> +__attribute__((interrupt, used))
> +__attribute__((interrupt, used))
> +void
> +fn (struct __uintr_frame *frame, unsigned long long uirrv)
> +{
> +  aligned i;
> +  if (check_int (&i, __alignof__(i)) != i)
> +    __builtin_abort ();
> +
> +  if (UIRRV != uirrv)
> +    __builtin_abort ();
> +  if (RIP != frame->rip)
> +    __builtin_abort ();
> +  if (RFLAGS != frame->rflags)
> +    __builtin_abort ();
> +  if (RSP != frame->rsp)
> +    __builtin_abort ();
> +
> +  exit (0);
> +}
> +
> +int
> +main ()
> +{
> +  asm ("push   $" STRING (RSP) ";              \
> +       push    $" STRING (RFLAGS) ";           \
> +       push    $" STRING (RIP) ";              \
> +       push    $" STRING (UIRRV) ";            \
> +       jmp     " ASMNAME ("fn"));
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/uintr-2.c b/gcc/testsuite/gcc.target/i386/uintr-2.c
> index e705732c1bd..2ff32640827 100644
> --- a/gcc/testsuite/gcc.target/i386/uintr-2.c
> +++ b/gcc/testsuite/gcc.target/i386/uintr-2.c
> @@ -1,17 +1,18 @@
>  /* { dg-do compile { target { ! ia32 } } } */
>  /* { dg-options "-O2 -muintr -mgeneral-regs-only" } */
>  /* { dg-final { scan-assembler-times "uiret" "2" } } */
> +/* { dg-final { scan-assembler-times "add\[lq]\[ \t]\+\\\$8, %\[er\]sp" "2" } } */
>
>  #include <x86gprintrin.h>
>
>  void
>  __attribute__((interrupt))
> -foo (void *frame)
> +foo (void *frame, unsigned long long uirrv)
>  {
>  }
>
>  void
>  __attribute__((interrupt))
> -UINTR_hanlder (struct __uintr_frame *frame)
> +UINTR_hanlder (struct __uintr_frame *frame, unsigned long long uirrv)
>  {
>  }
> diff --git a/gcc/testsuite/gcc.target/i386/uintr-3.c b/gcc/testsuite/gcc.target/i386/uintr-3.c
> index d2843495158..0b925066668 100644
> --- a/gcc/testsuite/gcc.target/i386/uintr-3.c
> +++ b/gcc/testsuite/gcc.target/i386/uintr-3.c
> @@ -1,9 +1,11 @@
>  /* { dg-do compile { target { ! ia32 } } } */
>  /* { dg-options "-O2 -muintr" } */
>  /* { dg-final { scan-assembler "uiret" } } */
> +/* { dg-final { scan-assembler "add\[lq]\[ \t]\+\\\$8, %\[er\]sp" } } */
> +
>  #include <x86gprintrin.h>
>
>  void __attribute__ ((target("general-regs-only"), interrupt))
> -UINTR_handler (struct __uintr_frame *p)
> +UINTR_handler (struct __uintr_frame *p, unsigned long long uirrv)
>  {
>  }
> diff --git a/gcc/testsuite/gcc.target/i386/uintr-4.c b/gcc/testsuite/gcc.target/i386/uintr-4.c
> index f3b371b4231..60478b126a7 100644
> --- a/gcc/testsuite/gcc.target/i386/uintr-4.c
> +++ b/gcc/testsuite/gcc.target/i386/uintr-4.c
> @@ -4,6 +4,6 @@
>  #include <x86gprintrin.h>
>
>  void __attribute__ ((interrupt))
> -UINTR_handler (struct __uintr_frame *p)
> -{ /* { dg-message "SSE instructions aren't allowed in an interrupt service routine" }  */
> +UINTR_handler (struct __uintr_frame *p, unsigned long long uirrv)
> +{ /* { dg-message "SSE instructions aren't allowed in an exception service routine" }  */
>  }
> diff --git a/gcc/testsuite/gcc.target/i386/uintr-5.c b/gcc/testsuite/gcc.target/i386/uintr-5.c
> index ac44be0a706..d49e54d3134 100644
> --- a/gcc/testsuite/gcc.target/i386/uintr-5.c
> +++ b/gcc/testsuite/gcc.target/i386/uintr-5.c
> @@ -5,6 +5,6 @@
>  #include <x86gprintrin.h>
>
>  void
> -UINTR_hanlder (struct __uintr_frame *frame)
> +UINTR_hanlder (struct __uintr_frame *frame, unsigned long long uirrv)
>  {
>  }
> --
> 2.29.2
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* V2 [PATCH] x86: Update user interrupt handler stack frame
  2020-12-10 21:57 ` Uros Bizjak
@ 2020-12-11 14:55   ` H.J. Lu
  0 siblings, 0 replies; 3+ messages in thread
From: H.J. Lu @ 2020-12-11 14:55 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 13467 bytes --]

On Thu, Dec 10, 2020 at 1:57 PM Uros Bizjak <ubizjak@gmail.com> wrote:
>
> On Thu, Dec 10, 2020 at 10:20 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> >
> > User interrupt handler stack frame is similar to exception interrupt
> > handler stack frame.  Instead of error code, the second argument is
> > user interrupt request register vector.
> >
> > gcc/
> >
> >         PR target/98219
> >         * config/i386/uintrintrin.h (__uintr_frame): Remove uirrv.
> >
> > gcc/testsuite/
> >
> >         PR target/98219
> >         * gcc.dg/guality/pr98219-1.c: New test.
> >         * gcc.dg/guality/pr98219-2.c: Likewise.
> >         * gcc.dg/torture/pr98219-1.c: Likewise.
> >         * gcc.dg/torture/pr98219-2.c: Likewise.
> >         * gcc.target/i386/uintr-2.c: Scan "add[lq] $8, %[er]sp".
> >         (foo): Add an unsigned long long argument.
> >         (UINTR_hanlder): Likewise.
> >         * gcc.target/i386/uintr-3.c: Scan "add[lq] $8, %[er]sp".
> >         (UINTR_hanlder): Add an unsigned long long argument.
> >         * gcc.target/i386/uintr-4.c (UINTR_hanlder): Likewise.
> >         * gcc.target/i386/uintr-5.c (UINTR_hanlder): Likewise.
>
> OK with the fixes, described inline.
>
> Thanks,
> Uros.
>
> > ---
> >  gcc/config/i386/uintrintrin.h            |  3 --
> >  gcc/testsuite/gcc.dg/guality/pr98219-1.c | 48 ++++++++++++++++++
> >  gcc/testsuite/gcc.dg/guality/pr98219-2.c | 63 ++++++++++++++++++++++++
> >  gcc/testsuite/gcc.dg/torture/pr98219-1.c | 44 +++++++++++++++++
> >  gcc/testsuite/gcc.dg/torture/pr98219-2.c | 59 ++++++++++++++++++++++
> >  gcc/testsuite/gcc.target/i386/uintr-2.c  |  5 +-
> >  gcc/testsuite/gcc.target/i386/uintr-3.c  |  4 +-
> >  gcc/testsuite/gcc.target/i386/uintr-4.c  |  4 +-
> >  gcc/testsuite/gcc.target/i386/uintr-5.c  |  2 +-
> >  9 files changed, 223 insertions(+), 9 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.dg/guality/pr98219-1.c
> >  create mode 100644 gcc/testsuite/gcc.dg/guality/pr98219-2.c
> >  create mode 100644 gcc/testsuite/gcc.dg/torture/pr98219-1.c
> >  create mode 100644 gcc/testsuite/gcc.dg/torture/pr98219-2.c
> >
> > diff --git a/gcc/config/i386/uintrintrin.h b/gcc/config/i386/uintrintrin.h
> > index 991f6427971..4606caf8582 100644
> > --- a/gcc/config/i386/uintrintrin.h
> > +++ b/gcc/config/i386/uintrintrin.h
> > @@ -38,9 +38,6 @@
> >
> >  struct __uintr_frame
> >  {
> > -  /* The position of the most significant bit set in user-interrupt
> > -     request register.  */
> > -  unsigned long long uirrv;
> >    /* RIP of the interrupted user process.  */
> >    unsigned long long rip;
> >    /* RFLAGS of the interrupted user process.  */
> > diff --git a/gcc/testsuite/gcc.dg/guality/pr98219-1.c b/gcc/testsuite/gcc.dg/guality/pr98219-1.c
> > new file mode 100644
> > index 00000000000..8d695080fd8
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/guality/pr98219-1.c
> > @@ -0,0 +1,48 @@
> > +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } */
>
> No need for extra curly braces after !, so:
>
> ... & { ! ia32 } ...
>
> here and in other tests.

Fixed.

> > +/* { dg-options "-g -muintr -mgeneral-regs-only" } */
> > +
> > +#include <x86gprintrin.h>
> > +
> > +extern void exit (int);
> > +
> > +#define UIRRV          0x12345670
> > +#define RIP            0x12345671
> > +#define RFLAGS         0x12345672
> > +#define RSP            0x12345673
> > +
> > +#define STRING(x)      XSTRING(x)
> > +#define XSTRING(x)     #x
> > +#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
> > +#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
> > +
> > +__attribute__((interrupt, used))
> > +void
> > +fn (struct __uintr_frame *frame, unsigned long long uirrv)
>
> Please define and use
>
> typedef unsigned int uword_t __attribute__ ((mode (__word__)));
>
> as is the case in interrupt-3.c. Also, the convention is:
>
> void
> __attribute_((...))
> fn (...)
>
> Please also fix in other tests.

Fixed.

> > +{
> > +  if (UIRRV != uirrv)          /* BREAK */
> > +    __builtin_abort ();
> > +  if (RIP != frame->rip)
> > +    __builtin_abort ();
> > +  if (RFLAGS != frame->rflags)
> > +    __builtin_abort ();
> > +  if (RSP != frame->rsp)
> > +    __builtin_abort ();
> > +
> > +  exit (0);
> > +}
> > +
> > +int
> > +main ()
> > +{
> > +  asm ("push   $" STRING (RSP) ";              \
> > +       push    $" STRING (RFLAGS) ";           \
> > +       push    $" STRING (RIP) ";              \
> > +       push    $" STRING (UIRRV) ";            \
> > +       jmp     " ASMNAME ("fn"));
> > +  return 0;
> > +}
> > +
> > +/* { dg-final { gdb-test 22 "uirrv" "0x12345670" } } */
> > +/* { dg-final { gdb-test 22 "frame->rip" "0x12345671" } } */
> > +/* { dg-final { gdb-test 22 "frame->rflags" "0x12345672" } } */
> > +/* { dg-final { gdb-test 22 "frame->rsp" "0x12345673" } } */
> > diff --git a/gcc/testsuite/gcc.dg/guality/pr98219-2.c b/gcc/testsuite/gcc.dg/guality/pr98219-2.c
> > new file mode 100644
> > index 00000000000..c0e48c981de
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/guality/pr98219-2.c
> > @@ -0,0 +1,63 @@
> > +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } */
> > +/* { dg-options "-g -muintr -mgeneral-regs-only" } */
> > +
> > +#include <x86gprintrin.h>
> > +
> > +extern void exit (int);
> > +typedef int aligned __attribute__((aligned(64)));
> > +
> > +#define UIRRV          0x12345670
> > +#define RIP            0x12345671
> > +#define RFLAGS         0x12345672
> > +#define RSP            0x12345673
> > +
> > +#define STRING(x)      XSTRING(x)
> > +#define XSTRING(x)     #x
> > +#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
> > +#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
> > +
> > +int
> > +check_int (int *i, int align)
> > +{
> > +  *i = 20;
> > +  if ((((ptrdiff_t) i) & (align - 1)) != 0)
> > +    __builtin_abort ();
> > +  return *i;
> > +}
> > +
> > +__attribute__((interrupt, used))
> > +__attribute__((interrupt, used))
>
> Two __attribute__s? Also, please follow convention as suggested above.

Fixed.

> > +void
> > +fn (struct __uintr_frame *frame, unsigned long long uirrv)
> > +{
> > +  aligned i;
> > +  if (check_int (&i, __alignof__(i)) != i)
> > +    __builtin_abort ();
> > +
> > +  if (UIRRV != uirrv)          /* BREAK */
> > +    __builtin_abort ();
> > +  if (RIP != frame->rip)
> > +    __builtin_abort ();
> > +  if (RFLAGS != frame->rflags)
> > +    __builtin_abort ();
> > +  if (RSP != frame->rsp)
> > +    __builtin_abort ();
> > +
> > +  exit (0);
> > +}
> > +
> > +int
> > +main ()
> > +{
> > +  asm ("push   $" STRING (RSP) ";              \
> > +       push    $" STRING (RFLAGS) ";           \
> > +       push    $" STRING (RIP) ";              \
> > +       push    $" STRING (UIRRV) ";            \
> > +       jmp     " ASMNAME ("fn"));
> > +  return 0;
> > +}
> > +
> > +/* { dg-final { gdb-test 34 "uirrv" "0x12345670" } } */
> > +/* { dg-final { gdb-test 34 "frame->rip" "0x12345671" } } */
> > +/* { dg-final { gdb-test 34 "frame->rflags" "0x12345672" } } */
> > +/* { dg-final { gdb-test 34 "frame->rsp" "0x12345673" } } */
> > diff --git a/gcc/testsuite/gcc.dg/torture/pr98219-1.c b/gcc/testsuite/gcc.dg/torture/pr98219-1.c
> > new file mode 100644
> > index 00000000000..c78495cc1c0
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/torture/pr98219-1.c
> > @@ -0,0 +1,44 @@
> > +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } */
> > +/* { dg-skip-if "PR81210 sp not aligned to 16 bytes" { *-*-darwin* } } */
> > +/* { dg-options "-muintr -mgeneral-regs-only" } */
> > +
> > +#include <x86gprintrin.h>
> > +
> > +extern void exit (int);
> > +
> > +#define UIRRV          0x12345670
> > +#define RIP            0x12345671
> > +#define RFLAGS         0x12345672
> > +#define RSP            0x12345673
> > +
> > +#define STRING(x)      XSTRING(x)
> > +#define XSTRING(x)     #x
> > +#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
> > +#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
> > +
> > +__attribute__((interrupt, used))
> > +void
> > +fn (struct __uintr_frame *frame, unsigned long long uirrv)
> > +{
> > +  if (UIRRV != uirrv)
> > +    __builtin_abort ();
> > +  if (RIP != frame->rip)
> > +    __builtin_abort ();
> > +  if (RFLAGS != frame->rflags)
> > +    __builtin_abort ();
> > +  if (RSP != frame->rsp)
> > +    __builtin_abort ();
> > +
> > +  exit (0);
> > +}
> > +
> > +int
> > +main ()
> > +{
> > +  asm ("push   $" STRING (RSP) ";              \
> > +       push    $" STRING (RFLAGS) ";           \
> > +       push    $" STRING (RIP) ";              \
> > +       push    $" STRING (UIRRV) ";            \
> > +       jmp     " ASMNAME ("fn"));
> > +  return 0;
> > +}
> > diff --git a/gcc/testsuite/gcc.dg/torture/pr98219-2.c b/gcc/testsuite/gcc.dg/torture/pr98219-2.c
> > new file mode 100644
> > index 00000000000..176fb78e42e
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/torture/pr98219-2.c
> > @@ -0,0 +1,59 @@
> > +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } */
> > +/* { dg-skip-if "PR81210 sp not aligned to 16 bytes" { *-*-darwin* } } */
> > +/* { dg-options "-muintr -mgeneral-regs-only" } */
> > +
> > +#include <x86gprintrin.h>
> > +
> > +extern void exit (int);
> > +typedef int aligned __attribute__((aligned(64)));
> > +
> > +#define UIRRV          0x12345670
> > +#define RIP            0x12345671
> > +#define RFLAGS         0x12345672
> > +#define RSP            0x12345673
> > +
> > +#define STRING(x)      XSTRING(x)
> > +#define XSTRING(x)     #x
> > +#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
> > +#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
> > +
> > +int
> > +check_int (int *i, int align)
> > +{
> > +  *i = 20;
> > +  if ((((ptrdiff_t) i) & (align - 1)) != 0)
> > +    __builtin_abort ();
> > +  return *i;
> > +}
> > +
> > +__attribute__((interrupt, used))
> > +__attribute__((interrupt, used))
> > +void
> > +fn (struct __uintr_frame *frame, unsigned long long uirrv)
> > +{
> > +  aligned i;
> > +  if (check_int (&i, __alignof__(i)) != i)
> > +    __builtin_abort ();
> > +
> > +  if (UIRRV != uirrv)
> > +    __builtin_abort ();
> > +  if (RIP != frame->rip)
> > +    __builtin_abort ();
> > +  if (RFLAGS != frame->rflags)
> > +    __builtin_abort ();
> > +  if (RSP != frame->rsp)
> > +    __builtin_abort ();
> > +
> > +  exit (0);
> > +}
> > +
> > +int
> > +main ()
> > +{
> > +  asm ("push   $" STRING (RSP) ";              \
> > +       push    $" STRING (RFLAGS) ";           \
> > +       push    $" STRING (RIP) ";              \
> > +       push    $" STRING (UIRRV) ";            \
> > +       jmp     " ASMNAME ("fn"));
> > +  return 0;
> > +}
> > diff --git a/gcc/testsuite/gcc.target/i386/uintr-2.c b/gcc/testsuite/gcc.target/i386/uintr-2.c
> > index e705732c1bd..2ff32640827 100644
> > --- a/gcc/testsuite/gcc.target/i386/uintr-2.c
> > +++ b/gcc/testsuite/gcc.target/i386/uintr-2.c
> > @@ -1,17 +1,18 @@
> >  /* { dg-do compile { target { ! ia32 } } } */
> >  /* { dg-options "-O2 -muintr -mgeneral-regs-only" } */
> >  /* { dg-final { scan-assembler-times "uiret" "2" } } */
> > +/* { dg-final { scan-assembler-times "add\[lq]\[ \t]\+\\\$8, %\[er\]sp" "2" } } */
> >
> >  #include <x86gprintrin.h>
> >
> >  void
> >  __attribute__((interrupt))
> > -foo (void *frame)
> > +foo (void *frame, unsigned long long uirrv)
> >  {
> >  }
> >
> >  void
> >  __attribute__((interrupt))
> > -UINTR_hanlder (struct __uintr_frame *frame)
> > +UINTR_hanlder (struct __uintr_frame *frame, unsigned long long uirrv)
> >  {
> >  }
> > diff --git a/gcc/testsuite/gcc.target/i386/uintr-3.c b/gcc/testsuite/gcc.target/i386/uintr-3.c
> > index d2843495158..0b925066668 100644
> > --- a/gcc/testsuite/gcc.target/i386/uintr-3.c
> > +++ b/gcc/testsuite/gcc.target/i386/uintr-3.c
> > @@ -1,9 +1,11 @@
> >  /* { dg-do compile { target { ! ia32 } } } */
> >  /* { dg-options "-O2 -muintr" } */
> >  /* { dg-final { scan-assembler "uiret" } } */
> > +/* { dg-final { scan-assembler "add\[lq]\[ \t]\+\\\$8, %\[er\]sp" } } */
> > +
> >  #include <x86gprintrin.h>
> >
> >  void __attribute__ ((target("general-regs-only"), interrupt))
> > -UINTR_handler (struct __uintr_frame *p)
> > +UINTR_handler (struct __uintr_frame *p, unsigned long long uirrv)
> >  {
> >  }
> > diff --git a/gcc/testsuite/gcc.target/i386/uintr-4.c b/gcc/testsuite/gcc.target/i386/uintr-4.c
> > index f3b371b4231..60478b126a7 100644
> > --- a/gcc/testsuite/gcc.target/i386/uintr-4.c
> > +++ b/gcc/testsuite/gcc.target/i386/uintr-4.c
> > @@ -4,6 +4,6 @@
> >  #include <x86gprintrin.h>
> >
> >  void __attribute__ ((interrupt))
> > -UINTR_handler (struct __uintr_frame *p)
> > -{ /* { dg-message "SSE instructions aren't allowed in an interrupt service routine" }  */
> > +UINTR_handler (struct __uintr_frame *p, unsigned long long uirrv)
> > +{ /* { dg-message "SSE instructions aren't allowed in an exception service routine" }  */
> >  }
> > diff --git a/gcc/testsuite/gcc.target/i386/uintr-5.c b/gcc/testsuite/gcc.target/i386/uintr-5.c
> > index ac44be0a706..d49e54d3134 100644
> > --- a/gcc/testsuite/gcc.target/i386/uintr-5.c
> > +++ b/gcc/testsuite/gcc.target/i386/uintr-5.c
> > @@ -5,6 +5,6 @@
> >  #include <x86gprintrin.h>
> >
> >  void
> > -UINTR_hanlder (struct __uintr_frame *frame)
> > +UINTR_hanlder (struct __uintr_frame *frame, unsigned long long uirrv)
> >  {
> >  }
> > --
> > 2.29.2
> >

Here is the updated patch I am checking in.

Thanks.

-- 
H.J.

[-- Attachment #2: 0001-x86-Update-user-interrupt-handler-stack-frame.patch --]
[-- Type: text/x-patch, Size: 11347 bytes --]

From 12456e259f2020c6258e02e08dcec6361e1822bf Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 9 Dec 2020 18:14:24 -0800
Subject: [PATCH] x86: Update user interrupt handler stack frame

User interrupt handler stack frame is similar to exception interrupt
handler stack frame.  Instead of error code, the second argument is
user interrupt request register vector.

gcc/

	PR target/98219
	* config/i386/uintrintrin.h (__uintr_frame): Remove uirrv.

gcc/testsuite/

	PR target/98219
	* gcc.dg/guality/pr98219-1.c: New test.
	* gcc.dg/guality/pr98219-2.c: Likewise.
	* gcc.dg/torture/pr98219-1.c: Likewise.
	* gcc.dg/torture/pr98219-2.c: Likewise.
	* gcc.target/i386/uintr-2.c: Scan "add[lq] $8, %[er]sp".
	(uword_t): New.
	(foo): Add a uword_t argument.
	(UINTR_hanlder): Likewise.
	* gcc.target/i386/uintr-3.c: Scan "add[lq] $8, %[er]sp".
	(uword_t): New.
	(UINTR_hanlder): Add a uword_t argument.
	* gcc.target/i386/uintr-4.c (uword_t): New.
	(UINTR_hanlder): Add a uword_t argument.
	* gcc.target/i386/uintr-5.c (uword_t): New.
	(UINTR_hanlder): Add a uword_t argument.
---
 gcc/config/i386/uintrintrin.h            |  3 --
 gcc/testsuite/gcc.dg/guality/pr98219-1.c | 49 ++++++++++++++++++
 gcc/testsuite/gcc.dg/guality/pr98219-2.c | 63 ++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/pr98219-1.c | 45 +++++++++++++++++
 gcc/testsuite/gcc.dg/torture/pr98219-2.c | 59 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/uintr-2.c  |  7 ++-
 gcc/testsuite/gcc.target/i386/uintr-3.c  |  6 ++-
 gcc/testsuite/gcc.target/i386/uintr-4.c  |  6 ++-
 gcc/testsuite/gcc.target/i386/uintr-5.c  |  4 +-
 9 files changed, 233 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/guality/pr98219-1.c
 create mode 100644 gcc/testsuite/gcc.dg/guality/pr98219-2.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr98219-1.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr98219-2.c

diff --git a/gcc/config/i386/uintrintrin.h b/gcc/config/i386/uintrintrin.h
index 991f6427971..4606caf8582 100644
--- a/gcc/config/i386/uintrintrin.h
+++ b/gcc/config/i386/uintrintrin.h
@@ -38,9 +38,6 @@
 
 struct __uintr_frame
 {
-  /* The position of the most significant bit set in user-interrupt
-     request register.  */
-  unsigned long long uirrv;
   /* RIP of the interrupted user process.  */
   unsigned long long rip;
   /* RFLAGS of the interrupted user process.  */
diff --git a/gcc/testsuite/gcc.dg/guality/pr98219-1.c b/gcc/testsuite/gcc.dg/guality/pr98219-1.c
new file mode 100644
index 00000000000..c9cb8a51b34
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr98219-1.c
@@ -0,0 +1,49 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! ia32 } } } } */
+/* { dg-options "-g -muintr -mgeneral-regs-only" } */
+
+#include <x86gprintrin.h>
+
+extern void exit (int);
+typedef unsigned int uword_t __attribute__ ((mode (__word__)));
+
+#define UIRRV		0x12345670
+#define RIP		0x12345671
+#define RFLAGS		0x12345672
+#define RSP		0x12345673
+
+#define STRING(x)	XSTRING(x)
+#define XSTRING(x)	#x
+#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
+
+void
+__attribute__((interrupt, used))
+fn (struct __uintr_frame *frame, uword_t uirrv)
+{
+  if (UIRRV != uirrv)		/* BREAK */
+    __builtin_abort ();
+  if (RIP != frame->rip)
+    __builtin_abort ();
+  if (RFLAGS != frame->rflags)
+    __builtin_abort ();
+  if (RSP != frame->rsp)
+    __builtin_abort ();
+
+  exit (0);
+}
+
+int
+main ()
+{
+  asm ("push	$" STRING (RSP) ";		\
+	push	$" STRING (RFLAGS) ";		\
+	push	$" STRING (RIP) ";		\
+	push	$" STRING (UIRRV) ";		\
+	jmp	" ASMNAME ("fn"));
+  return 0;
+}
+
+/* { dg-final { gdb-test 22 "uirrv" "0x12345670" } } */
+/* { dg-final { gdb-test 22 "frame->rip" "0x12345671" } } */
+/* { dg-final { gdb-test 22 "frame->rflags" "0x12345672" } } */
+/* { dg-final { gdb-test 22 "frame->rsp" "0x12345673" } } */
diff --git a/gcc/testsuite/gcc.dg/guality/pr98219-2.c b/gcc/testsuite/gcc.dg/guality/pr98219-2.c
new file mode 100644
index 00000000000..1f74eb3a82c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr98219-2.c
@@ -0,0 +1,63 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! ia32 } } } } */
+/* { dg-options "-g -muintr -mgeneral-regs-only" } */
+
+#include <x86gprintrin.h>
+
+extern void exit (int);
+typedef unsigned int uword_t __attribute__ ((mode (__word__)));
+typedef int aligned __attribute__((aligned(64)));
+
+#define UIRRV		0x12345670
+#define RIP		0x12345671
+#define RFLAGS		0x12345672
+#define RSP		0x12345673
+
+#define STRING(x)	XSTRING(x)
+#define XSTRING(x)	#x
+#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
+
+int
+check_int (int *i, int align)
+{
+  *i = 20;
+  if ((((ptrdiff_t) i) & (align - 1)) != 0)
+    __builtin_abort ();
+  return *i;
+}
+
+void
+__attribute__((interrupt, used))
+fn (struct __uintr_frame *frame, uword_t uirrv)
+{
+  aligned i;
+  if (check_int (&i, __alignof__(i)) != i)
+    __builtin_abort ();
+
+  if (UIRRV != uirrv)		/* BREAK */
+    __builtin_abort ();
+  if (RIP != frame->rip)
+    __builtin_abort ();
+  if (RFLAGS != frame->rflags)
+    __builtin_abort ();
+  if (RSP != frame->rsp)
+    __builtin_abort ();
+
+  exit (0);
+}
+
+int
+main ()
+{
+  asm ("push	$" STRING (RSP) ";		\
+	push	$" STRING (RFLAGS) ";		\
+	push	$" STRING (RIP) ";		\
+	push	$" STRING (UIRRV) ";		\
+	jmp	" ASMNAME ("fn"));
+  return 0;
+}
+
+/* { dg-final { gdb-test 34 "uirrv" "0x12345670" } } */
+/* { dg-final { gdb-test 34 "frame->rip" "0x12345671" } } */
+/* { dg-final { gdb-test 34 "frame->rflags" "0x12345672" } } */
+/* { dg-final { gdb-test 34 "frame->rsp" "0x12345673" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr98219-1.c b/gcc/testsuite/gcc.dg/torture/pr98219-1.c
new file mode 100644
index 00000000000..89b5aa3b9cb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr98219-1.c
@@ -0,0 +1,45 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! ia32 } } } } */
+/* { dg-skip-if "PR81210 sp not aligned to 16 bytes" { *-*-darwin* } } */
+/* { dg-options "-muintr -mgeneral-regs-only" } */
+
+#include <x86gprintrin.h>
+
+extern void exit (int);
+typedef unsigned int uword_t __attribute__ ((mode (__word__)));
+
+#define UIRRV		0x12345670
+#define RIP		0x12345671
+#define RFLAGS		0x12345672
+#define RSP		0x12345673
+
+#define STRING(x)	XSTRING(x)
+#define XSTRING(x)	#x
+#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
+
+void
+__attribute__((interrupt, used))
+fn (struct __uintr_frame *frame, uword_t uirrv)
+{
+  if (UIRRV != uirrv)
+    __builtin_abort ();
+  if (RIP != frame->rip)
+    __builtin_abort ();
+  if (RFLAGS != frame->rflags)
+    __builtin_abort ();
+  if (RSP != frame->rsp)
+    __builtin_abort ();
+
+  exit (0);
+}
+
+int
+main ()
+{
+  asm ("push	$" STRING (RSP) ";		\
+	push	$" STRING (RFLAGS) ";		\
+	push	$" STRING (RIP) ";		\
+	push	$" STRING (UIRRV) ";		\
+	jmp	" ASMNAME ("fn"));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr98219-2.c b/gcc/testsuite/gcc.dg/torture/pr98219-2.c
new file mode 100644
index 00000000000..c2f33f84f3e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr98219-2.c
@@ -0,0 +1,59 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! ia32 } } } } */
+/* { dg-skip-if "PR81210 sp not aligned to 16 bytes" { *-*-darwin* } } */
+/* { dg-options "-muintr -mgeneral-regs-only" } */
+
+#include <x86gprintrin.h>
+
+extern void exit (int);
+typedef unsigned int uword_t __attribute__ ((mode (__word__)));
+typedef int aligned __attribute__((aligned(64)));
+
+#define UIRRV		0x12345670
+#define RIP		0x12345671
+#define RFLAGS		0x12345672
+#define RSP		0x12345673
+
+#define STRING(x)	XSTRING(x)
+#define XSTRING(x)	#x
+#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+#define ASMNAME2(prefix, cname) XSTRING (prefix) cname
+
+int
+check_int (int *i, int align)
+{
+  *i = 20;
+  if ((((ptrdiff_t) i) & (align - 1)) != 0)
+    __builtin_abort ();
+  return *i;
+}
+
+void
+__attribute__((interrupt, used))
+fn (struct __uintr_frame *frame, uword_t uirrv)
+{
+  aligned i;
+  if (check_int (&i, __alignof__(i)) != i)
+    __builtin_abort ();
+
+  if (UIRRV != uirrv)
+    __builtin_abort ();
+  if (RIP != frame->rip)
+    __builtin_abort ();
+  if (RFLAGS != frame->rflags)
+    __builtin_abort ();
+  if (RSP != frame->rsp)
+    __builtin_abort ();
+
+  exit (0);
+}
+
+int
+main ()
+{
+  asm ("push	$" STRING (RSP) ";		\
+	push	$" STRING (RFLAGS) ";		\
+	push	$" STRING (RIP) ";		\
+	push	$" STRING (UIRRV) ";		\
+	jmp	" ASMNAME ("fn"));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/uintr-2.c b/gcc/testsuite/gcc.target/i386/uintr-2.c
index e705732c1bd..0a83c662b94 100644
--- a/gcc/testsuite/gcc.target/i386/uintr-2.c
+++ b/gcc/testsuite/gcc.target/i386/uintr-2.c
@@ -1,17 +1,20 @@
 /* { dg-do compile { target { ! ia32 } } } */
 /* { dg-options "-O2 -muintr -mgeneral-regs-only" } */
 /* { dg-final { scan-assembler-times "uiret" "2" } } */
+/* { dg-final { scan-assembler-times "add\[lq]\[ \t]\+\\\$8, %\[er\]sp" "2" } } */
 
 #include <x86gprintrin.h>
 
+typedef unsigned int uword_t __attribute__ ((mode (__word__)));
+
 void
 __attribute__((interrupt))
-foo (void *frame)
+foo (void *frame, uword_t uirrv)
 {
 }
 
 void
 __attribute__((interrupt))
-UINTR_hanlder (struct __uintr_frame *frame)
+UINTR_hanlder (struct __uintr_frame *frame, uword_t uirrv)
 {
 }
diff --git a/gcc/testsuite/gcc.target/i386/uintr-3.c b/gcc/testsuite/gcc.target/i386/uintr-3.c
index d2843495158..92476cfa45c 100644
--- a/gcc/testsuite/gcc.target/i386/uintr-3.c
+++ b/gcc/testsuite/gcc.target/i386/uintr-3.c
@@ -1,9 +1,13 @@
 /* { dg-do compile { target { ! ia32 } } } */
 /* { dg-options "-O2 -muintr" } */
 /* { dg-final { scan-assembler "uiret" } } */
+/* { dg-final { scan-assembler "add\[lq]\[ \t]\+\\\$8, %\[er\]sp" } } */
+
 #include <x86gprintrin.h>
 
+typedef unsigned int uword_t __attribute__ ((mode (__word__)));
+
 void __attribute__ ((target("general-regs-only"), interrupt))
-UINTR_handler (struct __uintr_frame *p)
+UINTR_handler (struct __uintr_frame *p, uword_t uirrv)
 {
 }
diff --git a/gcc/testsuite/gcc.target/i386/uintr-4.c b/gcc/testsuite/gcc.target/i386/uintr-4.c
index f3b371b4231..4d0ec34dfa0 100644
--- a/gcc/testsuite/gcc.target/i386/uintr-4.c
+++ b/gcc/testsuite/gcc.target/i386/uintr-4.c
@@ -3,7 +3,9 @@
 
 #include <x86gprintrin.h>
 
+typedef unsigned int uword_t __attribute__ ((mode (__word__)));
+
 void __attribute__ ((interrupt))
-UINTR_handler (struct __uintr_frame *p)
-{ /* { dg-message "SSE instructions aren't allowed in an interrupt service routine" }  */
+UINTR_handler (struct __uintr_frame *p, uword_t uirrv)
+{ /* { dg-message "SSE instructions aren't allowed in an exception service routine" }  */
 }
diff --git a/gcc/testsuite/gcc.target/i386/uintr-5.c b/gcc/testsuite/gcc.target/i386/uintr-5.c
index ac44be0a706..49cb2ec8097 100644
--- a/gcc/testsuite/gcc.target/i386/uintr-5.c
+++ b/gcc/testsuite/gcc.target/i386/uintr-5.c
@@ -4,7 +4,9 @@
 
 #include <x86gprintrin.h>
 
+typedef unsigned int uword_t __attribute__ ((mode (__word__)));
+
 void
-UINTR_hanlder (struct __uintr_frame *frame)
+UINTR_hanlder (struct __uintr_frame *frame, uword_t uirrv)
 {
 }
-- 
2.29.2


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-12-11 14:56 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-10 21:20 [PATCH] x86: Update user interrupt handler stack frame H.J. Lu
2020-12-10 21:57 ` Uros Bizjak
2020-12-11 14:55   ` V2 " H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).