x86: Update user interrupt handler stack frame
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 10 Dec 2020 02:14:24 +0000 (18:14 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 11 Dec 2020 14:55:58 +0000 (06:55 -0800)
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
gcc/testsuite/gcc.dg/guality/pr98219-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/guality/pr98219-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr98219-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr98219-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/uintr-2.c
gcc/testsuite/gcc.target/i386/uintr-3.c
gcc/testsuite/gcc.target/i386/uintr-4.c
gcc/testsuite/gcc.target/i386/uintr-5.c

index 991f64279716a239b1aa18ca83b02a95bb0161f3..4606caf8582d17773032fa3348d4e65ec398efab 100644 (file)
@@ -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 (file)
index 0000000..c9cb8a5
--- /dev/null
@@ -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 (file)
index 0000000..1f74eb3
--- /dev/null
@@ -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 (file)
index 0000000..89b5aa3
--- /dev/null
@@ -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 (file)
index 0000000..c2f33f8
--- /dev/null
@@ -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;
+}
index e705732c1bd5504fe7dfdb98d4c7a651324a22c8..0a83c662b949535b187469646afb1597e94188c4 100644 (file)
@@ -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)
 {
 }
index d2843495158ef4c952c2c6c316d7dd5ad3577b7c..92476cfa45c12d0857aa083bffa0c9ddbc699fbe 100644 (file)
@@ -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)
 {
 }
index f3b371b423155a977debca99702f276fa9926ce4..4d0ec34dfa0f18c12fa84a05e048d47f94ee5ebe 100644 (file)
@@ -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" }  */
 }
index ac44be0a7064694f03e7c26f8f07e3db1635624b..49cb2ec8097cc335158f880e1728679a310ea2f6 100644 (file)
@@ -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)
 {
 }