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

Reply via email to