[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[bug#30111] gnu: address@hidden: Apply the 'retpoline' mitigation techni
From: |
Alex Vong |
Subject: |
[bug#30111] gnu: address@hidden: Apply the 'retpoline' mitigation technique. |
Date: |
Sun, 14 Jan 2018 21:07:17 +0800 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) |
Hello,
This patch adds the repoline patches (totally 17 of them) taken from the
'retpoline-20180107' branch at
``http://git.infradead.org/users/dwmw2/gcc-retpoline.git'' to address@hidden
Last time it builds fine on my laptop. I am now re-building since I add
some comments on the patches. I will reply asap if anything goes wrong
with the re-build.
>From 5be54f7ebe9b0ab6dc65ea974584be0850604b14 Mon Sep 17 00:00:00 2001
From: Alex Vong <address@hidden>
Date: Sun, 14 Jan 2018 20:12:19 +0800
Subject: [PATCH] gnu: address@hidden: Apply the 'retpoline' mitigation
technique.
This is part of Spectre (branch target injection) [CVE-2017-5715]
mitigation. Suggested by Mark H Weaver <address@hidden>.
* gnu/local.mk (dist_patch_DATA): Add them.
* gnu/packages/gcc.scm (address@hidden): Use them.
*
gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch,
gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch,
gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch,
gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch,
gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch,
gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch,
gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch,
gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch,
gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch,
gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch,
gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch,
gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch,
gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch,
gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch,
gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch,
gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch,
gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch:
New files.
---
gnu/local.mk | 19 +-
gnu/packages/gcc.scm | 20 +-
...-Add-indirect_branch-attribute-with-tests.patch | 475 +++++++++++
...tion-return-and-function_return-attribute.patch | 740 ++++++++++++++++
...tion-return-keep-to-indirect-branch-tests.patch | 421 ++++++++++
.../gcc-retpoline-Add-mindirect-branch-loop.patch | 233 ++++++
...e-Add-mindirect-branch-register-and-tests.patch | 403 +++++++++
...tpoline-Add-mindirect-branch-thunk-extern.patch | 263 ++++++
...tpoline-Add-mindirect-branch-thunk-inline.patch | 310 +++++++
.../gcc-retpoline-Add-mindirect-branch-thunk.patch | 729 ++++++++++++++++
...irect-branch-register-to-indirect-branch-.patch | 554 ++++++++++++
...or-mindirect-branch-thunk-fcheck-pointer-.patch | 134 +++
...Disable-red-zone-with-local-indirect-jump.patch | 147 ++++
...ks-to-__x86_indirect_thunk_rax-etc.-to-re.patch | 926 +++++++++++++++++++++
...ndirect_thunk.reg-for-indirect-branch-via.patch | 623 ++++++++++++++
...line-i386-Add-V-register-operand-modifier.patch | 76 ++
...se-reference-of-struct-ix86_frame-to-avoi.patch | 69 ++
...ove-struct-ix86_frame-to-machine_function.patch | 249 ++++++
...ference-of-struct-ix86_frame-to-avoid-cop.patch | 85 ++
19 files changed, 6474 insertions(+), 2 deletions(-)
create mode 100644
gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch
create mode 100644
gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch
diff --git a/gnu/local.mk b/gnu/local.mk
index 6af8bfc4b..122e8ef0c 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -9,7 +9,7 @@
# Copyright © 2016 Adonay "adfeno" Felipe Nogueira
<https://libreplanet.org/wiki/User:Adfeno> <address@hidden>
# Copyright © 2016, 2017 Ricardo Wurmus <address@hidden>
# Copyright © 2016 Ben Woodcroft <address@hidden>
-# Copyright © 2016, 2017 Alex Vong <address@hidden>
+# Copyright © 2016, 2017, 2018 Alex Vong <address@hidden>
# Copyright © 2016, 2017 Efraim Flashner <address@hidden>
# Copyright © 2016, 2017 Jan Nieuwenhuizen <address@hidden>
# Copyright © 2017 Tobias Geerinckx-Rice <address@hidden>
@@ -652,6 +652,23 @@ dist_patch_DATA =
\
%D%/packages/patches/gcc-asan-powerpc-missing-include.patch \
%D%/packages/patches/gcc-cross-environment-variables.patch \
%D%/packages/patches/gcc-libvtv-runpath.patch \
+
%D%/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch
\
+
%D%/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch
\
+
%D%/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch
\
+ %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch \
+
%D%/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch
\
+ %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch
\
+ %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch
\
+
%D%/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch
\
+
%D%/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch
\
+ %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch \
+
%D%/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch
\
+
%D%/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch
\
+
%D%/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch
\
+
%D%/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch
\
+
%D%/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch
\
+
%D%/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch
\
+
%D%/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch
\
%D%/packages/patches/gcc-strmov-store-file-names.patch \
%D%/packages/patches/gcc-4-compile-with-gcc-5.patch \
%D%/packages/patches/gcc-4.6-gnu-inline.patch \
diff --git a/gnu/packages/gcc.scm b/gnu/packages/gcc.scm
index ad8992289..6b913aff9 100644
--- a/gnu/packages/gcc.scm
+++ b/gnu/packages/gcc.scm
@@ -5,6 +5,7 @@
;;; Copyright © 2015 Andreas Enge <address@hidden>
;;; Copyright © 2015, 2016, 2017 Efraim Flashner <address@hidden>
;;; Copyright © 2016 Carlos Sánchez de La Lama <address@hidden>
+;;; Copyright © 2018 ALex Vong <address@hidden>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -427,7 +428,24 @@ Go. It also includes runtime support libraries for these
languages.")
(base32
"16j7i0888j2f1yp9l0nhji6cq65dy6y4nwy8868a8njbzzwavxqw"))
(patches (search-patches "gcc-strmov-store-file-names.patch"
- "gcc-5.0-libvtv-runpath.patch"))))
+ "gcc-5.0-libvtv-runpath.patch"
+
"gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch"
+
"gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch"
+
"gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch"
+
"gcc-retpoline-Add-mindirect-branch-thunk.patch"
+
"gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch"
+
"gcc-retpoline-Add-mindirect-branch-thunk-inline.patch"
+
"gcc-retpoline-Add-mindirect-branch-thunk-extern.patch"
+
"gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch"
+
"gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch"
+
"gcc-retpoline-Add-mindirect-branch-loop.patch"
+
"gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch"
+
"gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch"
+
"gcc-retpoline-Add-mindirect-branch-register-and-tests.patch"
+
"gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch"
+
"gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch"
+
"gcc-retpoline-i386-Add-V-register-operand-modifier.patch"
+
"gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch"))))
(description
"GCC is the GNU Compiler Collection. It provides compiler front-ends
for several languages, including C, C++, Objective-C, Fortran, Ada, and Go.
diff --git
a/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch
b/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch
new file mode 100644
index 000000000..5129a8273
--- /dev/null
+++
b/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tests.patch
@@ -0,0 +1,475 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From e9794727bb0384be6d27ad1edaefc71c23cc0d86 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Tue, 28 Nov 2017 06:10:39 -0800
+Subject: [PATCH 08/17] Add indirect_branch attribute with tests
+
+__attribute__ ((indirect_branch("thunk")))
+__attribute__ ((indirect_branch("thunk-inline")))
+__attribute__ ((indirect_branch("thunk-extern")))
+__attribute__ ((indirect_branch("keep")))
+---
+ gcc/config/i386/i386-opts.h | 1 +
+ gcc/config/i386/i386.c | 74 ++++++++++++++++++++--
+ gcc/config/i386/i386.h | 3 +
+ .../gcc.target/i386/indirect-thunk-attr-1.c | 22 +++++++
+ .../gcc.target/i386/indirect-thunk-attr-2.c | 20 ++++++
+ .../gcc.target/i386/indirect-thunk-attr-3.c | 21 ++++++
+ .../gcc.target/i386/indirect-thunk-attr-4.c | 20 ++++++
+ .../gcc.target/i386/indirect-thunk-attr-5.c | 22 +++++++
+ .../gcc.target/i386/indirect-thunk-attr-6.c | 21 ++++++
+ .../gcc.target/i386/indirect-thunk-attr-7.c | 44 +++++++++++++
+ .../gcc.target/i386/indirect-thunk-attr-8.c | 41 ++++++++++++
+ 11 files changed, 283 insertions(+), 6 deletions(-)
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
+
+diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
+index f8d80ba7ec6..9e56d7f2d12 100644
+--- a/gcc/config/i386/i386-opts.h
++++ b/gcc/config/i386/i386-opts.h
+@@ -100,6 +100,7 @@ enum stack_protector_guard {
+ };
+
+ enum indirect_branch {
++ indirect_branch_unset = 0,
+ indirect_branch_keep,
+ indirect_branch_thunk,
+ indirect_branch_thunk_inline,
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index ac542f79846..5e66af08066 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -7137,6 +7137,37 @@ ix86_set_func_type (tree fndecl)
+ }
+ }
+
++/* Set the indirect_branch_type field from the function FNDECL. */
++
++static void
++ix86_set_indirect_branch_type (tree fndecl)
++{
++ if (cfun->machine->indirect_branch_type == indirect_branch_unset)
++ {
++ tree attr = lookup_attribute ("indirect_branch",
++ DECL_ATTRIBUTES (fndecl));
++ if (attr != NULL)
++ {
++ tree args = TREE_VALUE (attr);
++ if (args == NULL)
++ gcc_unreachable ();
++ tree cst = TREE_VALUE (args);
++ if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0)
++ cfun->machine->indirect_branch_type = indirect_branch_keep;
++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0)
++ cfun->machine->indirect_branch_type = indirect_branch_thunk;
++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0)
++ cfun->machine->indirect_branch_type = indirect_branch_thunk_inline;
++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0)
++ cfun->machine->indirect_branch_type = indirect_branch_thunk_extern;
++ else
++ gcc_unreachable ();
++ }
++ else
++ cfun->machine->indirect_branch_type = ix86_indirect_branch;
++ }
++}
++
+ /* Establish appropriate back-end context for processing the function
+ FNDECL. The argument might be NULL to indicate processing at top
+ level, outside of any function scope. */
+@@ -7152,7 +7183,10 @@ ix86_set_current_function (tree fndecl)
+ one is extern inline and one isn't. Call ix86_set_func_type
+ to set the func_type field. */
+ if (fndecl != NULL_TREE)
+- ix86_set_func_type (fndecl);
++ {
++ ix86_set_func_type (fndecl);
++ ix86_set_indirect_branch_type (fndecl);
++ }
+ return;
+ }
+
+@@ -7172,6 +7206,7 @@ ix86_set_current_function (tree fndecl)
+ }
+
+ ix86_set_func_type (fndecl);
++ ix86_set_indirect_branch_type (fndecl);
+
+ tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+ if (new_tree == NULL_TREE)
+@@ -28605,9 +28640,11 @@ ix86_output_indirect_branch (rtx call_op, const char
*xasm,
+ char push_buf[64];
+ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);
+
+- if (ix86_indirect_branch != indirect_branch_thunk_inline)
++ if (cfun->machine->indirect_branch_type
++ != indirect_branch_thunk_inline)
+ {
+- bool need_thunk = ix86_indirect_branch == indirect_branch_thunk;
++ bool need_thunk
++ = cfun->machine->indirect_branch_type == indirect_branch_thunk;
+ if (need_bnd_p)
+ indirect_thunk_bnd_needed |= need_thunk;
+ else
+@@ -28716,7 +28753,7 @@ const char *
+ ix86_output_indirect_jmp (rtx call_op)
+ {
+ if (ix86_red_zone_size == 0
+- && ix86_indirect_branch != indirect_branch_keep)
++ && cfun->machine->indirect_branch_type != indirect_branch_keep)
+ {
+ ix86_output_indirect_branch (call_op, "%0", true);
+ return "";
+@@ -28733,7 +28770,7 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
+ bool direct_p = constant_call_address_operand (call_op, VOIDmode);
+ bool output_indirect_p
+ = (!TARGET_SEH
+- && ix86_indirect_branch != indirect_branch_keep);
++ && cfun->machine->indirect_branch_type != indirect_branch_keep);
+ bool seh_nop_p = false;
+ const char *xasm;
+
+@@ -41749,7 +41786,7 @@ ix86_handle_struct_attribute (tree *node, tree name,
tree, int,
+ }
+
+ static tree
+-ix86_handle_fndecl_attribute (tree *node, tree name, tree, int,
++ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int,
+ bool *no_add_attrs)
+ {
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+@@ -41758,6 +41795,29 @@ ix86_handle_fndecl_attribute (tree *node, tree name,
tree, int,
+ name);
+ *no_add_attrs = true;
+ }
++
++ if (is_attribute_p ("indirect_branch", name))
++ {
++ tree cst = TREE_VALUE (args);
++ if (TREE_CODE (cst) != STRING_CST)
++ {
++ warning (OPT_Wattributes,
++ "%qE attribute requires a string constant argument",
++ name);
++ *no_add_attrs = true;
++ }
++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0
++ && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0
++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0
++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0)
++ {
++ warning (OPT_Wattributes,
++ "argument to %qE attribute is not "
++ "(keep|thunk|thunk-inline|thunk-extern)", name);
++ *no_add_attrs = true;
++ }
++ }
++
+ return NULL_TREE;
+ }
+
+@@ -46052,6 +46112,8 @@ static const struct attribute_spec
ix86_attribute_table[] =
+ ix86_handle_interrupt_attribute, false },
+ { "no_caller_saved_registers", 0, 0, false, true, true,
+ ix86_handle_no_caller_saved_registers_attribute, false },
++ { "indirect_branch", 1, 1, true, false, false,
++ ix86_handle_fndecl_attribute, false },
+
+ /* End element. */
+ { NULL, 0, 0, false, false, false, NULL, false }
+diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
+index 7d9f9020fb3..a9c199a107c 100644
+--- a/gcc/config/i386/i386.h
++++ b/gcc/config/i386/i386.h
+@@ -2604,6 +2604,9 @@ struct GTY(()) machine_function {
+ /* Function type. */
+ ENUM_BITFIELD(function_type) func_type : 2;
+
++ /* How to generate indirec branch. */
++ ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3;
++
+ /* If true, the current function is a function specified with
+ the "interrupt" or "no_caller_saved_registers" attribute. */
+ BOOL_BITFIELD no_caller_saved_registers : 1;
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+new file mode 100644
+index 00000000000..26550fad4c8
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+@@ -0,0 +1,22 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+new file mode 100644
+index 00000000000..f57bb2a92d6
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+@@ -0,0 +1,20 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+new file mode 100644
+index 00000000000..a3668a6586c
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+@@ -0,0 +1,21 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+new file mode 100644
+index 00000000000..a9c4a137dd4
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+@@ -0,0 +1,20 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+new file mode 100644
+index 00000000000..9582e0c5824
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+@@ -0,0 +1,22 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+new file mode 100644
+index 00000000000..66442cacfe8
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+@@ -0,0 +1,21 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+new file mode 100644
+index 00000000000..2a19b54cd2e
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+@@ -0,0 +1,44 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -fno-pic" } */
++
++void func0 (void);
++void func1 (void);
++void func2 (void);
++void func3 (void);
++void func4 (void);
++void func4 (void);
++void func5 (void);
++
++__attribute__ ((indirect_branch("thunk-extern")))
++void
++bar (int i)
++{
++ switch (i)
++ {
++ default:
++ func0 ();
++ break;
++ case 1:
++ func1 ();
++ break;
++ case 2:
++ func2 ();
++ break;
++ case 3:
++ func3 ();
++ break;
++ case 4:
++ func4 ();
++ break;
++ case 5:
++ func5 ();
++ break;
++ }
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target
{ ! x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
+new file mode 100644
+index 00000000000..9f6d12d74a1
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
+@@ -0,0 +1,41 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */
++
++void func0 (void);
++void func1 (void);
++void func2 (void);
++void func3 (void);
++void func4 (void);
++void func4 (void);
++void func5 (void);
++
++__attribute__ ((indirect_branch("keep")))
++void
++bar (int i)
++{
++ switch (i)
++ {
++ default:
++ func0 ();
++ break;
++ case 1:
++ func1 ();
++ break;
++ case 2:
++ func2 ();
++ break;
++ case 3:
++ func3 ();
++ break;
++ case 4:
++ func4 ();
++ break;
++ case 5:
++ func5 ();
++ break;
++ }
++}
++
++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch
b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch
new file mode 100644
index 000000000..0845de4b2
--- /dev/null
+++
b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_return-attribute.patch
@@ -0,0 +1,740 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 29d5a3f23c18c96944dd3230a41380a6edcd25fd Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Tue, 5 Dec 2017 13:29:06 -0800
+Subject: [PATCH 11/17] Add -mfunction-return= and function_return attribute
+
+Add -mfunction-return= and function_return attribute tests
+
+-mfunction-return=thunk
+ Convert function return instruction to PC-relative call thunk.
+-mfunction-return=thunk-inline
+ Convert function return instruction to PC-relative call thunk with
+ thunk inlined.
+-mfunction-return=thunk-extern
+ Convert function return instruction to PC-relative call to external
+ thunk.
+
+Add function_return attribute to function declaration
+
+__attribute__ ((function_return("thunk")))
+__attribute__ ((function_return("thunk-inline")))
+__attribute__ ((function_return("thunk-extern")))
+__attribute__ ((function_return("keep")))
+---
+ gcc/config/i386/i386-protos.h | 1 +
+ gcc/config/i386/i386.c | 146 +++++++++++++++++++++++++--
+ gcc/config/i386/i386.h | 3 +
+ gcc/config/i386/i386.md | 9 +-
+ gcc/config/i386/i386.opt | 6 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-1.c | 12 +++
+ gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 22 ++++
+ gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 22 ++++
+ gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 21 ++++
+ gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 21 ++++
+ gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 21 ++++
+ gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 21 ++++
+ gcc/testsuite/gcc.target/i386/ret-thunk-16.c | 18 ++++
+ gcc/testsuite/gcc.target/i386/ret-thunk-2.c | 12 +++
+ gcc/testsuite/gcc.target/i386/ret-thunk-3.c | 12 +++
+ gcc/testsuite/gcc.target/i386/ret-thunk-4.c | 12 +++
+ gcc/testsuite/gcc.target/i386/ret-thunk-5.c | 14 +++
+ gcc/testsuite/gcc.target/i386/ret-thunk-6.c | 13 +++
+ gcc/testsuite/gcc.target/i386/ret-thunk-7.c | 13 +++
+ gcc/testsuite/gcc.target/i386/ret-thunk-8.c | 14 +++
+ gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 23 +++++
+ 21 files changed, 421 insertions(+), 15 deletions(-)
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-1.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-10.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-11.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-12.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-13.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-14.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-15.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-16.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-2.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-3.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-4.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-5.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-6.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-7.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-8.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-9.c
+
+diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
+index b746429f420..213663811de 100644
+--- a/gcc/config/i386/i386-protos.h
++++ b/gcc/config/i386/i386-protos.h
+@@ -316,6 +316,7 @@ extern enum attr_cpu ix86_schedule;
+
+ extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op);
+ extern const char * ix86_output_indirect_jmp (rtx call_op);
++extern const char * ix86_output_function_return (bool long_p);
+ extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load,
+ enum machine_mode mode);
+
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index be1ff4752a9..7ae3523095c 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -7166,6 +7166,31 @@ ix86_set_indirect_branch_type (tree fndecl)
+ else
+ cfun->machine->indirect_branch_type = ix86_indirect_branch;
+ }
++
++ if (cfun->machine->function_return_type == indirect_branch_unset)
++ {
++ tree attr = lookup_attribute ("function_return",
++ DECL_ATTRIBUTES (fndecl));
++ if (attr != NULL)
++ {
++ tree args = TREE_VALUE (attr);
++ if (args == NULL)
++ gcc_unreachable ();
++ tree cst = TREE_VALUE (args);
++ if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0)
++ cfun->machine->function_return_type = indirect_branch_keep;
++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0)
++ cfun->machine->function_return_type = indirect_branch_thunk;
++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0)
++ cfun->machine->function_return_type = indirect_branch_thunk_inline;
++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0)
++ cfun->machine->function_return_type = indirect_branch_thunk_extern;
++ else
++ gcc_unreachable ();
++ }
++ else
++ cfun->machine->function_return_type = ix86_function_return;
++ }
+ }
+
+ /* Establish appropriate back-end context for processing the function
+@@ -11958,8 +11983,12 @@ static int indirect_thunks_bnd_used;
+ /* Fills in the label name that should be used for the indirect thunk. */
+
+ static void
+-indirect_thunk_name (char name[32], int regno, bool need_bnd_p)
++indirect_thunk_name (char name[32], int regno, bool need_bnd_p,
++ bool ret_p)
+ {
++ if (regno >= 0 && ret_p)
++ gcc_unreachable ();
++
+ if (USE_HIDDEN_LINKONCE)
+ {
+ const char *bnd = need_bnd_p ? "_bnd" : "";
+@@ -11974,7 +12003,10 @@ indirect_thunk_name (char name[32], int regno, bool
need_bnd_p)
+ bnd, reg_prefix, reg_names[regno]);
+ }
+ else
+- sprintf (name, "__x86.indirect_thunk%s", bnd);
++ {
++ const char *ret = ret_p ? "return" : "indirect";
++ sprintf (name, "__x86.%s_thunk%s", ret, bnd);
++ }
+ }
+ else
+ {
+@@ -11987,10 +12019,20 @@ indirect_thunk_name (char name[32], int regno, bool
need_bnd_p)
+ }
+ else
+ {
+- if (need_bnd_p)
+- ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);
++ if (ret_p)
++ {
++ if (need_bnd_p)
++ ASM_GENERATE_INTERNAL_LABEL (name, "LRTB", 0);
++ else
++ ASM_GENERATE_INTERNAL_LABEL (name, "LRT", 0);
++ }
+ else
+- ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);
++ {
++ if (need_bnd_p)
++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);
++ else
++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);
++ }
+ }
+ }
+ }
+@@ -12071,7 +12113,7 @@ output_indirect_thunk_function (bool need_bnd_p, int
regno)
+ tree decl;
+
+ /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */
+- indirect_thunk_name (name, regno, need_bnd_p);
++ indirect_thunk_name (name, regno, need_bnd_p, false);
+ decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
+ get_identifier (name),
+ build_function_type_list (void_type_node, NULL_TREE));
+@@ -12114,6 +12156,35 @@ output_indirect_thunk_function (bool need_bnd_p, int
regno)
+ ASM_OUTPUT_LABEL (asm_out_file, name);
+ }
+
++ if (regno < 0)
++ {
++ /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */
++ char alias[32];
++
++ indirect_thunk_name (alias, regno, need_bnd_p, true);
++ ASM_OUTPUT_DEF (asm_out_file, alias, name);
++#if TARGET_MACHO
++ if (TARGET_MACHO)
++ {
++ fputs ("\t.weak_definition\t", asm_out_file);
++ assemble_name (asm_out_file, alias);
++ fputs ("\n\t.private_extern\t", asm_out_file);
++ assemble_name (asm_out_file, alias);
++ putc ('\n', asm_out_file);
++ }
++#else
++ if (USE_HIDDEN_LINKONCE)
++ {
++ fputs ("\t.globl\t", asm_out_file);
++ assemble_name (asm_out_file, alias);
++ putc ('\n', asm_out_file);
++ fputs ("\t.hidden\t", asm_out_file);
++ assemble_name (asm_out_file, alias);
++ putc ('\n', asm_out_file);
++ }
++#endif
++ }
++
+ DECL_INITIAL (decl) = make_node (BLOCK);
+ current_function_decl = decl;
+ allocate_struct_function (decl, false);
+@@ -28736,7 +28807,7 @@ ix86_output_indirect_branch (rtx call_op, const char
*xasm,
+ indirect_thunk_needed = true;
+ }
+ }
+- indirect_thunk_name (thunk_name_buf, regno, need_bnd_p);
++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false);
+ thunk_name = thunk_name_buf;
+ }
+ else
+@@ -28860,6 +28931,43 @@ ix86_output_indirect_jmp (rtx call_op)
+ return "%!jmp\t%A0";
+ }
+
++const char *
++ix86_output_function_return (bool long_p)
++{
++ if (cfun->machine->function_return_type != indirect_branch_keep)
++ {
++ char thunk_name[32];
++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);
++
++ if (cfun->machine->function_return_type
++ != indirect_branch_thunk_inline)
++ {
++ bool need_thunk = (cfun->machine->function_return_type
++ == indirect_branch_thunk);
++ indirect_thunk_name (thunk_name, -1, need_bnd_p, true);
++ if (need_bnd_p)
++ {
++ indirect_thunk_bnd_needed |= need_thunk;
++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
++ }
++ else
++ {
++ indirect_thunk_needed |= need_thunk;
++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
++ }
++ }
++ else
++ output_indirect_thunk (need_bnd_p, -1);
++
++ return "";
++ }
++
++ if (!long_p || ix86_bnd_prefixed_insn_p (current_output_insn))
++ return "%!ret";
++
++ return "rep%; ret";
++}
++
+ /* Output the assembly for a call instruction. */
+
+ const char *
+@@ -41916,6 +42024,28 @@ ix86_handle_fndecl_attribute (tree *node, tree name,
tree args, int,
+ }
+ }
+
++ if (is_attribute_p ("function_return", name))
++ {
++ tree cst = TREE_VALUE (args);
++ if (TREE_CODE (cst) != STRING_CST)
++ {
++ warning (OPT_Wattributes,
++ "%qE attribute requires a string constant argument",
++ name);
++ *no_add_attrs = true;
++ }
++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0
++ && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0
++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0
++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0)
++ {
++ warning (OPT_Wattributes,
++ "argument to %qE attribute is not "
++ "(keep|thunk|thunk-inline|thunk-extern)", name);
++ *no_add_attrs = true;
++ }
++ }
++
+ return NULL_TREE;
+ }
+
+@@ -46212,6 +46342,8 @@ static const struct attribute_spec
ix86_attribute_table[] =
+ ix86_handle_no_caller_saved_registers_attribute, false },
+ { "indirect_branch", 1, 1, true, false, false,
+ ix86_handle_fndecl_attribute, false },
++ { "function_return", 1, 1, true, false, false,
++ ix86_handle_fndecl_attribute, false },
+
+ /* End element. */
+ { NULL, 0, 0, false, false, false, NULL, false }
+diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
+index a9c199a107c..f248f3ba2f5 100644
+--- a/gcc/config/i386/i386.h
++++ b/gcc/config/i386/i386.h
+@@ -2607,6 +2607,9 @@ struct GTY(()) machine_function {
+ /* How to generate indirec branch. */
+ ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3;
+
++ /* How to generate function return. */
++ ENUM_BITFIELD(indirect_branch) function_return_type : 3;
++
+ /* If true, the current function is a function specified with
+ the "interrupt" or "no_caller_saved_registers" attribute. */
+ BOOL_BITFIELD no_caller_saved_registers : 1;
+diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
+index 01b7b2039e6..00a9afef225 100644
+--- a/gcc/config/i386/i386.md
++++ b/gcc/config/i386/i386.md
+@@ -12288,7 +12288,7 @@
+ (define_insn "simple_return_internal"
+ [(simple_return)]
+ "reload_completed"
+- "%!ret"
++ "* return ix86_output_function_return (false);"
+ [(set_attr "length" "1")
+ (set_attr "atom_unit" "jeu")
+ (set_attr "length_immediate" "0")
+@@ -12310,12 +12310,7 @@
+ [(simple_return)
+ (unspec [(const_int 0)] UNSPEC_REP)]
+ "reload_completed"
+-{
+- if (ix86_bnd_prefixed_insn_p (insn))
+- return "%!ret";
+-
+- return "rep%; ret";
+-}
++ "* return ix86_output_function_return (true);"
+ [(set_attr "length" "2")
+ (set_attr "atom_unit" "jeu")
+ (set_attr "length_immediate" "0")
+diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
+index bc81e6bea86..fc2c81c3fb5 100644
+--- a/gcc/config/i386/i386.opt
++++ b/gcc/config/i386/i386.opt
+@@ -932,9 +932,13 @@ mindirect-branch=
+ Target Report RejectNegative Joined Enum(indirect_branch)
Var(ix86_indirect_branch) Init(indirect_branch_keep)
+ Update indirect call and jump.
+
++mfunction-return=
++Target Report RejectNegative Joined Enum(indirect_branch)
Var(ix86_function_return) Init(indirect_branch_keep)
++Update function return.
++
+ Enum
+ Name(indirect_branch) Type(enum indirect_branch)
+-Known indirect branch choices (for use with the -mindirect-branch= option):
++Known indirect branch choices (for use with the
-mindirect-branch=/-mfunction-return= options):
+
+ EnumValue
+ Enum(indirect_branch) String(keep) Value(indirect_branch_keep)
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c
+new file mode 100644
+index 00000000000..406956f48e5
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c
+@@ -0,0 +1,12 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=thunk" } */
++
++void
++foo (void)
++{
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
+new file mode 100644
+index 00000000000..aecea4224f9
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
+@@ -0,0 +1,22 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk
-fno-pic" } */
++
++extern void (*bar) (void);
++
++int
++foo (void)
++{
++ bar ();
++ return 0;
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 }
} } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } }
} } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target { x32 } } } } */
++/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target {
x32 } } } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
+new file mode 100644
+index 00000000000..3bacfb54dfd
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
+@@ -0,0 +1,22 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk
-fno-pic" } */
++
++extern void (*bar) (void);
++
++int
++foo (void)
++{
++ bar ();
++ return 0;
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 }
} } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } }
} } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target { x32 } } } } */
++/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target {
x32 } } } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
+new file mode 100644
+index 00000000000..851115ac507
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
+@@ -0,0 +1,21 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic"
} */
++
++extern void (*bar) (void);
++
++int
++foo (void)
++{
++ bar ();
++ return 0;
++}
++
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } }
} } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target { x32 } } } } */
++/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target {
x32 } } } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
+new file mode 100644
+index 00000000000..7acb6fa5eae
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
+@@ -0,0 +1,21 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline
-fno-pic" } */
++
++extern void (*bar) (void);
++extern int foo (void) __attribute__ ((function_return("thunk")));
++
++int
++foo (void)
++{
++ bar ();
++ return 0;
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 }
} } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "call\[
\t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
+new file mode 100644
+index 00000000000..bf340fac7c6
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
+@@ -0,0 +1,21 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern
-fno-pic" } */
++
++extern void (*bar) (void);
++
++__attribute__ ((function_return("thunk-inline")))
++int
++foo (void)
++{
++ bar ();
++ return 0;
++}
++
++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 }
} } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target { x32 } } } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
+new file mode 100644
+index 00000000000..735f8648c96
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
+@@ -0,0 +1,21 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic"
} */
++
++extern void (*bar) (void);
++
++__attribute__ ((function_return("thunk-extern"), indirect_branch("thunk")))
++int
++foo (void)
++{
++ bar ();
++ return 0;
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 }
} } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-16.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c
+new file mode 100644
+index 00000000000..cf3920563e0
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c
+@@ -0,0 +1,18 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=thunk-inline
-mindirect-branch=thunk-extern -fno-pic" } */
++
++extern void (*bar) (void);
++
++__attribute__ ((function_return("keep"), indirect_branch("keep")))
++int
++foo (void)
++{
++ bar ();
++ return 0;
++}
++
++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-not {\tlfence} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-2.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c
+new file mode 100644
+index 00000000000..190947cc2ca
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c
+@@ -0,0 +1,12 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=thunk-inline" } */
++
++void
++foo (void)
++{
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-3.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c
+new file mode 100644
+index 00000000000..d71de3ac520
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c
+@@ -0,0 +1,12 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=thunk-extern" } */
++
++void
++foo (void)
++{
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-not {\tlfence} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-4.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c
+new file mode 100644
+index 00000000000..68c22122f0d
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c
+@@ -0,0 +1,12 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=keep" } */
++
++void
++foo (void)
++{
++}
++
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-not {\tlfence} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-5.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c
+new file mode 100644
+index 00000000000..28c576e2267
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c
+@@ -0,0 +1,14 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=keep" } */
++
++extern void foo (void) __attribute__ ((function_return("thunk")));
++
++void
++foo (void)
++{
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c
+new file mode 100644
+index 00000000000..10ad40b9c26
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c
+@@ -0,0 +1,13 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=keep" } */
++
++__attribute__ ((function_return("thunk-inline")))
++void
++foo (void)
++{
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-7.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c
+new file mode 100644
+index 00000000000..7ac0beaa73e
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c
+@@ -0,0 +1,13 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=keep" } */
++
++__attribute__ ((function_return("thunk-extern")))
++void
++foo (void)
++{
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-not {\tlfence} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-8.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c
+new file mode 100644
+index 00000000000..777ab7c8088
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c
+@@ -0,0 +1,14 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=thunk-inline" } */
++
++extern void foo (void) __attribute__ ((function_return("keep")));
++
++void
++foo (void)
++{
++}
++
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-not {\tlfence} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
+new file mode 100644
+index 00000000000..569e5f47973
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
+@@ -0,0 +1,23 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk
-fno-pic" } */
++
++extern void (*bar) (void);
++
++int
++foo (void)
++{
++ bar ();
++ return 0;
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86.return_thunk:" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "__x86.indirect_thunk:" } } */
++/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 }
} } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target { x32 } } } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch
b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch
new file mode 100644
index 000000000..ac900bab0
--- /dev/null
+++
b/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indirect-branch-tests.patch
@@ -0,0 +1,421 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From def2b5d75fd6234984ec969f4586fcb8c516a3b9 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Wed, 6 Dec 2017 09:58:42 -0800
+Subject: [PATCH 12/17] Add -mfunction-return=keep to indirect branch tests
+
+---
+ gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 2 +-
+ 33 files changed, 33 insertions(+), 33 deletions(-)
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+index 785e593405f..318db1e7f5c 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic"
} */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+index b69075e6483..f2700dd36cf 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic"
} */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+index df8109baf55..46685d9a674 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic"
} */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+index 8f3b9f4d8a5..8f701775cea 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic"
} */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
+index 1a9bb0e431e..f88ac31d07a 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target *-*-linux* } } */
+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */
++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt
-mindirect-branch=thunk" } */
+
+ extern void bar (void);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
+index bc7d20ec6ad..d745116d321 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target *-*-linux* } } */
+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */
++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt
-mindirect-branch=thunk" } */
+
+ extern void bar (void);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+index f0e1cfe1893..969cb8c6ddc 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic"
} */
+
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+index 8b88449e625..12a61c3bbc7 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+index c69f7bf4f60..a06907933a2 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+index c845099a83e..7f56725e6b6 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+index f636f3422fd..fd4ab1dbaa0 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+index 5f1d6a78041..1ffbf3b1181 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+index 56c92da9812..1559072919a 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+index cfb6f5b234b..1717e7bb436 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
+index 9f6d12d74a1..af1bb125a22 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic"
} */
+
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+index a5b1d38e061..20903b0f79d 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target { ! x32 } } } */
+-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx
-fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk
-fcheck-pointer-bounds -mmpx -fno-pic" } */
+
+ void (*dispatch) (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+index a42add209e2..aef4bd144f4 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target { ! x32 } } } */
+-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx
-fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk
-fcheck-pointer-bounds -mmpx -fno-pic" } */
+
+ void (*dispatch) (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
+index 265e010a0fe..2cc0343f828 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */
+-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx
-fpic -fno-plt" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk
-fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
+
+ void bar (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
+index 1c01bcb7fc6..91560fef661 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */
+-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx
-fpic -fno-plt" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk
-fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
+
+ void bar (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+index f1fa0a11922..dc6bd10af4c 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern
-fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+index d6e078d594b..955aa256529 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern
-fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+index 3bbe2646955..1537239416f 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern
-fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+index 596fac599f6..c82e53068fe 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern
-fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
+index ad54aaeac4c..23548d85f78 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target *-*-linux* } } */
+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */
++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt
-mindirect-branch=thunk-extern" } */
+
+ extern void bar (void);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
+index a8e75254cfe..56c2fe92f25 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target *-*-linux* } } */
+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */
++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt
-mindirect-branch=thunk-extern" } */
+
+ extern void bar (void);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+index ab367951c45..e12b88593fe 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern
-fno-pic" } */
+
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+index 09b8ad7d879..87b5429702f 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline
-fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+index 1f873758fbe..a496a41a918 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline
-fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+index b24af1da963..6fe5ce71abf 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline
-fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+index 1a86608f727..65cd997a33f 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline
-fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
+index f4890fe97b2..7321d015c02 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target *-*-linux* } } */
+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */
++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt
-mindirect-branch=thunk-inline" } */
+
+ extern void bar (void);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
+index 81b09e73ab8..6ec2e5621ab 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target *-*-linux* } } */
+-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */
++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt
-mindirect-branch=thunk-inline" } */
+
+ extern void bar (void);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+index 01d45782185..a3d1a13cded 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline
-fno-pic" } */
+
+ void func0 (void);
+ void func1 (void);
+--
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch
b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch
new file mode 100644
index 000000000..ab715f46a
--- /dev/null
+++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch
@@ -0,0 +1,233 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From d667049b53e3d45de057fba2f1ed0e3f268201c1 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Thu, 16 Nov 2017 14:46:20 -0800
+Subject: [PATCH 10/17] Add -mindirect-branch-loop=
+
+Add -mindirect-branch-loop= tests.
+---
+ gcc/config/i386/i386-opts.h | 6 ++++++
+ gcc/config/i386/i386.c | 19 +++++++++++++++++--
+ gcc/config/i386/i386.opt | 16 ++++++++++++++++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c | 19 +++++++++++++++++++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c | 19 +++++++++++++++++++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c | 19 +++++++++++++++++++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c | 19 +++++++++++++++++++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c | 19 +++++++++++++++++++
+ 8 files changed, 134 insertions(+), 2 deletions(-)
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
+
+diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
+index 9e56d7f2d12..b7b8fd280a3 100644
+--- a/gcc/config/i386/i386-opts.h
++++ b/gcc/config/i386/i386-opts.h
+@@ -107,4 +107,10 @@ enum indirect_branch {
+ indirect_branch_thunk_extern
+ };
+
++enum indirect_branch_loop {
++ indirect_branch_loop_lfence,
++ indirect_branch_loop_pause,
++ indirect_branch_loop_nop
++};
++
+ #endif
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index 590729b3f87..be1ff4752a9 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -12016,8 +12016,23 @@ output_indirect_thunk (bool need_bnd_p, int regno)
+
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
+
+- /* lfence . */
+- fprintf (asm_out_file, "\tlfence\n");
++ switch (ix86_indirect_branch_loop)
++ {
++ case indirect_branch_loop_lfence:
++ /* lfence. */
++ fprintf (asm_out_file, "\tlfence\n");
++ break;
++ case indirect_branch_loop_pause:
++ /* pause. */
++ fprintf (asm_out_file, "\tpause\n");
++ break;
++ case indirect_branch_loop_nop:
++ /* nop. */
++ fprintf (asm_out_file, "\tnop\n");
++ break;
++ default:
++ gcc_unreachable ();
++ }
+
+ /* Jump. */
+ fputs ("\tjmp\t", asm_out_file);
+diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
+index 4a932e11bf6..bc81e6bea86 100644
+--- a/gcc/config/i386/i386.opt
++++ b/gcc/config/i386/i386.opt
+@@ -947,3 +947,19 @@ Enum(indirect_branch) String(thunk-inline)
Value(indirect_branch_thunk_inline)
+
+ EnumValue
+ Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)
++
++mindirect-branch-loop=
++Target Report RejectNegative Joined Enum(indirect_branch_loop)
Var(ix86_indirect_branch_loop) Undocumented Init(indirect_branch_loop_lfence)
++
++Enum
++Name(indirect_branch_loop) Type(enum indirect_branch_loop)
++Known looop choices (for use with the -mindirect-branch-loop= option):
++
++EnumValue
++Enum(indirect_branch_loop) String(lfence) Value(indirect_branch_loop_lfence)
++
++EnumValue
++Enum(indirect_branch_loop) String(pause) Value(indirect_branch_loop_pause)
++
++EnumValue
++Enum(indirect_branch_loop) String(nop) Value(indirect_branch_loop_nop)
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
+new file mode 100644
+index 00000000000..f0e8f4949c8
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
+@@ -0,0 +1,19 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=pause
-fno-pic" } */
++
++typedef void (*dispatch_t)(long offset);
++
++dispatch_t dispatch;
++
++void
++male_indirect_jump (long offset)
++{
++ dispatch(offset);
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tpause} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
+new file mode 100644
+index 00000000000..a577ac2568a
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
+@@ -0,0 +1,19 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=nop
-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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tnop} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
+new file mode 100644
+index 00000000000..c8dcb9639c4
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
+@@ -0,0 +1,19 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=lfence
-fno-pic" } */
++
++typedef void (*dispatch_t)(long offset);
++
++dispatch_t dispatch;
++
++void
++male_indirect_jump (long offset)
++{
++ dispatch(offset);
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
+new file mode 100644
+index 00000000000..8569dfc92c3
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
+@@ -0,0 +1,19 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=thunk-inline
-mindirect-branch-loop=pause -fno-pic" } */
++
++typedef void (*dispatch_t)(long offset);
++
++dispatch_t dispatch;
++
++void
++male_indirect_jump (long offset)
++{
++ dispatch(offset);
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tpause} } } */
++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
+new file mode 100644
+index 00000000000..bcf19c9ede1
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
+@@ -0,0 +1,19 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=thunk-extern
-mindirect-branch-loop=pause -fno-pic" } */
++
++typedef void (*dispatch_t)(long offset);
++
++dispatch_t dispatch;
++
++void
++male_indirect_jump (long offset)
++{
++ dispatch(offset);
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch
b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch
new file mode 100644
index 000000000..de9e373fd
--- /dev/null
+++
b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-tests.patch
@@ -0,0 +1,403 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From fb8875abab630962dbcb08c822b1b960fa5a51d4 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Wed, 19 Jul 2017 19:23:02 -0700
+Subject: [PATCH 13/17] Add -mindirect-branch-register and tests
+
+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. With -mindirect-branch-register:
+
+void (*func) (void);
+
+void
+bar (void)
+{
+ func ();
+}
+
+is compiled into:
+
+ movq func(%rip), %rax
+ jmp __x86.indirect_thunk.ax
+
+__x86.indirect_thunk.ax:
+ call .LIND3
+.LIND2:
+ lfence
+ jmp .LIND2
+.LIND3:
+ mov %rax, (%rsp)
+ ret
+
+and
+
+void (*func) (void);
+
+int
+bar (void)
+{
+ func ();
+ return 0;
+}
+
+is compiled into:
+
+ subq $8, %rsp
+ movq func(%rip), %rax
+ call __x86.indirect_thunk.ax
+ xorl %eax, %eax
+ addq $8, %rsp
+ ret
+
+ * 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.
+---
+ gcc/config/i386/constraints.md | 12 +++++---
+ gcc/config/i386/i386.md | 34 ++++++++++++++--------
+ gcc/config/i386/i386.opt | 4 +++
+ gcc/config/i386/predicates.md | 21 ++++++++-----
+ .../gcc.target/i386/indirect-thunk-register-1.c | 22 ++++++++++++++
+ .../gcc.target/i386/indirect-thunk-register-2.c | 20 +++++++++++++
+ .../gcc.target/i386/indirect-thunk-register-3.c | 19 ++++++++++++
+ 7 files changed, 109 insertions(+), 23 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
+
+diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
+index 38d604fdace..697caf704dd 100644
+--- a/gcc/config/i386/constraints.md
++++ b/gcc/config/i386/constraints.md
+@@ -198,16 +198,20 @@
+
+ (define_constraint "Bs"
+ "@internal Sibcall memory operand."
+- (ior (and (not (match_test "TARGET_X32"))
++ (ior (and (not (match_test "TARGET_X32
++ || ix86_indirect_branch_thunk_register"))
+ (match_operand 0 "sibcall_memory_operand"))
+- (and (match_test "TARGET_X32 && Pmode == DImode")
++ (and (match_test "TARGET_X32 && Pmode == DImode
++ && !ix86_indirect_branch_thunk_register")
+ (match_operand 0 "GOT_memory_operand"))))
+
+ (define_constraint "Bw"
+ "@internal Call memory operand."
+- (ior (and (not (match_test "TARGET_X32"))
++ (ior (and (not (match_test "TARGET_X32
++ || ix86_indirect_branch_thunk_register"))
+ (match_operand 0 "memory_operand"))
+- (and (match_test "TARGET_X32 && Pmode == DImode")
++ (and (match_test "TARGET_X32 && Pmode == DImode
++ && !ix86_indirect_branch_thunk_register")
+ (match_operand 0 "GOT_memory_operand"))))
+
+ (define_constraint "Bz"
+diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
+index 00a9afef225..473fa5c089b 100644
+--- a/gcc/config/i386/i386.md
++++ b/gcc/config/i386/i386.md
+@@ -11608,7 +11608,7 @@
+ [(set (pc) (match_operand 0 "indirect_branch_operand"))]
+ ""
+ {
+- if (TARGET_X32)
++ if (TARGET_X32 || ix86_indirect_branch_thunk_register)
+ operands[0] = convert_memory_address (word_mode, operands[0]);
+ })
+
+@@ -11657,7 +11657,7 @@
+ OPTAB_DIRECT);
+ }
+
+- if (TARGET_X32)
++ if (TARGET_X32 || ix86_indirect_branch_thunk_register)
+ operands[0] = convert_memory_address (word_mode, operands[0]);
+ })
+
+@@ -11844,7 +11844,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_thunk_register"
+ "* return ix86_output_call_insn (insn, operands[0]);"
+ [(set_attr "type" "call")])
+
+@@ -11853,7 +11853,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_thunk_register
++ && SIBLING_CALL_P (peep2_next_insn (1))
+ && !reg_mentioned_p (operands[0],
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
+ [(parallel [(call (mem:QI (match_dup 1))
+@@ -11866,7 +11868,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_thunk_register
++ && SIBLING_CALL_P (peep2_next_insn (2))
+ && !reg_mentioned_p (operands[0],
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
+@@ -11888,7 +11892,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)
+@@ -11908,7 +11912,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)
+@@ -11962,7 +11966,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_thunk_register
++ && peep2_reg_dead_p (2, operands[0])"
+ [(set (pc) (match_dup 1))])
+
+ ;; Call subroutine, returning value in operand 0
+@@ -12043,7 +12049,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_thunk_register"
+ "* return ix86_output_call_insn (insn, operands[1]);"
+ [(set_attr "type" "callv")])
+
+@@ -12053,7 +12059,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_thunk_register
++ && SIBLING_CALL_P (peep2_next_insn (1))
+ && !reg_mentioned_p (operands[0],
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
+ [(parallel [(set (match_dup 2)
+@@ -12068,7 +12076,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_thunk_register
++ && SIBLING_CALL_P (peep2_next_insn (2))
+ && !reg_mentioned_p (operands[0],
+ CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
+@@ -12093,7 +12103,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)
+diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
+index fc2c81c3fb5..802245f4efe 100644
+--- a/gcc/config/i386/i386.opt
++++ b/gcc/config/i386/i386.opt
+@@ -952,6 +952,10 @@ Enum(indirect_branch) String(thunk-inline)
Value(indirect_branch_thunk_inline)
+ EnumValue
+ Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)
+
++mindirect-branch-register
++Target Report Var(ix86_indirect_branch_thunk_register) Init(0)
++Force indirect call and jump via register.
++
+ mindirect-branch-loop=
+ Target Report RejectNegative Joined Enum(indirect_branch_loop)
Var(ix86_indirect_branch_loop) Undocumented Init(indirect_branch_loop_lfence)
+
+diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
+index 8f250a2e720..fc4933e4533 100644
+--- a/gcc/config/i386/predicates.md
++++ b/gcc/config/i386/predicates.md
+@@ -635,7 +635,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 "TARGET_X32
++ || ix86_indirect_branch_thunk_register"))
+ (match_operand 0 "memory_operand"))))
+
+ ;; Return true if OP is a memory operands that can be used in sibcalls.
+@@ -664,7 +665,8 @@
+
+ ;; Return true if OP is a GOT memory operand.
+ (define_predicate "GOT_memory_operand"
+- (match_operand 0 "memory_operand")
++ (and (match_test "!ix86_indirect_branch_thunk_register")
++ (match_operand 0 "memory_operand"))
+ {
+ op = XEXP (op, 0);
+ return (GET_CODE (op) == CONST
+@@ -678,9 +680,11 @@
+ (ior (match_test "constant_call_address_operand
+ (op, mode == VOIDmode ? mode : Pmode)")
+ (match_operand 0 "call_register_no_elim_operand")
+- (ior (and (not (match_test "TARGET_X32"))
++ (ior (and (not (match_test "TARGET_X32
++ || ix86_indirect_branch_thunk_register"))
+ (match_operand 0 "memory_operand"))
+- (and (match_test "TARGET_X32 && Pmode == DImode")
++ (and (match_test "TARGET_X32 && Pmode == DImode
++ && !ix86_indirect_branch_thunk_register")
+ (match_operand 0 "GOT_memory_operand")))))
+
+ ;; Similarly, but for tail calls, in which we cannot allow memory references.
+@@ -688,14 +692,17 @@
+ (ior (match_test "constant_call_address_operand
+ (op, mode == VOIDmode ? mode : Pmode)")
+ (match_operand 0 "register_no_elim_operand")
+- (ior (and (not (match_test "TARGET_X32"))
++ (ior (and (not (match_test "TARGET_X32
++ || ix86_indirect_branch_thunk_register"))
+ (match_operand 0 "sibcall_memory_operand"))
+- (and (match_test "TARGET_X32 && Pmode == DImode")
++ (and (match_test "TARGET_X32 && Pmode == DImode
++ && !ix86_indirect_branch_thunk_register")
+ (match_operand 0 "GOT_memory_operand")))))
+
+ ;; Return true if OP is a 32-bit GOT symbol operand.
+ (define_predicate "GOT32_symbol_operand"
+- (match_test "GET_CODE (op) == CONST
++ (match_test "!ix86_indirect_branch_thunk_register
++ && GET_CODE (op) == CONST
+ && GET_CODE (XEXP (op, 0)) == UNSPEC
+ && XINT (XEXP (op, 0), 1) == UNSPEC_GOT"))
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
+new file mode 100644
+index 00000000000..ef493a05bbf
+--- /dev/null
++++ b/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 {\tlfence} } } */
++/* { 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" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
+new file mode 100644
+index 00000000000..89fc8e6e6c4
+--- /dev/null
++++ b/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 {\tlfence} } } */
++/* { 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" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
+new file mode 100644
+index 00000000000..31af7ac05b8
+--- /dev/null
++++ b/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(lfence|pause|nop)} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch
b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch
new file mode 100644
index 000000000..18b2dfaea
--- /dev/null
+++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patch
@@ -0,0 +1,263 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 4032162fb6d36e20091885d0558f91daaa0080d3 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Mon, 27 Nov 2017 08:38:41 -0800
+Subject: [PATCH 07/17] Add -mindirect-branch=thunk-extern
+
+Add -mindirect-branch=thunk-extern tests
+---
+ gcc/config/i386/i386-opts.h | 3 +-
+ gcc/config/i386/i386.opt | 3 ++
+ .../gcc.target/i386/indirect-thunk-extern-1.c | 19 ++++++++++
+ .../gcc.target/i386/indirect-thunk-extern-2.c | 19 ++++++++++
+ .../gcc.target/i386/indirect-thunk-extern-3.c | 20 ++++++++++
+ .../gcc.target/i386/indirect-thunk-extern-4.c | 20 ++++++++++
+ .../gcc.target/i386/indirect-thunk-extern-5.c | 16 ++++++++
+ .../gcc.target/i386/indirect-thunk-extern-6.c | 17 +++++++++
+ .../gcc.target/i386/indirect-thunk-extern-7.c | 43 ++++++++++++++++++++++
+ 9 files changed, 159 insertions(+), 1 deletion(-)
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+
+diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
+index f301890575a..f8d80ba7ec6 100644
+--- a/gcc/config/i386/i386-opts.h
++++ b/gcc/config/i386/i386-opts.h
+@@ -102,7 +102,8 @@ enum stack_protector_guard {
+ enum indirect_branch {
+ indirect_branch_keep,
+ indirect_branch_thunk,
+- indirect_branch_thunk_inline
++ indirect_branch_thunk_inline,
++ indirect_branch_thunk_extern
+ };
+
+ #endif
+diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
+index 68484a75022..4a932e11bf6 100644
+--- a/gcc/config/i386/i386.opt
++++ b/gcc/config/i386/i386.opt
+@@ -944,3 +944,6 @@ Enum(indirect_branch) String(thunk)
Value(indirect_branch_thunk)
+
+ EnumValue
+ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline)
++
++EnumValue
++Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+new file mode 100644
+index 00000000000..0a1f91be988
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+@@ -0,0 +1,19 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+new file mode 100644
+index 00000000000..182520ab3dc
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+@@ -0,0 +1,19 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+new file mode 100644
+index 00000000000..5c31ddc34fd
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+@@ -0,0 +1,20 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+new file mode 100644
+index 00000000000..f24d0c060f2
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+@@ -0,0 +1,20 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
+new file mode 100644
+index 00000000000..ad54aaeac4c
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
+@@ -0,0 +1,16 @@
++/* { 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 "push(?:l|q)\[ address@hidden" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
+new file mode 100644
+index 00000000000..a8e75254cfe
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
+@@ -0,0 +1,17 @@
++/* { 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 "push(?:l|q)\[ address@hidden" } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+new file mode 100644
+index 00000000000..8d39fb6f939
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+@@ -0,0 +1,43 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */
++
++void func0 (void);
++void func1 (void);
++void func2 (void);
++void func3 (void);
++void func4 (void);
++void func4 (void);
++void func5 (void);
++
++void
++bar (int i)
++{
++ switch (i)
++ {
++ default:
++ func0 ();
++ break;
++ case 1:
++ func1 ();
++ break;
++ case 2:
++ func2 ();
++ break;
++ case 3:
++ func3 ();
++ break;
++ case 4:
++ func4 ();
++ break;
++ case 5:
++ func5 ();
++ break;
++ }
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target
{ ! x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch
b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch
new file mode 100644
index 000000000..bb12c0e95
--- /dev/null
+++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patch
@@ -0,0 +1,310 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 7f4f2bf1688c81496107993080e68a29a24de702 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Wed, 15 Nov 2017 11:20:31 -0800
+Subject: [PATCH 06/17] Add -mindirect-branch=thunk-inline
+
+Add -mindirect-branch=thunk-inline tests
+---
+ gcc/config/i386/i386-opts.h | 3 +-
+ gcc/config/i386/i386.c | 30 +++++++++++-----
+ gcc/config/i386/i386.opt | 3 ++
+ .../gcc.target/i386/indirect-thunk-inline-1.c | 18 ++++++++++
+ .../gcc.target/i386/indirect-thunk-inline-2.c | 18 ++++++++++
+ .../gcc.target/i386/indirect-thunk-inline-3.c | 19 ++++++++++
+ .../gcc.target/i386/indirect-thunk-inline-4.c | 19 ++++++++++
+ .../gcc.target/i386/indirect-thunk-inline-5.c | 15 ++++++++
+ .../gcc.target/i386/indirect-thunk-inline-6.c | 16 +++++++++
+ .../gcc.target/i386/indirect-thunk-inline-7.c | 42 ++++++++++++++++++++++
+ 10 files changed, 173 insertions(+), 10 deletions(-)
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+
+diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
+index 1565d8fdc65..f301890575a 100644
+--- a/gcc/config/i386/i386-opts.h
++++ b/gcc/config/i386/i386-opts.h
+@@ -101,7 +101,8 @@ enum stack_protector_guard {
+
+ enum indirect_branch {
+ indirect_branch_keep,
+- indirect_branch_thunk
++ indirect_branch_thunk,
++ indirect_branch_thunk_inline
+ };
+
+ #endif
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index 96424361a1c..ac542f79846 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -28600,16 +28600,23 @@ static void
+ ix86_output_indirect_branch (rtx call_op, const char *xasm,
+ bool sibcall_p)
+ {
+- char thunk_name[32];
++ char thunk_name_buf[32];
++ char *thunk_name;
+ char push_buf[64];
+ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);
+
+- bool need_thunk = ix86_indirect_branch == indirect_branch_thunk;
+- if (need_bnd_p)
+- indirect_thunk_bnd_needed |= need_thunk;
++ if (ix86_indirect_branch != indirect_branch_thunk_inline)
++ {
++ bool need_thunk = ix86_indirect_branch == indirect_branch_thunk;
++ if (need_bnd_p)
++ indirect_thunk_bnd_needed |= need_thunk;
++ else
++ indirect_thunk_needed |= need_thunk;
++ indirect_thunk_name (thunk_name_buf, need_bnd_p);
++ thunk_name = thunk_name_buf;
++ }
+ else
+- indirect_thunk_needed |= need_thunk;
+- indirect_thunk_name (thunk_name, need_bnd_p);
++ thunk_name = NULL;
+
+ snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s",
+ TARGET_64BIT ? 'q' : 'l', xasm);
+@@ -28683,10 +28690,15 @@ ix86_output_indirect_branch (rtx call_op, const char
*xasm,
+
+ output_asm_insn (push_buf, &call_op);
+
+- if (need_bnd_p)
+- fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
++ if (thunk_name != NULL)
++ {
++ if (need_bnd_p)
++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
++ else
++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
++ }
+ else
+- fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
++ output_indirect_thunk (need_bnd_p);
+
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
+
+diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
+index 1773e5614cf..68484a75022 100644
+--- a/gcc/config/i386/i386.opt
++++ b/gcc/config/i386/i386.opt
+@@ -941,3 +941,6 @@ Enum(indirect_branch) String(keep)
Value(indirect_branch_keep)
+
+ EnumValue
+ Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk)
++
++EnumValue
++Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline)
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+new file mode 100644
+index 00000000000..071e6c89ac7
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+@@ -0,0 +1,18 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+new file mode 100644
+index 00000000000..804c7ccdba7
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+@@ -0,0 +1,18 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+new file mode 100644
+index 00000000000..545a981add5
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+@@ -0,0 +1,19 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+new file mode 100644
+index 00000000000..d9ff4722cff
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+@@ -0,0 +1,19 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
+new file mode 100644
+index 00000000000..f4890fe97b2
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
+@@ -0,0 +1,15 @@
++/* { 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 "push(?:l|q)\[ address@hidden" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
+new file mode 100644
+index 00000000000..81b09e73ab8
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
+@@ -0,0 +1,16 @@
++/* { 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 "push(?:l|q)\[ address@hidden" } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+new file mode 100644
+index 00000000000..a0ce06b8232
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+@@ -0,0 +1,42 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */
++
++void func0 (void);
++void func1 (void);
++void func2 (void);
++void func3 (void);
++void func4 (void);
++void func4 (void);
++void func5 (void);
++
++void
++bar (int i)
++{
++ switch (i)
++ {
++ default:
++ func0 ();
++ break;
++ case 1:
++ func1 ();
++ break;
++ case 2:
++ func2 ();
++ break;
++ case 3:
++ func3 ();
++ break;
++ case 4:
++ func4 ();
++ break;
++ case 5:
++ func5 ();
++ break;
++ }
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target
{ ! x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch
b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch
new file mode 100644
index 000000000..edb9a8de5
--- /dev/null
+++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch
@@ -0,0 +1,729 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 63024dad9c00f1613738fd766e2f0afd455b76d1 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Wed, 1 Nov 2017 16:05:50 -0700
+Subject: [PATCH 04/17] Add -mindirect-branch=thunk
+
+Add tests for -mindirect-branch=thunk
+---
+ gcc/config/i386/i386-opts.h | 5 +
+ gcc/config/i386/i386-protos.h | 1 +
+ gcc/config/i386/i386.c | 318 ++++++++++++++++++++++-
+ gcc/config/i386/i386.md | 6 +-
+ gcc/config/i386/i386.opt | 14 +
+ gcc/doc/invoke.texi | 9 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 19 ++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 19 ++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 20 ++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 20 ++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 16 ++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 17 ++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 43 +++
+ 13 files changed, 495 insertions(+), 12 deletions(-)
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+
+diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
+index 542cd0f3d67..1565d8fdc65 100644
+--- a/gcc/config/i386/i386-opts.h
++++ b/gcc/config/i386/i386-opts.h
+@@ -99,4 +99,9 @@ enum stack_protector_guard {
+ SSP_GLOBAL /* global canary */
+ };
+
++enum indirect_branch {
++ indirect_branch_keep,
++ indirect_branch_thunk
++};
++
+ #endif
+diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
+index 8bdd67eb608..b746429f420 100644
+--- a/gcc/config/i386/i386-protos.h
++++ b/gcc/config/i386/i386-protos.h
+@@ -315,6 +315,7 @@ extern enum attr_cpu ix86_schedule;
+ #endif
+
+ extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op);
++extern const char * ix86_output_indirect_jmp (rtx call_op);
+ extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load,
+ enum machine_mode mode);
+
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index 504530a00cf..96424361a1c 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -11909,6 +11909,145 @@ ix86_setup_frame_addresses (void)
+ # endif
+ #endif
+
++static int indirectlabelno;
++static bool indirect_thunk_needed = false;
++static bool indirect_thunk_bnd_needed = false;
++
++#ifndef INDIRECT_LABEL
++# define INDIRECT_LABEL "LIND"
++#endif
++
++/* Fills in the label name that should be used for the indirect thunk. */
++
++static void
++indirect_thunk_name (char name[32], bool need_bnd_p)
++{
++ if (USE_HIDDEN_LINKONCE)
++ {
++ const char *bnd = need_bnd_p ? "_bnd" : "";
++ sprintf (name, "__x86.indirect_thunk%s", bnd);
++ }
++ else
++ {
++ if (need_bnd_p)
++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);
++ else
++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);
++ }
++}
++
++static void
++output_indirect_thunk (bool need_bnd_p)
++{
++ char indirectlabel1[32];
++ char indirectlabel2[32];
++
++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, INDIRECT_LABEL,
++ indirectlabelno++);
++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, INDIRECT_LABEL,
++ indirectlabelno++);
++
++ /* Call */
++ if (need_bnd_p)
++ fputs ("\tbnd call\t", asm_out_file);
++ else
++ fputs ("\tcall\t", asm_out_file);
++ assemble_name_raw (asm_out_file, indirectlabel2);
++ fputc ('\n', asm_out_file);
++
++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
++
++ /* lfence . */
++ fprintf (asm_out_file, "\tlfence\n");
++
++ /* Jump. */
++ fputs ("\tjmp\t", asm_out_file);
++ assemble_name_raw (asm_out_file, indirectlabel1);
++ fputc ('\n', asm_out_file);
++
++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
++
++ /* LEA. */
++ rtx xops[2];
++ xops[0] = stack_pointer_rtx;
++ xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
++ output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);
++
++ if (need_bnd_p)
++ fputs ("\tbnd ret\n", asm_out_file);
++ else
++ fputs ("\tret\n", asm_out_file);
++}
++
++static void
++output_indirect_thunk_function (bool need_bnd_p)
++{
++ char name[32];
++ tree decl;
++
++ indirect_thunk_name (name, need_bnd_p);
++ decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
++ get_identifier (name),
++ build_function_type_list (void_type_node, NULL_TREE));
++ DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
++ NULL_TREE, void_type_node);
++ TREE_PUBLIC (decl) = 1;
++ TREE_STATIC (decl) = 1;
++ DECL_IGNORED_P (decl) = 1;
++
++#if TARGET_MACHO
++ if (TARGET_MACHO)
++ {
++ switch_to_section (darwin_sections[picbase_thunk_section]);
++ fputs ("\t.weak_definition\t", asm_out_file);
++ assemble_name (asm_out_file, name);
++ fputs ("\n\t.private_extern\t", asm_out_file);
++ assemble_name (asm_out_file, name);
++ putc ('\n', asm_out_file);
++ ASM_OUTPUT_LABEL (asm_out_file, name);
++ DECL_WEAK (decl) = 1;
++ }
++ else
++#endif
++ if (USE_HIDDEN_LINKONCE)
++ {
++ cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME
(decl));
++
++ targetm.asm_out.unique_section (decl, 0);
++ switch_to_section (get_named_section (decl, NULL, 0));
++
++ targetm.asm_out.globalize_label (asm_out_file, name);
++ fputs ("\t.hidden\t", asm_out_file);
++ assemble_name (asm_out_file, name);
++ putc ('\n', asm_out_file);
++ ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
++ }
++ else
++ {
++ switch_to_section (text_section);
++ ASM_OUTPUT_LABEL (asm_out_file, name);
++ }
++
++ DECL_INITIAL (decl) = make_node (BLOCK);
++ current_function_decl = decl;
++ allocate_struct_function (decl, false);
++ init_function_start (decl);
++ /* We're about to hide the function body from callees of final_* by
++ emitting it directly; tell them we're a thunk, if they care. */
++ cfun->is_thunk = true;
++ first_function_block_is_cold = false;
++ /* Make sure unwind info is emitted for the thunk if needed. */
++ final_start_function (emit_barrier (), asm_out_file, 1);
++
++ output_indirect_thunk (need_bnd_p);
++
++ final_end_function ();
++ init_insn_lengths ();
++ free_after_compilation (cfun);
++ set_cfun (NULL);
++ current_function_decl = NULL;
++}
++
+ static int pic_labels_used;
+
+ /* Fills in the label name that should be used for a pc thunk for
+@@ -11935,6 +12074,11 @@ ix86_code_end (void)
+ rtx xops[2];
+ int regno;
+
++ if (indirect_thunk_needed)
++ output_indirect_thunk_function (false);
++ if (indirect_thunk_bnd_needed)
++ output_indirect_thunk_function (true);
++
+ for (regno = AX_REG; regno <= SP_REG; regno++)
+ {
+ char name[32];
+@@ -28452,12 +28596,132 @@ ix86_nopic_noplt_attribute_p (rtx call_op)
+ return false;
+ }
+
++static void
++ix86_output_indirect_branch (rtx call_op, const char *xasm,
++ bool sibcall_p)
++{
++ char thunk_name[32];
++ char push_buf[64];
++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);
++
++ bool need_thunk = ix86_indirect_branch == indirect_branch_thunk;
++ if (need_bnd_p)
++ indirect_thunk_bnd_needed |= need_thunk;
++ else
++ indirect_thunk_needed |= need_thunk;
++ indirect_thunk_name (thunk_name, need_bnd_p);
++
++ snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s",
++ TARGET_64BIT ? 'q' : 'l', xasm);
++
++ if (sibcall_p)
++ {
++ output_asm_insn (push_buf, &call_op);
++ if (thunk_name != NULL)
++ {
++ if (need_bnd_p)
++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
++ else
++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
++ }
++ else
++ output_indirect_thunk (need_bnd_p);
++ }
++ else
++ {
++ char indirectlabel1[32];
++ char indirectlabel2[32];
++
++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,
++ INDIRECT_LABEL,
++ indirectlabelno++);
++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,
++ INDIRECT_LABEL,
++ indirectlabelno++);
++
++ /* Jump. */
++ if (need_bnd_p)
++ fputs ("\tbnd jmp\t", asm_out_file);
++ else
++ fputs ("\tjmp\t", asm_out_file);
++ assemble_name_raw (asm_out_file, indirectlabel2);
++ fputc ('\n', asm_out_file);
++
++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
++
++ if (MEM_P (call_op))
++ {
++ struct ix86_address parts;
++ rtx addr = XEXP (call_op, 0);
++ if (ix86_decompose_address (addr, &parts)
++ && parts.base == stack_pointer_rtx)
++ {
++ /* Since call will adjust stack by -UNITS_PER_WORD,
++ we must convert "disp(stack, index, scale)" to
++ "disp+UNITS_PER_WORD(stack, index, scale)". */
++ if (parts.index)
++ {
++ addr = gen_rtx_MULT (Pmode, parts.index,
++ GEN_INT (parts.scale));
++ addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
++ addr);
++ }
++ else
++ addr = stack_pointer_rtx;
++
++ rtx disp;
++ if (parts.disp != NULL_RTX)
++ disp = plus_constant (Pmode, parts.disp,
++ UNITS_PER_WORD);
++ else
++ disp = GEN_INT (UNITS_PER_WORD);
++
++ addr = gen_rtx_PLUS (Pmode, addr, disp);
++ call_op = gen_rtx_MEM (GET_MODE (call_op), addr);
++ }
++ }
++
++ output_asm_insn (push_buf, &call_op);
++
++ if (need_bnd_p)
++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
++ else
++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
++
++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
++
++ /* Call. */
++ if (need_bnd_p)
++ fputs ("\tbnd call\t", asm_out_file);
++ else
++ fputs ("\tcall\t", asm_out_file);
++ assemble_name_raw (asm_out_file, indirectlabel1);
++ fputc ('\n', asm_out_file);
++ }
++}
++
++const char *
++ix86_output_indirect_jmp (rtx call_op)
++{
++ if (ix86_red_zone_size == 0
++ && ix86_indirect_branch != indirect_branch_keep)
++ {
++ ix86_output_indirect_branch (call_op, "%0", true);
++ return "";
++ }
++ else
++ return "%!jmp\t%A0";
++}
++
+ /* Output the assembly for a call instruction. */
+
+ const char *
+ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
+ {
+ bool direct_p = constant_call_address_operand (call_op, VOIDmode);
++ bool output_indirect_p
++ = (!TARGET_SEH
++ && ix86_indirect_branch != indirect_branch_keep);
+ bool seh_nop_p = false;
+ const char *xasm;
+
+@@ -28467,10 +28731,21 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
+ {
+ if (ix86_nopic_noplt_attribute_p (call_op))
+ {
++ direct_p = false;
+ if (TARGET_64BIT)
+- xasm = "address@hidden(%%rip)|[QWORD PTR address@hidden";
++ {
++ if (output_indirect_p)
++ xasm = "address@hidden(%%rip)|[QWORD PTR address@hidden";
++ else
++ xasm = "address@hidden(%%rip)|[QWORD PTR address@hidden";
++ }
+ else
+- xasm = "address@hidden|[DWORD PTR address@hidden";
++ {
++ if (output_indirect_p)
++ xasm = "address@hidden|[DWORD PTR address@hidden";
++ else
++ xasm = "address@hidden|[DWORD PTR address@hidden";
++ }
+ }
+ else
+ xasm = "%!jmp\t%P0";
+@@ -28480,9 +28755,17 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
+ else if (TARGET_SEH)
+ xasm = "%!rex.W jmp\t%A0";
+ else
+- xasm = "%!jmp\t%A0";
++ {
++ if (output_indirect_p)
++ xasm = "%0";
++ else
++ xasm = "%!jmp\t%A0";
++ }
+
+- output_asm_insn (xasm, &call_op);
++ if (output_indirect_p && !direct_p)
++ ix86_output_indirect_branch (call_op, xasm, true);
++ else
++ output_asm_insn (xasm, &call_op);
+ return "";
+ }
+
+@@ -28520,18 +28803,37 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
+ {
+ if (ix86_nopic_noplt_attribute_p (call_op))
+ {
++ direct_p = false;
+ if (TARGET_64BIT)
+- xasm = "address@hidden(%%rip)|[QWORD PTR address@hidden";
++ {
++ if (output_indirect_p)
++ xasm = "address@hidden(%%rip)|[QWORD PTR address@hidden";
++ else
++ xasm = "address@hidden(%%rip)|[QWORD PTR address@hidden";
++ }
+ else
+- xasm = "address@hidden|[DWORD PTR address@hidden";
++ {
++ if (output_indirect_p)
++ xasm = "address@hidden|[DWORD PTR address@hidden";
++ else
++ xasm = "address@hidden|[DWORD PTR address@hidden";
++ }
+ }
+ else
+ xasm = "%!call\t%P0";
+ }
+ else
+- xasm = "%!call\t%A0";
++ {
++ if (output_indirect_p)
++ xasm = "%0";
++ else
++ xasm = "%!call\t%A0";
++ }
+
+- output_asm_insn (xasm, &call_op);
++ if (output_indirect_p && !direct_p)
++ ix86_output_indirect_branch (call_op, xasm, false);
++ else
++ output_asm_insn (xasm, &call_op);
+
+ if (seh_nop_p)
+ return "nop";
+diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
+index 81cfba57afc..01b7b2039e6 100644
+--- a/gcc/config/i386/i386.md
++++ b/gcc/config/i386/i386.md
+@@ -11615,7 +11615,7 @@
+ (define_insn "*indirect_jump"
+ [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
+ ""
+- "%!jmp\t%A0"
++ "* return ix86_output_indirect_jmp (operands[0]);"
+ [(set_attr "type" "ibr")
+ (set_attr "length_immediate" "0")
+ (set_attr "maybe_prefix_bnd" "1")])
+@@ -11665,7 +11665,7 @@
+ [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
+ (use (label_ref (match_operand 1)))]
+ ""
+- "%!jmp\t%A0"
++ "* return ix86_output_indirect_jmp (operands[0]);"
+ [(set_attr "type" "ibr")
+ (set_attr "length_immediate" "0")
+ (set_attr "maybe_prefix_bnd" "1")])
+@@ -12337,7 +12337,7 @@
+ [(simple_return)
+ (use (match_operand:SI 0 "register_operand" "r"))]
+ "reload_completed"
+- "%!jmp\t%A0"
++ "* return ix86_output_indirect_jmp (operands[0]);"
+ [(set_attr "type" "ibr")
+ (set_attr "length_immediate" "0")
+ (set_attr "maybe_prefix_bnd" "1")])
+diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
+index 9384e29b1de..1773e5614cf 100644
+--- a/gcc/config/i386/i386.opt
++++ b/gcc/config/i386/i386.opt
+@@ -927,3 +927,17 @@ Attempt to avoid generating instruction sequences
containing ret bytes.
+ mgeneral-regs-only
+ Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags)
Save
+ Generate code which uses only the general registers.
++
++mindirect-branch=
++Target Report RejectNegative Joined Enum(indirect_branch)
Var(ix86_indirect_branch) Init(indirect_branch_keep)
++Update indirect call and jump.
++
++Enum
++Name(indirect_branch) Type(enum indirect_branch)
++Known indirect branch choices (for use with the -mindirect-branch= option):
++
++EnumValue
++Enum(indirect_branch) String(keep) Value(indirect_branch_keep)
++
++EnumValue
++Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk)
+diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
+index a0fb09eb9e1..fafda2926bd 100644
+--- a/gcc/doc/invoke.texi
++++ b/gcc/doc/invoke.texi
+@@ -1210,7 +1210,7 @@ See RS/6000 and PowerPC Options.
+ -msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol
+ -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol
+ address@hidden address@hidden @gol
+--mmitigate-rop -mgeneral-regs-only}
++-mmitigate-rop -mgeneral-regs-only address@hidden
+
+ @emph{x86 Windows Options}
+ @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
+@@ -25648,6 +25648,13 @@ Generate code that uses only the general-purpose
registers. This
+ prevents the compiler from using floating-point, vector, mask and bound
+ registers.
+
address@hidden address@hidden
address@hidden -mindirect-branch
++Update indirect call and jump with @var{choice}. The default is
address@hidden, which keeps indirect call and jump unmodified.
address@hidden converts indirect call and jump to push and
++PC-relative call thunk.
++
+ @end table
+
+ These @samp{-m} switches are supported in addition to the above
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+new file mode 100644
+index 00000000000..d8b6f5a06a5
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+@@ -0,0 +1,19 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+new file mode 100644
+index 00000000000..f7d5cb315a8
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+@@ -0,0 +1,19 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+new file mode 100644
+index 00000000000..736d7cda058
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+@@ -0,0 +1,20 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+new file mode 100644
+index 00000000000..cef9b10513e
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+@@ -0,0 +1,20 @@
++/* { 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 "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
+new file mode 100644
+index 00000000000..1a9bb0e431e
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
+@@ -0,0 +1,16 @@
++/* { 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 "push(?:l|q)\[ address@hidden" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
+new file mode 100644
+index 00000000000..bc7d20ec6ad
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
+@@ -0,0 +1,17 @@
++/* { 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 "push(?:l|q)\[ address@hidden" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+new file mode 100644
+index 00000000000..ea0fa312f64
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+@@ -0,0 +1,43 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */
++
++void func0 (void);
++void func1 (void);
++void func2 (void);
++void func3 (void);
++void func4 (void);
++void func4 (void);
++void func5 (void);
++
++void
++bar (int i)
++{
++ switch (i)
++ {
++ default:
++ func0 ();
++ break;
++ case 1:
++ func1 ();
++ break;
++ case 2:
++ func2 ();
++ break;
++ case 3:
++ func3 ();
++ break;
++ case 4:
++ func4 ();
++ break;
++ case 5:
++ func5 ();
++ break;
++ }
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target
{ ! x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch
b/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch
new file mode 100644
index 000000000..2b4ac1b81
--- /dev/null
+++
b/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-indirect-branch-.patch
@@ -0,0 +1,554 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 2c14ecf03978ce6c60e021a2b0d72778a5fe0982 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Tue, 12 Dec 2017 12:34:26 -0800
+Subject: [PATCH 14/17] Add -mno-indirect-branch-register to indirect branch
+ tests
+
+---
+ gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 2 +-
+ 44 files changed, 44 insertions(+), 44 deletions(-)
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+index 318db1e7f5c..b0625207b92 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+index f2700dd36cf..0b289685e6b 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+index 46685d9a674..79a9f76285f 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+index 8f701775cea..901d94213bd 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
+index f88ac31d07a..d2c9bd9d7ca 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target *-*-linux* } } */
+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt
-mindirect-branch=thunk" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep
-fpic -fno-plt -mindirect-branch=thunk" } */
+
+ extern void bar (void);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
+index d745116d321..f8b028db7a2 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target *-*-linux* } } */
+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt
-mindirect-branch=thunk" } */
++/* { dg-options "-O2 -mno-indirect-branch-register
-mno-indirect-branch-register -mno-indirect-branch-register
-mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */
+
+ extern void bar (void);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+index 969cb8c6ddc..465775407ec 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
++++ b/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);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+index 12a61c3bbc7..5309d5a3eaa 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+index a06907933a2..dd1efca49fd 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+index 7f56725e6b6..e97ca636020 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+index fd4ab1dbaa0..b547cbbf255 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+index 1ffbf3b1181..353689dc415 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+index 1559072919a..1edef7208f4 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+index 1717e7bb436..c2e816cdfc6 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
++++ b/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);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+index 20903b0f79d..5c10de47b7c 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
++++ b/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];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+index aef4bd144f4..9eedd9a5a82 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
++++ b/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];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
+index 2cc0343f828..b2b8587eac7 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk
-fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep
-mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
+
+ void bar (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
+index 91560fef661..9459a2417f4 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */
+-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk
-fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
++/* { dg-options "-O2 -mno-indirect-branch-register
-mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk
-fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
+
+ void bar (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+index dc6bd10af4c..b0aa3811e65 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+index 955aa256529..75fabcd988c 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+index 1537239416f..1d9dff2e834 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+index c82e53068fe..5b464155e38 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
+index 23548d85f78..55ce91c73ec 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target *-*-linux* } } */
+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt
-mindirect-branch=thunk-extern" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep
-fpic -fno-plt -mindirect-branch=thunk-extern" } */
+
+ extern void bar (void);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
+index 56c2fe92f25..06180e7bee9 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target *-*-linux* } } */
+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt
-mindirect-branch=thunk-extern" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep
-fpic -fno-plt -mindirect-branch=thunk-extern" } */
+
+ extern void bar (void);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+index e12b88593fe..790a05cec3e 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
++++ b/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);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+index 87b5429702f..1ce8ca5aff1 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+index a496a41a918..f6b71e868bd 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+index 6fe5ce71abf..84a09d4d0d6 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+index 65cd997a33f..cfe3aefa0bf 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
+index 7321d015c02..6411454243f 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target *-*-linux* } } */
+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt
-mindirect-branch=thunk-inline" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep
-fpic -fno-plt -mindirect-branch=thunk-inline" } */
+
+ extern void bar (void);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
+index 6ec2e5621ab..d4297fe21c4 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile { target *-*-linux* } } */
+-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt
-mindirect-branch=thunk-inline" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep
-fpic -fno-plt -mindirect-branch=thunk-inline" } */
+
+ extern void bar (void);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+index a3d1a13cded..eb318efdf4d 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
++++ b/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);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
+index f0e8f4949c8..605e32bb584 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=pause
-fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk
-mindirect-branch-loop=pause -fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
+index a577ac2568a..dd7a7b60621 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=nop
-fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk
-mindirect-branch-loop=nop -fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
+index c8dcb9639c4..338f22c373c 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=lfence
-fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=thunk
-mindirect-branch-loop=lfence -fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
+index 8569dfc92c3..3b083ee30a8 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk-inline
-mindirect-branch-loop=pause -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register
-mindirect-branch=thunk-inline -mindirect-branch-loop=pause -fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
+index bcf19c9ede1..31a9a81a911 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
+@@ -1,5 +1,5 @@
+ /* { dg-do compile } */
+-/* { dg-options "-O2 -mindirect-branch=thunk-extern
-mindirect-branch-loop=pause -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register
-mindirect-branch=thunk-extern -mindirect-branch-loop=pause -fno-pic" } */
+
+ typedef void (*dispatch_t)(long offset);
+
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
+index aecea4224f9..74f37ee9a62 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
+index 3bacfb54dfd..0a52318e86b 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
+index 851115ac507..d2f775490ea 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
+index 7acb6fa5eae..82d46165f3e 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
++++ b/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")));
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
+index bf340fac7c6..6711eb27fa8 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
+index 735f8648c96..37758c33371 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
++++ b/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);
+
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
+index 569e5f47973..70771ea35d7 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
++++ b/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);
+
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch
b/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch
new file mode 100644
index 000000000..e21bb5039
--- /dev/null
+++
b/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fcheck-pointer-.patch
@@ -0,0 +1,134 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From ece041bc3083aabd00fab9de5ba409fbd7dcad8c Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Mon, 4 Dec 2017 12:58:20 -0800
+Subject: [PATCH 05/17] Add tests for -mindirect-branch=thunk
+ -fcheck-pointer-bounds -mmpx
+
+---
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 19 +++++++++++++++++++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 20 ++++++++++++++++++++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 18 ++++++++++++++++++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 19 +++++++++++++++++++
+ 4 files changed, 76 insertions(+)
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+new file mode 100644
+index 00000000000..a5b1d38e061
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { ! x32 } } } */
++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx
-fno-pic" } */
++
++void (*dispatch) (char *);
++char buf[10];
++
++void
++foo (void)
++{
++ dispatch (buf);
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } }
*/
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "bnd ret" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+new file mode 100644
+index 00000000000..a42add209e2
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { ! x32 } } } */
++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx
-fno-pic" } */
++
++void (*dispatch) (char *);
++char buf[10];
++
++int
++foo (void)
++{
++ dispatch (buf);
++ return 0;
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } }
*/
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "bnd ret" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
+new file mode 100644
+index 00000000000..265e010a0fe
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
+@@ -0,0 +1,18 @@
++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */
++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx
-fpic -fno-plt" } */
++
++void bar (char *);
++char buf[10];
++
++void
++foo (void)
++{
++ bar (buf);
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ address@hidden" } } */
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } }
*/
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "bnd ret" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
+new file mode 100644
+index 00000000000..1c01bcb7fc6
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */
++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx
-fpic -fno-plt" } */
++
++void bar (char *);
++char buf[10];
++
++int
++foo (void)
++{
++ bar (buf);
++ return 0;
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ address@hidden" } } */
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler "bnd ret" } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch
b/gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch
new file mode 100644
index 000000000..b22e364af
--- /dev/null
+++
b/gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jump.patch
@@ -0,0 +1,147 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From f96e28553b0f2253184441f22852d76976e19968 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Tue, 12 Dec 2017 19:15:25 -0800
+Subject: [PATCH 15/17] Disable red zone with local indirect jump
+
+---
+ gcc/config/i386/i386-protos.h | 2 +-
+ gcc/config/i386/i386.c | 22 +++++++++++++++++-----
+ gcc/config/i386/i386.h | 4 ++++
+ gcc/config/i386/i386.md | 8 +++++---
+ 4 files changed, 27 insertions(+), 9 deletions(-)
+
+diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
+index 213663811de..a78bfa00427 100644
+--- a/gcc/config/i386/i386-protos.h
++++ b/gcc/config/i386/i386-protos.h
+@@ -315,7 +315,7 @@ extern enum attr_cpu ix86_schedule;
+ #endif
+
+ extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op);
+-extern const char * ix86_output_indirect_jmp (rtx call_op);
++extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p);
+ extern const char * ix86_output_function_return (bool long_p);
+ extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load,
+ enum machine_mode mode);
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index 7ae3523095c..344cafe3dac 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -4209,12 +4209,19 @@ make_pass_stv (gcc::context *ctxt)
+ return new pass_stv (ctxt);
+ }
+
+-/* Return true if a red-zone is in use. */
++/* Return true if a red-zone is in use. We can't use red-zone when
++ there are local indirect jumps, like "indirect_jump" or "tablejump",
++ which jumps to another place in the function, since "call" in the
++ indirect thunk pushes the return address onto stack, destroying
++ red-zone. */
+
+ bool
+ ix86_using_red_zone (void)
+ {
+- return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI;
++ return (TARGET_RED_ZONE
++ && !TARGET_64BIT_MS_ABI
++ && (!cfun->machine->has_local_indirect_jump
++ || cfun->machine->indirect_branch_type == indirect_branch_keep));
+ }
+
+ /* Return a string that documents the current -m options. The caller is
+@@ -28919,11 +28926,16 @@ ix86_output_indirect_branch (rtx call_op, const char
*xasm,
+ }
+
+ const char *
+-ix86_output_indirect_jmp (rtx call_op)
++ix86_output_indirect_jmp (rtx call_op, bool ret_p)
+ {
+- if (ix86_red_zone_size == 0
+- && cfun->machine->indirect_branch_type != indirect_branch_keep)
++ if (cfun->machine->indirect_branch_type != indirect_branch_keep)
+ {
++ /* We can't have red-zone if this isn't a function return since
++ "call" in the indirect thunk pushes the return address onto
++ stack, destroying red-zone. */
++ if (!ret_p && ix86_red_zone_size != 0)
++ gcc_unreachable ();
++
+ ix86_output_indirect_branch (call_op, "%0", true);
+ return "";
+ }
+diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
+index f248f3ba2f5..5f30d3f8d19 100644
+--- a/gcc/config/i386/i386.h
++++ b/gcc/config/i386/i386.h
+@@ -2607,6 +2607,10 @@ struct GTY(()) machine_function {
+ /* How to generate indirec branch. */
+ ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3;
+
++ /* If true, the current function has local indirect jumps, like
++ "indirect_jump" or "tablejump". */
++ BOOL_BITFIELD has_local_indirect_jump : 1;
++
+ /* How to generate function return. */
+ ENUM_BITFIELD(indirect_branch) function_return_type : 3;
+
+diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
+index 473fa5c089b..ea95aad7540 100644
+--- a/gcc/config/i386/i386.md
++++ b/gcc/config/i386/i386.md
+@@ -11610,12 +11610,13 @@
+ {
+ if (TARGET_X32 || ix86_indirect_branch_thunk_register)
+ operands[0] = convert_memory_address (word_mode, operands[0]);
++ cfun->machine->has_local_indirect_jump = true;
+ })
+
+ (define_insn "*indirect_jump"
+ [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
+ ""
+- "* return ix86_output_indirect_jmp (operands[0]);"
++ "* return ix86_output_indirect_jmp (operands[0], false);"
+ [(set_attr "type" "ibr")
+ (set_attr "length_immediate" "0")
+ (set_attr "maybe_prefix_bnd" "1")])
+@@ -11659,13 +11660,14 @@
+
+ if (TARGET_X32 || ix86_indirect_branch_thunk_register)
+ operands[0] = convert_memory_address (word_mode, operands[0]);
++ cfun->machine->has_local_indirect_jump = true;
+ })
+
+ (define_insn "*tablejump_1"
+ [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
+ (use (label_ref (match_operand 1)))]
+ ""
+- "* return ix86_output_indirect_jmp (operands[0]);"
++ "* return ix86_output_indirect_jmp (operands[0], false);"
+ [(set_attr "type" "ibr")
+ (set_attr "length_immediate" "0")
+ (set_attr "maybe_prefix_bnd" "1")])
+@@ -12342,7 +12344,7 @@
+ [(simple_return)
+ (use (match_operand:SI 0 "register_operand" "r"))]
+ "reload_completed"
+- "* return ix86_output_indirect_jmp (operands[0]);"
++ "* return ix86_output_indirect_jmp (operands[0], true);"
+ [(set_attr "type" "ibr")
+ (set_attr "length_immediate" "0")
+ (set_attr "maybe_prefix_bnd" "1")])
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch
b/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch
new file mode 100644
index 000000000..6379270df
--- /dev/null
+++
b/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_rax-etc.-to-re.patch
@@ -0,0 +1,926 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From a072725899c551d9f3f06f3595e2a49748ab0187 Mon Sep 17 00:00:00 2001
+From: David Woodhouse <address@hidden>
+Date: Sun, 7 Jan 2018 17:27:09 +0000
+Subject: [PATCH 17/17] Rename thunks to __x86_indirect_thunk_rax etc. to
+ remove dots
+
+---
+ gcc/config/i386/i386.c | 8 ++++----
+ gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c | 6 +++---
+ gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 10 +++++-----
+ gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 10 +++++-----
+ gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 10 +++++-----
+ gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 6 +++---
+ gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 6 +++---
+ gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 6 +++---
+ gcc/testsuite/gcc.target/i386/ret-thunk-16.c | 4 ++--
+ gcc/testsuite/gcc.target/i386/ret-thunk-2.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-4.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-5.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-6.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-7.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-8.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 10 +++++-----
+ 58 files changed, 105 insertions(+), 105 deletions(-)
+
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index 6cb0681233a..9e6c9bdb514 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -12006,13 +12006,13 @@ indirect_thunk_name (char name[32], int regno, bool
need_bnd_p,
+ reg_prefix = TARGET_64BIT ? "r" : "e";
+ else
+ reg_prefix = "";
+- sprintf (name, "__x86.indirect_thunk%s.%s%s",
++ sprintf (name, "__x86_indirect_thunk%s_%s%s",
+ bnd, reg_prefix, reg_names[regno]);
+ }
+ else
+ {
+ const char *ret = ret_p ? "return" : "indirect";
+- sprintf (name, "__x86.%s_thunk%s", ret, bnd);
++ sprintf (name, "__x86_%s_thunk%s", ret, bnd);
+ }
+ }
+ else
+@@ -12119,7 +12119,7 @@ output_indirect_thunk_function (bool need_bnd_p, int
regno)
+ char name[32];
+ tree decl;
+
+- /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */
++ /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */
+ indirect_thunk_name (name, regno, need_bnd_p, false);
+ decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
+ get_identifier (name),
+@@ -12165,7 +12165,7 @@ output_indirect_thunk_function (bool need_bnd_p, int
regno)
+
+ if (regno < 0)
+ {
+- /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */
++ /* Create alias for __x86_return_thunk/__x86_return_thunk_bnd. */
+ char alias[32];
+
+ indirect_thunk_name (alias, regno, need_bnd_p, true);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+index b0625207b92..f4f2b7debe0 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+index 0b289685e6b..d4e5dadd966 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+index 79a9f76285f..9802fae5d04 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+index 901d94213bd..fad3105b50d 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
+index d2c9bd9d7ca..e44f2ff5682 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
+@@ -10,7 +10,7 @@ foo (void)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ address@hidden" } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
+index f8b028db7a2..f1e03a30854 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
+@@ -11,7 +11,7 @@ foo (void)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ address@hidden" } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+index 465775407ec..fc91a334459 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+@@ -36,8 +36,8 @@ bar (int i)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target
{ ! x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+index 5309d5a3eaa..a8ab95b6451 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+@@ -15,8 +15,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+index dd1efca49fd..467d62324d5 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+index e97ca636020..02223f8d0f4 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+@@ -17,5 +17,5 @@ male_indirect_jump (long offset)
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+index b547cbbf255..a80b46af934 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+@@ -16,5 +16,5 @@ male_indirect_jump (long offset)
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+index 353689dc415..4bb1c5f9220 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+@@ -17,6 +17,6 @@ male_indirect_jump (long offset)
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 }
} } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32
} } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+index 1edef7208f4..4e33a638862 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+@@ -16,6 +16,6 @@ male_indirect_jump (long offset)
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 }
} } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32
} } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+index c2e816cdfc6..427ba3ddbb4 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+@@ -37,8 +37,8 @@ bar (int i)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target
{ ! x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
+index af1bb125a22..c246f974610 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
+@@ -36,6 +36,6 @@ bar (int i)
+ }
+ }
+
+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+index 5c10de47b7c..3399ad56a7f 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+@@ -12,7 +12,7 @@ foo (void)
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+ /* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } }
*/
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } }
*/
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "bnd ret" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+index 9eedd9a5a82..daa9528f7bd 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+@@ -13,7 +13,7 @@ foo (void)
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+ /* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } }
*/
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } }
*/
+ /* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "bnd ret" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
+index b2b8587eac7..647ec5a4ade 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
+@@ -11,7 +11,7 @@ foo (void)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ address@hidden" } } */
+-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk_bnd" } }
*/
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } }
*/
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "bnd ret" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
+index 9459a2417f4..3a7a1cea8bc 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
+@@ -12,7 +12,7 @@ foo (void)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ address@hidden" } } */
+-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk" } } */
+ /* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler "bnd ret" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+index b0aa3811e65..5c20a35ecec 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+index 75fabcd988c..b2fb6e1bcd2 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+index 1d9dff2e834..9c84547cd7c 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 }
} } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32
} } } } */
+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+index 5b464155e38..457849564bb 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 }
} } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32
} } } } */
+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
+index 55ce91c73ec..5c07e02df6a 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
+@@ -10,7 +10,7 @@ foo (void)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ address@hidden" } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
+index 06180e7bee9..3eb440693a0 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
+@@ -13,5 +13,5 @@ foo (void)
+ /* { dg-final { scan-assembler "push(?:l|q)\[ address@hidden" } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+index 790a05cec3e..d4747ea0764 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+@@ -36,8 +36,8 @@ bar (int i)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target
{ ! x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+index 1ce8ca5aff1..f7fad345ca4 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+@@ -14,5 +14,5 @@ male_indirect_jump (long offset)
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+index f6b71e868bd..91388544a20 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+@@ -14,5 +14,5 @@ male_indirect_jump (long offset)
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+index 84a09d4d0d6..69f03e6472e 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+@@ -15,5 +15,5 @@ male_indirect_jump (long offset)
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+index cfe3aefa0bf..226b776abcf 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+@@ -15,5 +15,5 @@ male_indirect_jump (long offset)
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
+index 6411454243f..b9120017c10 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
+@@ -12,4 +12,4 @@ foo (void)
+ /* { dg-final { scan-assembler "push(?:l|q)\[ address@hidden" } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
+index d4297fe21c4..fbd6f9ec457 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
+@@ -13,4 +13,4 @@ foo (void)
+ /* { dg-final { scan-assembler "push(?:l|q)\[ address@hidden" } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+index eb318efdf4d..2553c56f97f 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+@@ -39,4 +39,4 @@ bar (int i)
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
+index 605e32bb584..c266ca6f2da 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tpause} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
+index dd7a7b60621..f7c1cf6c45a 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tnop} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
+index 338f22c373c..ef5c4b84312 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
+index 3b083ee30a8..941fcdaffb1 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
+@@ -15,5 +15,5 @@ male_indirect_jump (long offset)
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tpause} } } */
+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
+index 31a9a81a911..0c5ace58358 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
+index ef493a05bbf..1a28abb4604 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
+@@ -11,12 +11,12 @@ 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\]*__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 {\tlfence} } } */
+ /* { 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" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk_" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk_bnd\n" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
+index 89fc8e6e6c4..428d6f9e986 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
+@@ -17,4 +17,4 @@ male_indirect_jump (long offset)
+ /* { dg-final { scan-assembler {\tlfence} } } */
+ /* { 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" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
+index 31af7ac05b8..28dcdcf2855 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
+@@ -11,7 +11,7 @@ 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\]*__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(lfence|pause|nop)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c
+index 406956f48e5..07f382c21b2 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c
+@@ -6,7 +6,7 @@ foo (void)
+ {
+ }
+
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
+index 74f37ee9a62..da8029bad49 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
+@@ -12,11 +12,11 @@ foo (void)
+
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
+ /* { dg-final { scan-assembler-times {\tlfence} 2 } } */
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 }
} } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } }
} } */
+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target { x32 } } } } */
+-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target {
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } }
} } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target { x32 } } } } */
++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32
} } } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
+index 0a52318e86b..6964997871d 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
+@@ -10,13 +10,13 @@ foo (void)
+ return 0;
+ }
+
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
+ /* { dg-final { scan-assembler-times {\tlfence} 1 } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 }
} } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } }
} } */
+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target { x32 } } } } */
+-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target {
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } }
} } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target { x32 } } } } */
++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32
} } } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
+index d2f775490ea..ff0234bd17d 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
+@@ -10,12 +10,12 @@ foo (void)
+ return 0;
+ }
+
+-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
+ /* { dg-final { scan-assembler-times {\tlfence} 1 } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } }
} } */
+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target { x32 } } } } */
+-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target {
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } }
} } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target { x32 } } } } */
++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32
} } } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
+index 82d46165f3e..a5b16472051 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
+@@ -11,11 +11,11 @@ foo (void)
+ return 0;
+ }
+
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
+ /* { dg-final { scan-assembler-times {\tlfence} 2 } } */
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 }
} } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */
+-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.indirect_thunk" } } */
+-/* { dg-final { scan-assembler-not "call\[
\t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax"
{ target { x32 } } } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
+index 6711eb27fa8..219d71548bf 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
+@@ -12,10 +12,10 @@ foo (void)
+ }
+
+ /* { dg-final { scan-assembler-times {\tlfence} 1 } } */
+-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 }
} } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target { x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target { x32 } } } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
+index 37758c33371..bad6b16820d 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
+@@ -11,11 +11,11 @@ foo (void)
+ return 0;
+ }
+
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-times {\tlfence} 1 } } */
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 }
} } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-16.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c
+index cf3920563e0..173fe243d7b 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-16.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c
+@@ -11,8 +11,8 @@ foo (void)
+ return 0;
+ }
+
+-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+-/* { dg-final { scan-assembler-not "__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86_return_thunk" } } */
+ /* { dg-final { scan-assembler-not {\tlfence} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-2.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c
+index 190947cc2ca..5516813a290 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-2.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c
+@@ -9,4 +9,4 @@ foo (void)
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-3.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c
+index d71de3ac520..9f1ade857ef 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-3.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c
+@@ -6,7 +6,7 @@ foo (void)
+ {
+ }
+
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
+ /* { dg-final { scan-assembler-not {\tlfence} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-4.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c
+index 68c22122f0d..abecde0a550 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-4.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c
+@@ -6,7 +6,7 @@ foo (void)
+ {
+ }
+
+-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
+ /* { dg-final { scan-assembler-not {\tlfence} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-5.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c
+index 28c576e2267..3b51a9931db 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-5.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c
+@@ -8,7 +8,7 @@ foo (void)
+ {
+ }
+
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c
+index 10ad40b9c26..52160e0ee77 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c
+@@ -10,4 +10,4 @@ foo (void)
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-7.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c
+index 7ac0beaa73e..65819c2ab76 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-7.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c
+@@ -7,7 +7,7 @@ foo (void)
+ {
+ }
+
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
+ /* { dg-final { scan-assembler-not {\tlfence} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-8.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c
+index 777ab7c8088..a6a1bbc054b 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-8.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c
+@@ -8,7 +8,7 @@ foo (void)
+ {
+ }
+
+-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
+ /* { dg-final { scan-assembler-not {\tlfence} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
+index 70771ea35d7..21a0e6bde3d 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
+@@ -10,14 +10,14 @@ foo (void)
+ return 0;
+ }
+
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
+-/* { dg-final { scan-assembler-not "__x86.return_thunk:" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
++/* { dg-final { scan-assembler-not "__x86_return_thunk:" } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+-/* { dg-final { scan-assembler "__x86.indirect_thunk:" } } */
++/* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */
+ /* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 }
} } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { !
x32 } } } } */
+ /* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */
+-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target { x32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" {
target { x32 } } } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch
b/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch
new file mode 100644
index 000000000..bd6797816
--- /dev/null
+++
b/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirect-branch-via.patch
@@ -0,0 +1,623 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From e4e33b44a49eaa102806589ce12f021ab6a1e5f1 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Wed, 13 Dec 2017 12:59:50 -0800
+Subject: [PATCH 09/17] Use __x86.indirect_thunk.reg for indirect branch via
+ register
+
+---
+ gcc/config/i386/i386.c | 137 +++++++++++++++++----
+ gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 4 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 4 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 8 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 8 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 4 +-
+ .../gcc.target/i386/indirect-thunk-attr-1.c | 4 +-
+ .../gcc.target/i386/indirect-thunk-attr-2.c | 4 +-
+ .../gcc.target/i386/indirect-thunk-attr-3.c | 2 +-
+ .../gcc.target/i386/indirect-thunk-attr-4.c | 2 +-
+ .../gcc.target/i386/indirect-thunk-attr-5.c | 8 +-
+ .../gcc.target/i386/indirect-thunk-attr-6.c | 8 +-
+ .../gcc.target/i386/indirect-thunk-attr-7.c | 2 +-
+ .../gcc.target/i386/indirect-thunk-extern-1.c | 4 +-
+ .../gcc.target/i386/indirect-thunk-extern-2.c | 4 +-
+ .../gcc.target/i386/indirect-thunk-extern-3.c | 8 +-
+ .../gcc.target/i386/indirect-thunk-extern-4.c | 8 +-
+ .../gcc.target/i386/indirect-thunk-extern-7.c | 4 +-
+ .../gcc.target/i386/indirect-thunk-inline-1.c | 2 +-
+ .../gcc.target/i386/indirect-thunk-inline-2.c | 2 +-
+ .../gcc.target/i386/indirect-thunk-inline-3.c | 2 +-
+ .../gcc.target/i386/indirect-thunk-inline-4.c | 2 +-
+ .../gcc.target/i386/indirect-thunk-inline-7.c | 2 +-
+ 23 files changed, 158 insertions(+), 75 deletions(-)
+
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index 5e66af08066..590729b3f87 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -11948,6 +11948,9 @@ static int indirectlabelno;
+ static bool indirect_thunk_needed = false;
+ static bool indirect_thunk_bnd_needed = false;
+
++static int indirect_thunks_used;
++static int indirect_thunks_bnd_used;
++
+ #ifndef INDIRECT_LABEL
+ # define INDIRECT_LABEL "LIND"
+ #endif
+@@ -11955,24 +11958,45 @@ static bool indirect_thunk_bnd_needed = false;
+ /* Fills in the label name that should be used for the indirect thunk. */
+
+ static void
+-indirect_thunk_name (char name[32], bool need_bnd_p)
++indirect_thunk_name (char name[32], int regno, bool need_bnd_p)
+ {
+ if (USE_HIDDEN_LINKONCE)
+ {
+ const char *bnd = need_bnd_p ? "_bnd" : "";
+- sprintf (name, "__x86.indirect_thunk%s", bnd);
++ if (regno >= 0)
++ {
++ const char *reg_prefix;
++ if (LEGACY_INT_REGNO_P (regno))
++ reg_prefix = TARGET_64BIT ? "r" : "e";
++ else
++ reg_prefix = "";
++ sprintf (name, "__x86.indirect_thunk%s.%s%s",
++ bnd, reg_prefix, reg_names[regno]);
++ }
++ else
++ sprintf (name, "__x86.indirect_thunk%s", bnd);
+ }
+ else
+ {
+- if (need_bnd_p)
+- ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);
++ if (regno >= 0)
++ {
++ if (need_bnd_p)
++ ASM_GENERATE_INTERNAL_LABEL (name, "LITBR", regno);
++ else
++ ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno);
++ }
+ else
+- ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);
++ {
++ if (need_bnd_p)
++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);
++ else
++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);
++ }
+ }
+ }
+
+ static void
+-output_indirect_thunk (bool need_bnd_p)
++output_indirect_thunk (bool need_bnd_p, int regno)
+ {
+ char indirectlabel1[32];
+ char indirectlabel2[32];
+@@ -12002,11 +12026,22 @@ output_indirect_thunk (bool need_bnd_p)
+
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
+
+- /* LEA. */
+- rtx xops[2];
+- xops[0] = stack_pointer_rtx;
+- xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
+- output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);
++ if (regno >= 0)
++ {
++ /* MOV. */
++ rtx xops[2];
++ xops[0] = gen_rtx_MEM (word_mode, stack_pointer_rtx);
++ xops[1] = gen_rtx_REG (word_mode, regno);
++ output_asm_insn ("mov\t{%1, %0|%0, %1}", xops);
++ }
++ else
++ {
++ /* LEA. */
++ rtx xops[2];
++ xops[0] = stack_pointer_rtx;
++ xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
++ output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);
++ }
+
+ if (need_bnd_p)
+ fputs ("\tbnd ret\n", asm_out_file);
+@@ -12015,12 +12050,13 @@ output_indirect_thunk (bool need_bnd_p)
+ }
+
+ static void
+-output_indirect_thunk_function (bool need_bnd_p)
++output_indirect_thunk_function (bool need_bnd_p, int regno)
+ {
+ char name[32];
+ tree decl;
+
+- indirect_thunk_name (name, need_bnd_p);
++ /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd. */
++ indirect_thunk_name (name, regno, need_bnd_p);
+ decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
+ get_identifier (name),
+ build_function_type_list (void_type_node, NULL_TREE));
+@@ -12074,7 +12110,7 @@ output_indirect_thunk_function (bool need_bnd_p)
+ /* Make sure unwind info is emitted for the thunk if needed. */
+ final_start_function (emit_barrier (), asm_out_file, 1);
+
+- output_indirect_thunk (need_bnd_p);
++ output_indirect_thunk (need_bnd_p, regno);
+
+ final_end_function ();
+ init_insn_lengths ();
+@@ -12110,15 +12146,31 @@ ix86_code_end (void)
+ int regno;
+
+ if (indirect_thunk_needed)
+- output_indirect_thunk_function (false);
++ output_indirect_thunk_function (false, -1);
+ if (indirect_thunk_bnd_needed)
+- output_indirect_thunk_function (true);
++ output_indirect_thunk_function (true, -1);
++
++ for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++)
++ {
++ int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1;
++ if ((indirect_thunks_used & (1 << i)))
++ output_indirect_thunk_function (false, regno);
++
++ if ((indirect_thunks_bnd_used & (1 << i)))
++ output_indirect_thunk_function (true, regno);
++ }
+
+ for (regno = AX_REG; regno <= SP_REG; regno++)
+ {
+ char name[32];
+ tree decl;
+
++ if ((indirect_thunks_used & (1 << regno)))
++ output_indirect_thunk_function (false, regno);
++
++ if ((indirect_thunks_bnd_used & (1 << regno)))
++ output_indirect_thunk_function (true, regno);
++
+ if (!(pic_labels_used & (1 << regno)))
+ continue;
+
+@@ -28639,17 +28691,37 @@ ix86_output_indirect_branch (rtx call_op, const char
*xasm,
+ char *thunk_name;
+ char push_buf[64];
+ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);
++ int regno;
++
++ if (REG_P (call_op))
++ regno = REGNO (call_op);
++ else
++ regno = -1;
+
+ if (cfun->machine->indirect_branch_type
+ != indirect_branch_thunk_inline)
+ {
+- bool need_thunk
+- = cfun->machine->indirect_branch_type == indirect_branch_thunk;
+- if (need_bnd_p)
+- indirect_thunk_bnd_needed |= need_thunk;
+- else
+- indirect_thunk_needed |= need_thunk;
+- indirect_thunk_name (thunk_name_buf, need_bnd_p);
++ if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
++ {
++ if (regno >= 0)
++ {
++ int i = regno;
++ if (i >= FIRST_REX_INT_REG)
++ i -= (FIRST_REX_INT_REG - LAST_INT_REG - 1);
++ if (need_bnd_p)
++ indirect_thunks_bnd_used |= 1 << i;
++ else
++ indirect_thunks_used |= 1 << i;
++ }
++ else
++ {
++ if (need_bnd_p)
++ indirect_thunk_bnd_needed = true;
++ else
++ indirect_thunk_needed = true;
++ }
++ }
++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p);
+ thunk_name = thunk_name_buf;
+ }
+ else
+@@ -28660,7 +28732,8 @@ ix86_output_indirect_branch (rtx call_op, const char
*xasm,
+
+ if (sibcall_p)
+ {
+- output_asm_insn (push_buf, &call_op);
++ if (regno < 0)
++ output_asm_insn (push_buf, &call_op);
+ if (thunk_name != NULL)
+ {
+ if (need_bnd_p)
+@@ -28669,10 +28742,19 @@ ix86_output_indirect_branch (rtx call_op, const char
*xasm,
+ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
+ }
+ else
+- output_indirect_thunk (need_bnd_p);
++ output_indirect_thunk (need_bnd_p, regno);
+ }
+ else
+ {
++ if (regno >= 0 && thunk_name != NULL)
++ {
++ if (need_bnd_p)
++ fprintf (asm_out_file, "\tbnd call\t%s\n", thunk_name);
++ else
++ fprintf (asm_out_file, "\tcall\t%s\n", thunk_name);
++ return;
++ }
++
+ char indirectlabel1[32];
+ char indirectlabel2[32];
+
+@@ -28725,7 +28807,8 @@ ix86_output_indirect_branch (rtx call_op, const char
*xasm,
+ }
+ }
+
+- output_asm_insn (push_buf, &call_op);
++ if (regno < 0)
++ output_asm_insn (push_buf, &call_op);
+
+ if (thunk_name != NULL)
+ {
+@@ -28735,7 +28818,7 @@ ix86_output_indirect_branch (rtx call_op, const char
*xasm,
+ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
+ }
+ else
+- output_indirect_thunk (need_bnd_p);
++ output_indirect_thunk (need_bnd_p, regno);
+
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
+
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+index d8b6f5a06a5..785e593405f 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+index f7d5cb315a8..b69075e6483 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+index 736d7cda058..df8109baf55 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
+-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+index cef9b10513e..8f3b9f4d8a5 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
+-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+index ea0fa312f64..f0e1cfe1893 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+@@ -36,8 +36,8 @@ bar (int i)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target
{ ! x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+index 26550fad4c8..8b88449e625 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+@@ -15,8 +15,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+index f57bb2a92d6..c69f7bf4f60 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+index a3668a6586c..c845099a83e 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+@@ -15,7 +15,7 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+index a9c4a137dd4..f636f3422fd 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+@@ -14,7 +14,7 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+index 9582e0c5824..5f1d6a78041 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+@@ -15,8 +15,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */
+-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 }
} } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32
} } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+index 66442cacfe8..56c92da9812 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+@@ -14,8 +14,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */
+-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 }
} } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32
} } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+index 2a19b54cd2e..cfb6f5b234b 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+@@ -37,7 +37,7 @@ bar (int i)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target
{ ! x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+index 0a1f91be988..f1fa0a11922 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+index 182520ab3dc..d6e078d594b 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+@@ -12,8 +12,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+index 5c31ddc34fd..3bbe2646955 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */
+-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 }
} } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32
} } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+index f24d0c060f2..596fac599f6 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+@@ -13,8 +13,8 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */
+-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 }
} } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32
} } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+index 8d39fb6f939..ab367951c45 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+@@ -36,8 +36,8 @@ bar (int i)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target
{ ! x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { !
x32 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" {
target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+ /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+index 071e6c89ac7..09b8ad7d879 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+@@ -12,7 +12,7 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+index 804c7ccdba7..1f873758fbe 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+@@ -12,7 +12,7 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+index 545a981add5..b24af1da963 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+@@ -13,7 +13,7 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+index d9ff4722cff..1a86608f727 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+@@ -13,7 +13,7 @@ male_indirect_jump (long offset)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { !
x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+ /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+index a0ce06b8232..01d45782185 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+@@ -36,7 +36,7 @@ bar (int i)
+ }
+
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target
{ ! x32 } } } } */
+-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch
b/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch
new file mode 100644
index 000000000..1996a1dfe
--- /dev/null
+++
b/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.patch
@@ -0,0 +1,76 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From f83391fb22471a2f1c330e2e78f64630d64f497d Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Tue, 19 Dec 2017 08:28:36 -0800
+Subject: [PATCH 16/17] i386: Add 'V' register operand modifier
+
+For
+
+void
+bar (void (*func) (void))
+{
+ asm("call *%V0" : : "r"(func));
+}
+
+it generates:
+
+bar:
+ call *rdi
+ ret
+---
+ gcc/config/i386/i386.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index 344cafe3dac..6cb0681233a 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -17886,6 +17886,7 @@ put_condition_code (enum rtx_code code, machine_mode
mode, bool reverse,
+ If CODE is 'h', pretend the reg is the 'high' byte register.
+ If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.
+ If CODE is 'd', duplicate the operand for AVX instruction.
++ If CODE is 'V', print naked register name without %.
+ */
+
+ void
+@@ -17896,7 +17897,7 @@ print_reg (rtx x, int code, FILE *file)
+ unsigned int regno;
+ bool duplicated;
+
+- if (ASSEMBLER_DIALECT == ASM_ATT)
++ if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V')
+ putc ('%', file);
+
+ if (x == pc_rtx)
+@@ -18063,6 +18064,7 @@ print_reg (rtx x, int code, FILE *file)
+ & -- print some in-use local-dynamic symbol name.
+ H -- print a memory address offset by 8; used for sse high-parts
+ Y -- print condition for XOP pcom* instruction.
++ V -- print naked register name without %.
+ + -- print a branch hint as 'cs' or 'ds' prefix
+ ; -- print a semicolon (after prefixes due to bug in older gas).
+ ~ -- print "i" if TARGET_AVX2, "f" otherwise.
+@@ -18287,6 +18289,7 @@ ix86_print_operand (FILE *file, rtx x, int code)
+ case 'X':
+ case 'P':
+ case 'p':
++ case 'V':
+ break;
+
+ case 's':
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch
b/gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch
new file mode 100644
index 000000000..3c42dd802
--- /dev/null
+++
b/gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_frame-to-avoi.patch
@@ -0,0 +1,69 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From d96784e4a7355aaab68dec62f31a97bd10714064 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Tue, 28 Nov 2017 10:26:35 -0800
+Subject: [PATCH 03/17] i386: More use reference of struct ix86_frame to avoid
+ copy
+
+When there is no need to make a copy of ix86_frame, we can use reference
+of struct ix86_frame to avoid copy.
+
+ * config/i386/i386.c (ix86_expand_prologue): Use reference of
+ struct ix86_frame.
+ (ix86_expand_epilogue): Likewise.
+---
+ gcc/config/i386/i386.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index 01ecda7643b..504530a00cf 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -13656,7 +13656,6 @@ ix86_expand_prologue (void)
+ {
+ struct machine_function *m = cfun->machine;
+ rtx insn, t;
+- struct ix86_frame frame;
+ HOST_WIDE_INT allocate;
+ bool int_registers_saved;
+ bool sse_registers_saved;
+@@ -13680,7 +13679,7 @@ ix86_expand_prologue (void)
+ m->fs.sp_valid = true;
+
+ ix86_compute_frame_layout ();
+- frame = m->frame;
++ struct ix86_frame &frame = cfun->machine->frame;
+
+ if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
+ {
+@@ -14343,13 +14342,12 @@ ix86_expand_epilogue (int style)
+ {
+ struct machine_function *m = cfun->machine;
+ struct machine_frame_state frame_state_save = m->fs;
+- struct ix86_frame frame;
+ bool restore_regs_via_mov;
+ bool using_drap;
+
+ ix86_finalize_stack_realign_flags ();
+ ix86_compute_frame_layout ();
+- frame = m->frame;
++ struct ix86_frame &frame = cfun->machine->frame;
+
+ m->fs.sp_valid = (!frame_pointer_needed
+ || (crtl->sp_is_unchanging
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch
b/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch
new file mode 100644
index 000000000..908e3cd83
--- /dev/null
+++
b/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_function.patch
@@ -0,0 +1,249 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 85743811dfa4eb648edbbb637632ac53182b6e05 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <address@hidden>
+Date: Mon, 6 Nov 2017 09:11:08 -0800
+Subject: [PATCH 01/17] i386: Move struct ix86_frame to machine_function
+
+Make ix86_frame available to i386 code generation.
+
+ * config/i386/i386.c (ix86_frame): Moved to ...
+ * config/i386/i386.h (ix86_frame): Here.
+ (machine_function): Add frame.
+ * config/i386/i386.c (ix86_compute_frame_layout): Repace the
+ frame argument with &cfun->machine->frame.
+ (ix86_can_use_return_insn_p): Don't pass &frame to
+ ix86_compute_frame_layout. Copy frame from cfun->machine->frame.
+ (ix86_can_eliminate): Likewise.
+ (ix86_expand_prologue): Likewise.
+ (ix86_expand_epilogue): Likewise.
+ (ix86_expand_split_stack_prologue): Likewise.
+---
+ gcc/config/i386/i386.c | 68 ++++++++++----------------------------------------
+ gcc/config/i386/i386.h | 53 ++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 65 insertions(+), 56 deletions(-)
+
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index dc14d205de7..c23c259c538 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -2441,53 +2441,6 @@ struct GTY(()) stack_local_entry {
+ struct stack_local_entry *next;
+ };
+
+-/* Structure describing stack frame layout.
+- Stack grows downward:
+-
+- [arguments]
+- <- ARG_POINTER
+- saved pc
+-
+- saved static chain if ix86_static_chain_on_stack
+-
+- saved frame pointer if frame_pointer_needed
+- <- HARD_FRAME_POINTER
+- [saved regs]
+- <- regs_save_offset
+- [padding0]
+-
+- [saved SSE regs]
+- <- sse_regs_save_offset
+- [padding1] |
+- | <- FRAME_POINTER
+- [va_arg registers] |
+- |
+- [frame] |
+- |
+- [padding2] | = to_allocate
+- <- STACK_POINTER
+- */
+-struct ix86_frame
+-{
+- int nsseregs;
+- int nregs;
+- int va_arg_size;
+- int red_zone_size;
+- int outgoing_arguments_size;
+-
+- /* The offsets relative to ARG_POINTER. */
+- HOST_WIDE_INT frame_pointer_offset;
+- HOST_WIDE_INT hard_frame_pointer_offset;
+- HOST_WIDE_INT stack_pointer_offset;
+- HOST_WIDE_INT hfp_save_offset;
+- HOST_WIDE_INT reg_save_offset;
+- HOST_WIDE_INT sse_reg_save_offset;
+-
+- /* When save_regs_using_mov is set, emit prologue using
+- move instead of push instructions. */
+- bool save_regs_using_mov;
+-};
+-
+ /* Which cpu are we scheduling for. */
+ enum attr_cpu ix86_schedule;
+
+@@ -2579,7 +2532,7 @@ static unsigned int ix86_function_arg_boundary
(machine_mode,
+ const_tree);
+ static rtx ix86_static_chain (const_tree, bool);
+ static int ix86_function_regparm (const_tree, const_tree);
+-static void ix86_compute_frame_layout (struct ix86_frame *);
++static void ix86_compute_frame_layout (void);
+ static bool ix86_expand_vector_init_one_nonzero (bool, machine_mode,
+ rtx, rtx, int);
+ static void ix86_add_new_builtins (HOST_WIDE_INT, HOST_WIDE_INT);
+@@ -11892,7 +11845,8 @@ ix86_can_use_return_insn_p (void)
+ if (crtl->args.pops_args && crtl->args.size >= 32768)
+ return 0;
+
+- ix86_compute_frame_layout (&frame);
++ ix86_compute_frame_layout ();
++ frame = cfun->machine->frame;
+ return (frame.stack_pointer_offset == UNITS_PER_WORD
+ && (frame.nregs + frame.nsseregs) == 0);
+ }
+@@ -12378,8 +12332,8 @@ ix86_can_eliminate (const int from, const int to)
+ HOST_WIDE_INT
+ ix86_initial_elimination_offset (int from, int to)
+ {
+- struct ix86_frame frame;
+- ix86_compute_frame_layout (&frame);
++ ix86_compute_frame_layout ();
++ struct ix86_frame frame = cfun->machine->frame;
+
+ if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
+ return frame.hard_frame_pointer_offset;
+@@ -12418,8 +12372,9 @@ ix86_builtin_setjmp_frame_value (void)
+ /* Fill structure ix86_frame about frame of currently computed function. */
+
+ static void
+-ix86_compute_frame_layout (struct ix86_frame *frame)
++ix86_compute_frame_layout (void)
+ {
++ struct ix86_frame *frame = &cfun->machine->frame;
+ unsigned HOST_WIDE_INT stack_alignment_needed;
+ HOST_WIDE_INT offset;
+ unsigned HOST_WIDE_INT preferred_alignment;
+@@ -13726,7 +13681,8 @@ ix86_expand_prologue (void)
+ m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
+ m->fs.sp_valid = true;
+
+- ix86_compute_frame_layout (&frame);
++ ix86_compute_frame_layout ();
++ frame = m->frame;
+
+ if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
+ {
+@@ -14394,7 +14350,8 @@ ix86_expand_epilogue (int style)
+ bool using_drap;
+
+ ix86_finalize_stack_realign_flags ();
+- ix86_compute_frame_layout (&frame);
++ ix86_compute_frame_layout ();
++ frame = m->frame;
+
+ m->fs.sp_valid = (!frame_pointer_needed
+ || (crtl->sp_is_unchanging
+@@ -14904,7 +14861,8 @@ ix86_expand_split_stack_prologue (void)
+ gcc_assert (flag_split_stack && reload_completed);
+
+ ix86_finalize_stack_realign_flags ();
+- ix86_compute_frame_layout (&frame);
++ ix86_compute_frame_layout ();
++ frame = cfun->machine->frame;
+ allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
+
+ /* This is the label we will branch to if we have enough stack
+diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
+index 9e5f4d857d9..7d9f9020fb3 100644
+--- a/gcc/config/i386/i386.h
++++ b/gcc/config/i386/i386.h
+@@ -2446,9 +2446,56 @@ enum avx_u128_state
+
+ #define FASTCALL_PREFIX '@'
+
++#ifndef USED_FOR_TARGET
++/* Structure describing stack frame layout.
++ Stack grows downward:
++
++ [arguments]
++ <- ARG_POINTER
++ saved pc
++
++ saved static chain if ix86_static_chain_on_stack
++
++ saved frame pointer if frame_pointer_needed
++ <- HARD_FRAME_POINTER
++ [saved regs]
++ <- regs_save_offset
++ [padding0]
++
++ [saved SSE regs]
++ <- sse_regs_save_offset
++ [padding1] |
++ | <- FRAME_POINTER
++ [va_arg registers] |
++ |
++ [frame] |
++ |
++ [padding2] | = to_allocate
++ <- STACK_POINTER
++ */
++struct GTY(()) ix86_frame
++{
++ int nsseregs;
++ int nregs;
++ int va_arg_size;
++ int red_zone_size;
++ int outgoing_arguments_size;
++
++ /* The offsets relative to ARG_POINTER. */
++ HOST_WIDE_INT frame_pointer_offset;
++ HOST_WIDE_INT hard_frame_pointer_offset;
++ HOST_WIDE_INT stack_pointer_offset;
++ HOST_WIDE_INT hfp_save_offset;
++ HOST_WIDE_INT reg_save_offset;
++ HOST_WIDE_INT sse_reg_save_offset;
++
++ /* When save_regs_using_mov is set, emit prologue using
++ move instead of push instructions. */
++ bool save_regs_using_mov;
++};
++
+ /* Machine specific frame tracking during prologue/epilogue generation. */
+
+-#ifndef USED_FOR_TARGET
+ struct GTY(()) machine_frame_state
+ {
+ /* This pair tracks the currently active CFA as reg+offset. When reg
+@@ -2507,6 +2554,9 @@ struct GTY(()) machine_function {
+ int varargs_fpr_size;
+ int optimize_mode_switching[MAX_386_ENTITIES];
+
++ /* Cached initial frame layout for the current function. */
++ struct ix86_frame frame;
++
+ /* Number of saved registers USE_FAST_PROLOGUE_EPILOGUE
+ has been computed for. */
+ int use_fast_prologue_epilogue_nregs;
+@@ -2589,6 +2639,7 @@ struct GTY(()) machine_function {
+ #define ix86_current_function_calls_tls_descriptor \
+ (ix86_tls_descriptor_calls_expanded_in_cfun && df_regs_ever_live_p (SP_REG))
+ #define ix86_static_chain_on_stack (cfun->machine->static_chain_on_stack)
++#define ix86_red_zone_size (cfun->machine->frame.red_zone_size)
+
+ /* Control behavior of x86_file_start. */
+ #define X86_FILE_START_VERSION_DIRECTIVE false
+--
+2.15.1
+
diff --git
a/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch
b/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch
new file mode 100644
index 000000000..623ce5094
--- /dev/null
+++
b/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch
@@ -0,0 +1,85 @@
+'Retpoline' mitigation technique for Spectre (branch target injection)
+[CVE-2017-5715]:
+
+https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html
+https://support.google.com/faqs/answer/7625886
+https://spectreattack.com/
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repository
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' branch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 0b1769bdce27304a6a91bec234f47f102a2603d5 Mon Sep 17 00:00:00 2001
+From: hjl <address@hidden>
+Date: Mon, 6 Nov 2017 23:04:15 +0000
+Subject: [PATCH 02/17] i386: Use reference of struct ix86_frame to avoid copy
+
+When there is no need to make a copy of ix86_frame, we can use reference
+of struct ix86_frame to avoid copy.
+
+Tested on x86-64.
+
+ * config/i386/i386.c (ix86_can_use_return_insn_p): Use reference
+ of struct ix86_frame.
+ (ix86_initial_elimination_offset): Likewise.
+ (ix86_expand_split_stack_prologue): Likewise.
+
+git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/address@hidden
138bc75d-0d04-0410-961f-82ee72b054a4
+---
+ gcc/config/i386/i386.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index c23c259c538..01ecda7643b 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -11832,8 +11832,6 @@ symbolic_reference_mentioned_p (rtx op)
+ bool
+ ix86_can_use_return_insn_p (void)
+ {
+- struct ix86_frame frame;
+-
+ /* Don't use `ret' instruction in interrupt handler. */
+ if (! reload_completed
+ || frame_pointer_needed
+@@ -11846,7 +11844,7 @@ ix86_can_use_return_insn_p (void)
+ return 0;
+
+ ix86_compute_frame_layout ();
+- frame = cfun->machine->frame;
++ struct ix86_frame &frame = cfun->machine->frame;
+ return (frame.stack_pointer_offset == UNITS_PER_WORD
+ && (frame.nregs + frame.nsseregs) == 0);
+ }
+@@ -12333,7 +12331,7 @@ HOST_WIDE_INT
+ ix86_initial_elimination_offset (int from, int to)
+ {
+ ix86_compute_frame_layout ();
+- struct ix86_frame frame = cfun->machine->frame;
++ struct ix86_frame &frame = cfun->machine->frame;
+
+ if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
+ return frame.hard_frame_pointer_offset;
+@@ -14849,7 +14847,6 @@ static GTY(()) rtx split_stack_fn_large;
+ void
+ ix86_expand_split_stack_prologue (void)
+ {
+- struct ix86_frame frame;
+ HOST_WIDE_INT allocate;
+ unsigned HOST_WIDE_INT args_size;
+ rtx_code_label *label;
+@@ -14862,7 +14859,7 @@ ix86_expand_split_stack_prologue (void)
+
+ ix86_finalize_stack_realign_flags ();
+ ix86_compute_frame_layout ();
+- frame = cfun->machine->frame;
++ struct ix86_frame &frame = cfun->machine->frame;
+ allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
+
+ /* This is the label we will branch to if we have enough stack
+--
+2.15.1
+
--
2.15.1
Cheers,
Alex
- [bug#30111] gnu: address@hidden: Apply the 'retpoline' mitigation technique.,
Alex Vong <=
[bug#30111] [PATCH] gnu: address@hidden: Use retpoline options when building itself., Alex Vong, 2018/01/26