On Thu, Dec 10, 2020 at 1:57 PM Uros Bizjak <ubiz...@gmail.com> wrote: > > On Thu, Dec 10, 2020 at 10:20 PM H.J. Lu <hjl.to...@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.
From 12456e259f2020c6258e02e08dcec6361e1822bf Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <hjl.to...@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