aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2020-12-09 18:14:24 -0800
committerH.J. Lu <hjl.tools@gmail.com>2020-12-11 06:55:58 -0800
commit078c7498908d9b74caff34d12099b5c85470e277 (patch)
tree24f3776c19e7439923f79d071624cf1ead4c1a72
parent97b56dece74138398977ea53368a025ed231b35c (diff)
downloadgcc-078c7498908d9b74caff34d12099b5c85470e277.zip
gcc-078c7498908d9b74caff34d12099b5c85470e277.tar.gz
gcc-078c7498908d9b74caff34d12099b5c85470e277.tar.bz2
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.
-rw-r--r--gcc/config/i386/uintrintrin.h3
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr98219-1.c49
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr98219-2.c63
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr98219-1.c45
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr98219-2.c59
-rw-r--r--gcc/testsuite/gcc.target/i386/uintr-2.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/uintr-3.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/uintr-4.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/uintr-5.c4
9 files changed, 233 insertions, 9 deletions
diff --git a/gcc/config/i386/uintrintrin.h b/gcc/config/i386/uintrintrin.h
index 991f642..4606caf 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 0000000..c9cb8a5
--- /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 0000000..1f74eb3
--- /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 0000000..89b5aa3
--- /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 0000000..c2f33f8
--- /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 e705732..0a83c66 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 d284349..92476cf 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 f3b371b..4d0ec34 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 ac44be0..49cb2ec 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)
{
}