diff options
author | Christoph Muellner <christoph.muellner@theobroma-systems.com> | 2018-03-02 17:09:19 +0100 |
---|---|---|
committer | Christoph Muellner <christoph.muellner@theobroma-systems.com> | 2018-05-17 16:17:01 +0200 |
commit | 6b78b2be7018174f49e11a15aa5401b87a72fbbb (patch) | |
tree | 83fe33e15e2f43067e2ad95295965f94508bb63c /gcc/testsuite/gcc.target/aarch64 | |
parent | 0dbcf2c2b2e4e778d17fddc22b6a5c0b500fff50 (diff) |
aarch64: Retpoline (Spectre-V2 mitigation) for aarch64.master-dbcf2c2b2e
The compiler option -mindirect-branch=<value> converts indirect
branch-and-link-register and branch-register instructions according to <value>.
The default is ``keep``, which keeps indirect branch-and-link-register and
branch-register instructions unmodified.
``thunk`` converts indirect branch-and-link-register/branch-register
instructions to a branch-and-link/branch to a function containing a retpoline
(to stop speculative execution) followed by a branch-register to the target.
``thunk-inline`` is similar to ``thunk``, but inlines the retpoline
before the branch-and-link-register/branch-register instruction.
``thunk-extern`` is also similar to ``thunk``, but does not insert the
functions containing the retpoline. When using this option, these functions
need to be provided in a separate object file. The retpoline functions exist
for each register and are named ``__aarch64_indirect_thunk_xN`` (N being the
register number).
It is also possible to override the indirect-branch setting for
individual fuctions using the function attribute ``indirect_branch``.
The actual retpoline instruction sequence, which prevents speculative
indirect branches looks like this::
str x30, [sp, #-16]!
bl 101f
100: //speculation trap
wfe
b 100b
101: //do ROP
adr x30, 102f
ret
102: //non-spec code
ldr x30, [sp], #16
This patch has been tested with the included testcases and various other
source bases (benchmarks, retpoline-patched arm64 kernel, etc.).
Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Diffstat (limited to 'gcc/testsuite/gcc.target/aarch64')
24 files changed, 599 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-1.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-1.c new file mode 100644 index 000000000000..c5bd82a56d90 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-1.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch; + +void +male_indirect_jump (long offset) +{ + dispatch(offset); +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, #:lo12:dispatch\\\]" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*__aarch64_indirect_thunk_x1" } } */ + +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "br\[ \t\]*x1" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-2.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-2.c new file mode 100644 index 000000000000..0107bbd9559d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-2.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch[256]; + +void +male_indirect_jump (long offset) +{ + dispatch[offset](offset); +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "add\[ \t\]*x1, x1, :lo12:dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, x0, lsl 3\\\]" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*__aarch64_indirect_thunk_x1" } } */ + +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "br\[ \t\]*x1" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-3.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-3.c new file mode 100644 index 000000000000..d9b5cfed19b2 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-3.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch; + +int +male_indirect_jump (long offset) +{ + dispatch(offset); + return 0; +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, #:lo12:dispatch\\\]" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*__aarch64_indirect_thunk_x1" } } */ + +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "br\[ \t\]*x1" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-4.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-4.c new file mode 100644 index 000000000000..b89f333457c7 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-4.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch[256]; + +int +male_indirect_jump (long offset) +{ + dispatch[offset](offset); + return 0; +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "add\[ \t\]*x1, x1, :lo12:dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, x0, lsl 3\\\]" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*__aarch64_indirect_thunk_x1" } } */ + +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "br\[ \t\]*x1" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-5.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-5.c new file mode 100644 index 000000000000..eb7ccda2ae66 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-5.c @@ -0,0 +1,25 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ + +extern void bar (void); + +void +foo (void) +{ + bar (); +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x0, _GLOBAL_OFFSET_TABLE_" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x0, \\\[x0, #:gotpage_lo15:bar\\\]" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*__aarch64_indirect_thunk_x0" } } */ + +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "br\[ \t\]*x0" } } */ + +/* { dg-final { scan-assembler-not "__aarch64_indirect_thunk\n" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-6.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-6.c new file mode 100644 index 000000000000..4c21735dc3c8 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-6.c @@ -0,0 +1,26 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ + +extern void bar (void); + +int +foo (void) +{ + bar (); + return 0; +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x0, _GLOBAL_OFFSET_TABLE_" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x0, \\\[x0, #:gotpage_lo15:bar\\\]" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*__aarch64_indirect_thunk_x0" } } */ + +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "br\[ \t\]*x0" } } */ + +/* { dg-final { scan-assembler-not "__aarch64_indirect_thunk\n" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-1.c new file mode 100644 index 000000000000..2485e9248910 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-1.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch; + +extern void male_indirect_jump (long) + __attribute__ ((indirect_branch("thunk"))); + +void +male_indirect_jump (long offset) +{ + dispatch(offset); +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, #:lo12:dispatch\\\]" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*__aarch64_indirect_thunk_x1" } } */ + +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "br\[ \t\]*x1" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-2.c new file mode 100644 index 000000000000..8e9425294b6e --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-2.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch[256]; + +__attribute__ ((indirect_branch("thunk"))) +void +male_indirect_jump (long offset) +{ + dispatch[offset](offset); +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "add\[ \t\]*x1, x1, :lo12:dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, x0, lsl 3\\\]" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*__aarch64_indirect_thunk_x1" } } */ + +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "br\[ \t\]*x1" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-3.c new file mode 100644 index 000000000000..47005c96d098 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-3.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch; +extern int male_indirect_jump (long) + __attribute__ ((indirect_branch("thunk-inline"))); + +int +male_indirect_jump (long offset) +{ + dispatch(offset); + return 0; +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, #:lo12:dispatch\\\]" } } */ +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "blr\[ \t\]*x1" } } */ + +/* { dg-final { scan-assembler-not "__aarch64_indirect_thunk" } } */ + diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-4.c new file mode 100644 index 000000000000..4ad462f7efa2 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-4.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch[256]; + +__attribute__ ((indirect_branch("thunk-inline"))) +int +male_indirect_jump (long offset) +{ + dispatch[offset](offset); + return 0; +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "add\[ \t\]*x1, x1, :lo12:dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, x0, lsl 3\\\]" } } */ +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "blr\[ \t\]*x1" } } */ + +/* { dg-final { scan-assembler-not "__aarch64_indirect_thunk" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-5.c new file mode 100644 index 000000000000..178ce26ff25f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-5.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch; +extern int male_indirect_jump (long) + __attribute__ ((indirect_branch("thunk-extern"))); + +int +male_indirect_jump (long offset) +{ + dispatch(offset); + return 0; +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, #:lo12:dispatch\\\]" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*__aarch64_indirect_thunk_x1" } } */ + +/* { dg-final { scan-assembler-not "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler-not "wfe" } } */ +/* { dg-final { scan-assembler-not "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler-not "adr\[ \t\]*x30, .LIND2" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-6.c new file mode 100644 index 000000000000..75964a058391 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-attr-6.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch[256]; + +__attribute__ ((indirect_branch("thunk-extern"))) +int +male_indirect_jump (long offset) +{ + dispatch[offset](offset); + return 0; +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "add\[ \t\]*x1, x1, :lo12:dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, x0, lsl 3\\\]" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*__aarch64_indirect_thunk_x1" } } */ + +/* { dg-final { scan-assembler-not "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler-not "wfe" } } */ +/* { dg-final { scan-assembler-not "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler-not "adr\[ \t\]*x30, .LIND2" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-1.c new file mode 100644 index 000000000000..da4936d7b99c --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-1.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch; + +void +male_indirect_jump (long offset) +{ + dispatch(offset); +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, #:lo12:dispatch\\\]" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*__aarch64_indirect_thunk_x1" } } */ + +/* { dg-final { scan-assembler-not "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler-not "wfe" } } */ +/* { dg-final { scan-assembler-not "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler-not "adrp\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler-not "add\[ \t\]*x30, x30, :lo12:.LIND2" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-2.c new file mode 100644 index 000000000000..b7a6a693ebea --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-2.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch[256]; + +void +male_indirect_jump (long offset) +{ + dispatch[offset](offset); +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "add\[ \t\]*x1, x1, :lo12:dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, x0, lsl 3\\\]" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*__aarch64_indirect_thunk_x1" } } */ + +/* { dg-final { scan-assembler-not "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler-not "wfe" } } */ +/* { dg-final { scan-assembler-not "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler-not "adrp\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler-not "add\[ \t\]*x30, x30, :lo12:.LIND2" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-3.c new file mode 100644 index 000000000000..d4143b173612 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-3.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch; + +int +male_indirect_jump (long offset) +{ + dispatch(offset); + return 0; +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, #:lo12:dispatch\\\]" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*__aarch64_indirect_thunk_x1" } } */ + +/* { dg-final { scan-assembler-not "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler-not "wfe" } } */ +/* { dg-final { scan-assembler-not "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler-not "adrp\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler-not "add\[ \t\]*x30, x30, :lo12:.LIND2" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-4.c new file mode 100644 index 000000000000..f488a719f2a1 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-4.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch[256]; + +int +male_indirect_jump (long offset) +{ + dispatch[offset](offset); + return 0; +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "add\[ \t\]*x1, x1, :lo12:dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, x0, lsl 3\\\]" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*__aarch64_indirect_thunk_x1" } } */ + +/* { dg-final { scan-assembler-not "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler-not "wfe" } } */ +/* { dg-final { scan-assembler-not "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler-not "adrp\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler-not "add\[ \t\]*x30, x30, :lo12:.LIND2" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-5.c new file mode 100644 index 000000000000..d20a668121a0 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-5.c @@ -0,0 +1,20 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ + +extern void bar (void); + +void +foo (void) +{ + bar (); +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x0, _GLOBAL_OFFSET_TABLE_" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x0, \\\[x0, #:gotpage_lo15:bar\\\]" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*__aarch64_indirect_thunk_x0" } } */ + +/* { dg-final { scan-assembler-not "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler-not "wfe" } } */ +/* { dg-final { scan-assembler-not "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler-not "adrp\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler-not "add\[ \t\]*x30, x30, :lo12:.LIND2" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-6.c new file mode 100644 index 000000000000..635b53b35b90 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-extern-6.c @@ -0,0 +1,21 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ + +extern void bar (void); + +int +foo (void) +{ + bar (); + return 0; +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x0, _GLOBAL_OFFSET_TABLE_" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x0, \\\[x0, #:gotpage_lo15:bar\\\]" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*__aarch64_indirect_thunk_x0" } } */ + +/* { dg-final { scan-assembler-not "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler-not "wfe" } } */ +/* { dg-final { scan-assembler-not "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler-not "adrp\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler-not "add\[ \t\]*x30, x30, :lo12:.LIND2" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-1.c new file mode 100644 index 000000000000..4c94efc8121f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-1.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch; + +void +male_indirect_jump (long offset) +{ + dispatch(offset); +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, #:lo12:dispatch\\\]" } } */ +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "br\[ \t\]*x1" } } */ + +/* { dg-final { scan-assembler-not "__aarch64_indirect_thunk" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-2.c new file mode 100644 index 000000000000..3c5c263b5e6f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-2.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch[256]; + +void +male_indirect_jump (long offset) +{ + dispatch[offset](offset); +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "add\[ \t\]*x1, x1, :lo12:dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, x0, lsl 3\\\]" } } */ +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "br\[ \t\]*x1" } } */ + +/* { dg-final { scan-assembler-not "__aarch64_indirect_thunk" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-3.c new file mode 100644 index 000000000000..cd09d78b082b --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-3.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch; + +int +male_indirect_jump (long offset) +{ + dispatch(offset); + return 0; +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, #:lo12:dispatch\\\]" } } */ +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "blr\[ \t\]*x1" } } */ + +/* { dg-final { scan-assembler-not "__aarch64_indirect_thunk" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-4.c new file mode 100644 index 000000000000..45b33ac9c02c --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-4.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch[256]; + +int +male_indirect_jump (long offset) +{ + dispatch[offset](offset); + return 0; +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "add\[ \t\]*x1, x1, :lo12:dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, x0, lsl 3\\\]" } } */ +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "blr\[ \t\]*x1" } } */ + +/* { dg-final { scan-assembler-not "__aarch64_indirect_thunk" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-5.c new file mode 100644 index 000000000000..28b4c87b80af --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-5.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ + +extern void bar (void); + +void +foo (void) +{ + bar (); +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x0, _GLOBAL_OFFSET_TABLE_" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x0, \\\[x0, #:gotpage_lo15:bar\\\]" } } */ +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "br\[ \t\]*x0" } } */ + +/* { dg-final { scan-assembler-not "__aarch64_indirect_thunk\n" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-6.c new file mode 100644 index 000000000000..9cedefadd8d6 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-6.c @@ -0,0 +1,24 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ + +extern void bar (void); + +int +foo (void) +{ + bar (); + return 0; +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x0, _GLOBAL_OFFSET_TABLE_" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x0, \\\[x0, #:gotpage_lo15:bar\\\]" } } */ +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "blr\[ \t\]*x0" } } */ + +/* { dg-final { scan-assembler-not "__aarch64_indirect_thunk\n" } } */ |