slackbuilds_ponce/development/gcc5/patches/0007-x86-Add-mindirect-branch-register.diff
Eric Hameleers 786c4c9911 development/gcc5: update to 5.5.0
This re-aligns the gcc5.SlackBuild script with the latest
gcc.SlackBuild in Slackware 14.2.
Retpoline patches are included.

Signed-off-by: Eric Hameleers <alien@slackware.com>

Signed-off-by: Matteo Bernardini <ponce@slackbuilds.org>
2021-04-18 12:22:51 +02:00

812 lines
36 KiB
Diff

From 86118fbdbafe6af54b2da467e1073c49e1742116 Mon Sep 17 00:00:00 2001
From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 16 Jan 2018 11:17:49 +0000
Subject: [PATCH 7/9] x86: Add -mindirect-branch-register
Add -mindirect-branch-register to force indirect branch via register.
This is implemented by disabling patterns of indirect branch via memory,
similar to TARGET_X32.
-mindirect-branch= and -mfunction-return= tests are updated with
-mno-indirect-branch-register to avoid false test failures when
-mindirect-branch-register is added to RUNTESTFLAGS for "make check".
gcc/
Backport from mainline
2018-01-14 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/constraints.md (Bs): Disallow memory operand for
-mindirect-branch-register.
(Bw): Likewise.
* config/i386/predicates.md (indirect_branch_operand): Likewise.
(GOT_memory_operand): Likewise.
(call_insn_operand): Likewise.
(sibcall_insn_operand): Likewise.
(GOT32_symbol_operand): Likewise.
* config/i386/i386.md (indirect_jump): Call convert_memory_address
for -mindirect-branch-register.
(tablejump): Likewise.
(*sibcall_memory): Likewise.
(*sibcall_value_memory): Likewise.
Disallow peepholes of indirect call and jump via memory for
-mindirect-branch-register.
(*call_pop): Replace m with Bw.
(*call_value_pop): Likewise.
(*sibcall_pop_memory): Replace m with Bs.
* config/i386/i386.opt (mindirect-branch-register): New option.
* doc/invoke.texi: Document -mindirect-branch-register option.
gcc/testsuite/
Backport from mainline
2018-01-14 H.J. Lu <hongjiu.lu@intel.com>
* gcc.target/i386/indirect-thunk-1.c (dg-options): Add
-mno-indirect-branch-register.
* gcc.target/i386/indirect-thunk-2.c: Likewise.
* gcc.target/i386/indirect-thunk-3.c: Likewise.
* gcc.target/i386/indirect-thunk-4.c: Likewise.
* gcc.target/i386/indirect-thunk-5.c: Likewise.
* gcc.target/i386/indirect-thunk-6.c: Likewise.
* gcc.target/i386/indirect-thunk-7.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-1.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-2.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-3.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-4.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-5.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-6.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-7.c: Likewise.
* gcc.target/i386/indirect-thunk-bnd-1.c: Likewise.
* gcc.target/i386/indirect-thunk-bnd-2.c: Likewise.
* gcc.target/i386/indirect-thunk-bnd-3.c: Likewise.
* gcc.target/i386/indirect-thunk-bnd-4.c: Likewise.
* gcc.target/i386/indirect-thunk-extern-1.c: Likewise.
* gcc.target/i386/indirect-thunk-extern-2.c: Likewise.
* gcc.target/i386/indirect-thunk-extern-3.c: Likewise.
* gcc.target/i386/indirect-thunk-extern-4.c: Likewise.
* gcc.target/i386/indirect-thunk-extern-5.c: Likewise.
* gcc.target/i386/indirect-thunk-extern-6.c: Likewise.
* gcc.target/i386/indirect-thunk-extern-7.c: Likewise.
* gcc.target/i386/indirect-thunk-inline-1.c: Likewise.
* gcc.target/i386/indirect-thunk-inline-2.c: Likewise.
* gcc.target/i386/indirect-thunk-inline-3.c: Likewise.
* gcc.target/i386/indirect-thunk-inline-4.c: Likewise.
* gcc.target/i386/indirect-thunk-inline-5.c: Likewise.
* gcc.target/i386/indirect-thunk-inline-6.c: Likewise.
* gcc.target/i386/indirect-thunk-inline-7.c: Likewise.
* gcc.target/i386/ret-thunk-10.c: Likewise.
* gcc.target/i386/ret-thunk-11.c: Likewise.
* gcc.target/i386/ret-thunk-12.c: Likewise.
* gcc.target/i386/ret-thunk-13.c: Likewise.
* gcc.target/i386/ret-thunk-14.c: Likewise.
* gcc.target/i386/ret-thunk-15.c: Likewise.
* gcc.target/i386/ret-thunk-9.c: Likewise.
* gcc.target/i386/indirect-thunk-register-1.c: New test.
* gcc.target/i386/indirect-thunk-register-2.c: Likewise.
* gcc.target/i386/indirect-thunk-register-3.c: Likewise.
i386: Rename to ix86_indirect_branch_register
Rename the variable for -mindirect-branch-register to
ix86_indirect_branch_register to match the command-line option name.
Backport from mainline
2018-01-15 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/constraints.md (Bs): Replace
ix86_indirect_branch_thunk_register with
ix86_indirect_branch_register.
(Bw): Likewise.
* config/i386/i386.md (indirect_jump): Likewise.
(tablejump): Likewise.
(*sibcall_memory): Likewise.
(*sibcall_value_memory): Likewise.
Peepholes of indirect call and jump via memory: Likewise.
* config/i386/i386.opt: Likewise.
* config/i386/predicates.md (indirect_branch_operand): Likewise.
(GOT_memory_operand): Likewise.
(call_insn_operand): Likewise.
(sibcall_insn_operand): Likewise.
(GOT32_symbol_operand): Likewise.
x86: Rewrite ix86_indirect_branch_register logic
Rewrite ix86_indirect_branch_register logic with
(and (not (match_test "ix86_indirect_branch_register"))
(original condition before r256662))
Backport from mainline
2018-01-15 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/predicates.md (constant_call_address_operand):
Rewrite ix86_indirect_branch_register logic.
(sibcall_insn_operand): Likewise.
Don't check ix86_indirect_branch_register for GOT operand
Since GOT_memory_operand and GOT32_symbol_operand are simple pattern
matches, don't check ix86_indirect_branch_register here. If needed,
-mindirect-branch= will convert indirect branch via GOT slot to a call
and return thunk.
Backport from mainline
2018-01-15 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/constraints.md (Bs): Update
ix86_indirect_branch_register check. Don't check
ix86_indirect_branch_register with GOT_memory_operand.
(Bw): Likewise.
* config/i386/predicates.md (GOT_memory_operand): Don't check
ix86_indirect_branch_register here.
(GOT32_symbol_operand): Likewise.
i386: Rewrite indirect_branch_operand logic
Backport from mainline
2018-01-15 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/predicates.md (indirect_branch_operand): Rewrite
ix86_indirect_branch_register logic.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256735 138bc75d-0d04-0410-961f-82ee72b054a4
[Ubuntu note: Dropped indirect-thunk-5.c, indirect-thunk-6.c,
indirect-thunk-bnd-3.c, indirect-thunk-bnd-4.c,
indirect-thunk-extern-5.c, indirect-thunk-extern-6.c,
indirect-thunk-inline-5.c, and indirect-thunk-inline-6.c tests due
to gcc 5.4 and earlier not supporting the -fno-plt option.
--sbeattie,]
---
src/gcc/config/i386/constraints.md | 6 +
src/gcc/config/i386/i386.md | 34 ++++++----
src/gcc/config/i386/i386.opt | 4 +
src/gcc/config/i386/predicates.md | 9 +-
src/gcc/doc/invoke.texi | 7 +-
src/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c | 22 ++++++
src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c | 20 +++++
src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c | 19 +++++
src/gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 2
src/gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 2
src/gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 2
src/gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 2
src/gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 2
src/gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 2
src/gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 2
39 files changed, 134 insertions(+), 49 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
Index: b/src/gcc/config/i386/constraints.md
===================================================================
--- a/src/gcc/config/i386/constraints.md
+++ b/src/gcc/config/i386/constraints.md
@@ -157,12 +157,14 @@
(define_constraint "Bs"
"@internal Sibcall memory operand."
- (and (not (match_test "TARGET_X32"))
+ (and (not (match_test "ix86_indirect_branch_register"))
+ (not (match_test "TARGET_X32"))
(match_operand 0 "sibcall_memory_operand")))
(define_constraint "Bw"
"@internal Call memory operand."
- (and (not (match_test "TARGET_X32"))
+ (and (not (match_test "ix86_indirect_branch_register"))
+ (not (match_test "TARGET_X32"))
(match_operand 0 "memory_operand")))
(define_constraint "Bz"
Index: b/src/gcc/config/i386/i386.md
===================================================================
--- a/src/gcc/config/i386/i386.md
+++ b/src/gcc/config/i386/i386.md
@@ -11554,7 +11554,7 @@
[(set (pc) (match_operand 0 "indirect_branch_operand"))]
""
{
- if (TARGET_X32)
+ if (TARGET_X32 || ix86_indirect_branch_register)
operands[0] = convert_memory_address (word_mode, operands[0]);
cfun->machine->has_local_indirect_jump = true;
})
@@ -11607,7 +11607,7 @@
OPTAB_DIRECT);
}
- if (TARGET_X32)
+ if (TARGET_X32 || ix86_indirect_branch_register)
operands[0] = convert_memory_address (word_mode, operands[0]);
cfun->machine->has_local_indirect_jump = true;
})
@@ -11764,7 +11764,7 @@
[(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
(match_operand 1))
(unspec [(const_int 0)] UNSPEC_PEEPSIB)]
- "!TARGET_X32"
+ "!TARGET_X32 && !ix86_indirect_branch_register"
"* return ix86_output_call_insn (insn, operands[0]);"
[(set_attr "type" "call")])
@@ -11773,7 +11773,9 @@
(match_operand:W 1 "memory_operand"))
(call (mem:QI (match_dup 0))
(match_operand 3))]
- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
+ "!TARGET_X32
+ && !ix86_indirect_branch_register
+ && SIBLING_CALL_P (peep2_next_insn (1))
&& peep2_reg_dead_p (2, operands[0])"
[(parallel [(call (mem:QI (match_dup 1))
(match_dup 3))
@@ -11785,7 +11787,9 @@
(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(call (mem:QI (match_dup 0))
(match_operand 3))]
- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
+ "!TARGET_X32
+ && !ix86_indirect_branch_register
+ && SIBLING_CALL_P (peep2_next_insn (2))
&& peep2_reg_dead_p (3, operands[0])"
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(parallel [(call (mem:QI (match_dup 1))
@@ -11806,7 +11810,7 @@
})
(define_insn "*call_pop"
- [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
+ [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
(match_operand 1))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
@@ -11826,7 +11830,7 @@
[(set_attr "type" "call")])
(define_insn "*sibcall_pop_memory"
- [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
+ [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
(match_operand 1))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
@@ -11878,7 +11882,9 @@
[(set (match_operand:W 0 "register_operand")
(match_operand:W 1 "memory_operand"))
(set (pc) (match_dup 0))]
- "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
+ "!TARGET_X32
+ && !ix86_indirect_branch_register
+ && peep2_reg_dead_p (2, operands[0])"
[(set (pc) (match_dup 1))])
;; Call subroutine, returning value in operand 0
@@ -11928,7 +11934,7 @@
(call (mem:QI (match_operand:W 1 "memory_operand" "m"))
(match_operand 2)))
(unspec [(const_int 0)] UNSPEC_PEEPSIB)]
- "!TARGET_X32"
+ "!TARGET_X32 && !ix86_indirect_branch_register"
"* return ix86_output_call_insn (insn, operands[1]);"
[(set_attr "type" "callv")])
@@ -11938,7 +11944,9 @@
(set (match_operand 2)
(call (mem:QI (match_dup 0))
(match_operand 3)))]
- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
+ "!TARGET_X32
+ && !ix86_indirect_branch_register
+ && SIBLING_CALL_P (peep2_next_insn (1))
&& peep2_reg_dead_p (2, operands[0])"
[(parallel [(set (match_dup 2)
(call (mem:QI (match_dup 1))
@@ -11952,7 +11960,9 @@
(set (match_operand 2)
(call (mem:QI (match_dup 0))
(match_operand 3)))]
- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
+ "!TARGET_X32
+ && !ix86_indirect_branch_register
+ && SIBLING_CALL_P (peep2_next_insn (2))
&& peep2_reg_dead_p (3, operands[0])"
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(parallel [(set (match_dup 2)
@@ -11976,7 +11986,7 @@
(define_insn "*call_value_pop"
[(set (match_operand 0)
- (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
+ (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
(match_operand 2)))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
Index: b/src/gcc/config/i386/i386.opt
===================================================================
--- a/src/gcc/config/i386/i386.opt
+++ b/src/gcc/config/i386/i386.opt
@@ -900,3 +900,7 @@ Enum(indirect_branch) String(thunk-inlin
EnumValue
Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)
+
+mindirect-branch-register
+Target Report Var(ix86_indirect_branch_register) Init(0)
+Force indirect call and jump via register.
Index: b/src/gcc/config/i386/predicates.md
===================================================================
--- a/src/gcc/config/i386/predicates.md
+++ b/src/gcc/config/i386/predicates.md
@@ -607,7 +607,8 @@
;; Test for a valid operand for indirect branch.
(define_predicate "indirect_branch_operand"
(ior (match_operand 0 "register_operand")
- (and (not (match_test "TARGET_X32"))
+ (and (not (match_test "ix86_indirect_branch_register"))
+ (not (match_test "TARGET_X32"))
(match_operand 0 "memory_operand"))))
;; Test for a valid operand for a call instruction.
@@ -616,7 +617,8 @@
(ior (match_test "constant_call_address_operand
(op, mode == VOIDmode ? mode : Pmode)")
(match_operand 0 "call_register_no_elim_operand")
- (and (not (match_test "TARGET_X32"))
+ (and (not (match_test "ix86_indirect_branch_register"))
+ (not (match_test "TARGET_X32"))
(match_operand 0 "memory_operand"))))
;; Similarly, but for tail calls, in which we cannot allow memory references.
@@ -624,7 +626,8 @@
(ior (match_test "constant_call_address_operand
(op, mode == VOIDmode ? mode : Pmode)")
(match_operand 0 "register_no_elim_operand")
- (and (not (match_test "TARGET_X32"))
+ (and (not (match_test "ix86_indirect_branch_register"))
+ (not (match_test "TARGET_X32"))
(match_operand 0 "sibcall_memory_operand"))))
;; Match exactly zero.
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
void func0 (void);
void func1 (void);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
void func0 (void);
void func1 (void);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target { ! x32 } } } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */
void (*dispatch) (char *);
char buf[10];
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target { ! x32 } } } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */
void (*dispatch) (char *);
char buf[10];
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
void func0 (void);
void func1 (void);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
void func0 (void);
void func1 (void);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
===================================================================
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-register -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
+/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk\n" } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk_bnd\n" } } */
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
===================================================================
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-register -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
+/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
===================================================================
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-register -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
+/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
+/* { dg-final { scan-assembler-not {\t(pause|pause|nop)} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
Index: b/src/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */
extern void (*bar) (void);
Index: b/src/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */
extern void (*bar) (void);
Index: b/src/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
extern void (*bar) (void);
Index: b/src/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
extern void (*bar) (void);
extern int foo (void) __attribute__ ((function_return("thunk")));
Index: b/src/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
extern void (*bar) (void);
Index: b/src/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */
extern void (*bar) (void);
Index: b/src/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */
extern void (*bar) (void);