GNU bug report logs - #30111
[PATCH] gnu: gcc@7: Use retpoline options when building itself.

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: guix-patches; Reported by: Alex Vong <alexvong1995@HIDDEN>; Keywords: security patch; dated Sun, 14 Jan 2018 13:10:01 UTC; Maintainer for guix-patches is guix-patches@HIDDEN.

Message received at 30111 <at> debbugs.gnu.org:


Received: (at 30111) by debbugs.gnu.org; 27 Feb 2018 09:37:16 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Feb 27 04:37:16 2018
Received: from localhost ([127.0.0.1]:34326 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1eqbhC-0000ne-Eb
	for submit <at> debbugs.gnu.org; Tue, 27 Feb 2018 04:37:16 -0500
Received: from hera.aquilenet.fr ([185.233.100.1]:50778)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1eqbhA-0000nU-Jj
 for 30111 <at> debbugs.gnu.org; Tue, 27 Feb 2018 04:37:13 -0500
Received: from localhost (localhost [127.0.0.1])
 by hera.aquilenet.fr (Postfix) with ESMTP id F14A310CD3;
 Tue, 27 Feb 2018 10:37:11 +0100 (CET)
X-Virus-Scanned: Debian amavisd-new at aquilenet.fr
Received: from hera.aquilenet.fr ([127.0.0.1])
 by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id 3dVscEN-_2qH; Tue, 27 Feb 2018 10:37:11 +0100 (CET)
Received: from ribbon (unknown [193.50.110.216])
 by hera.aquilenet.fr (Postfix) with ESMTPSA id EFD641069E;
 Tue, 27 Feb 2018 10:37:10 +0100 (CET)
From: ludo@HIDDEN (Ludovic =?utf-8?Q?Court=C3=A8s?=)
To: Alex Vong <alexvong1995@HIDDEN>
Subject: Re: [bug#30111] [PATCH] gnu: gcc@7: Use retpoline options when
 building itself.
References: <877esksi62.fsf@HIDDEN> <87lggkt2ck.fsf@HIDDEN>
Date: Tue, 27 Feb 2018 10:37:10 +0100
In-Reply-To: <87lggkt2ck.fsf@HIDDEN> (Alex Vong's message of "Sat, 27 Jan
 2018 11:19:55 +0800")
Message-ID: <87r2p64vuh.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: 1.0 (+)
X-Debbugs-Envelope-To: 30111
Cc: 30111 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: 1.0 (+)

Hi Alex,

Sorry for the delay.

Alex Vong <alexvong1995@HIDDEN> skribis:

> This patch makes gcc use retpoline options when building itself. My last
> attempt to build it was successful. But after that I have changed
> something, I hope it wouldn't make it fail to build. (It shouldn't,
> since the options passed aren't changed.)

Any idea what upstream thinks of compiling GCC itself with these
options?  Do they offer a configure flag or something to help with that?

> Are we going to add these options to other natively compiled programs as
> well?

I don=E2=80=99t have a good answer.  Clearly we=E2=80=99ll want that in key=
 packages,
but then where do we draw the line, and also how do we make sure we
don=E2=80=99t repeat ourselves?

Thoughts?

>>From f6b9caae6e13936be65550c871208a3425fe4ce4 Mon Sep 17 00:00:00 2001
> From: Alex Vong <alexvong1995@HIDDEN>
> Date: Thu, 25 Jan 2018 23:24:24 +0800
> Subject: [PATCH] gnu: gcc@7: Use retpoline options when building itself.
>
> * gnu/packages/gcc.scm (gcc@7)[arguments]: Add retpoline options
> to #:make-flags.

[...]

> +    (arguments
> +     (substitute-keyword-arguments `(#:modules ((guix build gnu-build-sy=
stem)
> +                                                (guix build utils)
> +                                                (ice-9 regex)
> +                                                (srfi srfi-1)
> +                                                (srfi srfi-26))
> +                                     ,@(package-arguments gcc-6))
> +       ;; Use retpoline options when building itself.
> +       ((#:make-flags flags)
> +        `(let* ((cross-compiling? ,(%current-target-system))
> +                (system (if cross-compiling?
> +                            ,(%current-target-system)
> +                            ,(%current-system)))
> +                (retpoline-opts '("-mindirect-branch=3Dthunk"
> +                                  "-mfunction-return=3Dthunk"
> +                                  "-mindirect-branch-register"))
> +                (append-flag
> +                 (lambda (flag)
> +                   (if (string-match "^((BOOT_)?CFLAGS|C(XX)?FLAGS_FOR_T=
ARGET)=3D"
> +                                     flag)
> +                       (string-join (cons flag retpoline-opts))
> +                       flag)))
> +                (add-flag
> +                 (lambda (prefix flags)
> +                   (if (any (cut string-prefix? prefix <>) flags)
> +                       flags
> +                       (cons (string-append prefix
> +                                            (string-join retpoline-opts))
> +                             flags))))
> +                (add-gcc-flag (cut add-flag
> +                                (if cross-compiling? "CFLAGS=3D" "BOOT_C=
FLAGS=3D")
> +                                <>))
> +                (add-c-lib-flag (cut add-flag "CFLAGS_FOR_TARGET=3D" <>))
> +                (add-c++-lib-flag (cut add-flag "CXXFLAGS_FOR_TARGET=3D"=
 <>)))
> +           ;; Right now, the retpoline options are x86-specific.
> +           (if (any (cut string-prefix? <> system) '("x86_64" "i686"))
> +               (add-gcc-flag (add-c-lib-flag (add-c++-lib-flag (map appe=
nd-flag
> +                                                                    ,fla=
gs))))
> +               ,flags)))))

I=E2=80=99m a bit concerned by the apparent complexity and the extra mainte=
nance
burden it may entail.  I don=E2=80=99t have any concrete suggestions though=
.  I
suppose we should somehow abstract GCC compilation to make it easier to
pass new flags?

Thanks,
Ludo=E2=80=99.




Information forwarded to guix-patches@HIDDEN:
bug#30111; Package guix-patches. Full text available.

Message received at 30111 <at> debbugs.gnu.org:


Received: (at 30111) by debbugs.gnu.org; 27 Jan 2018 03:20:08 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Jan 26 22:20:08 2018
Received: from localhost ([127.0.0.1]:44226 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1efH2G-0000Nu-0q
	for submit <at> debbugs.gnu.org; Fri, 26 Jan 2018 22:20:08 -0500
Received: from mail-pl0-f42.google.com ([209.85.160.42]:46249)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <alexvong1995@HIDDEN>) id 1efH2E-0000NL-DV
 for 30111 <at> debbugs.gnu.org; Fri, 26 Jan 2018 22:20:06 -0500
Received: by mail-pl0-f42.google.com with SMTP id 36so162832ple.13
 for <30111 <at> debbugs.gnu.org>; Fri, 26 Jan 2018 19:20:06 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:subject:date:message-id:user-agent:mime-version;
 bh=INWO0vgcdUguooZek3yjvLD1lqq8Du1YPt/20t8bm40=;
 b=UzFim0L1DrcK1OcUIKjxIRrwn0tnTDRBsIy5r+nAqiWjBDHXBnL3e1liR2fbHOkeqs
 9QZg77Pndjy+2LEbDliPAjablPIWtkP3Nn6xnTj7wfn15v/lk0RH91oir4UJuypjMJSS
 enfJ8LUbasKKuAAdYG2h6ePCZhgPo5xv20z4M3qyAIUTJx6sMHDk9+p3wL9r+a7M5RS4
 fNeZnaTNZ34fZzFWMcucfnqBcFDkL8zxg/DaRPlBS+V7yh64KplNTdf3r/WjAELZxBG+
 VViW799SML4G2DDMrnB7pYYBGui8Ea1ll2G/XnBxHrddhzev5xMtMZExIFx88EZU0g/u
 gxLg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:subject:date:message-id:user-agent
 :mime-version;
 bh=INWO0vgcdUguooZek3yjvLD1lqq8Du1YPt/20t8bm40=;
 b=EAcHvg1TVSgldoDLKwTwzD9Zt9HINAll2ttApWeU+LwSvVQPN6f4O+h0xSa9d9lg50
 NACmPZVxwVIj5fUT5rh9jrOg+Q57/3Nur/Dk01VQ7QHVVBJ/T9AjrsWkRcACpuJjc2Bw
 3k4hs5B3PQOUg1+g6xdt31EwQWoERhJ9XFPzlxKhj6OOzaZdq5YKP9VIpT+m40mvTOYw
 ScCjKXg5y7P+gths1FtuuLGuZwh1C/Q6DgnOQx2nDMpTtcrVDHywiz/TldsPGMSbAfrp
 dm/BF+uKKutQXbNuVDGfnStT3vHiLb3tQOuV9kRNR4jHNc1jYpkCEpROilU2P6Vie7U2
 //IQ==
X-Gm-Message-State: AKwxyteJQgXbpT6k3np1SqmTRMyF/Iwg7p65ivU4ZP93ZrRGi4jCnfbG
 pIRHl/TzOB3zGkwJ2L+xAuk=
X-Google-Smtp-Source: AH8x226Jm9Tf/0lanefPvD0Rpe7I4x8+dh8sZD2DQ8S7Zrh1/LVItIdtfgEKS7Q/4Xbyg8aueifp1w==
X-Received: by 2002:a17:902:7c97:: with SMTP id
 y23-v6mr15975284pll.439.1517023200767; 
 Fri, 26 Jan 2018 19:20:00 -0800 (PST)
Received: from debian (n218250043136.netvigator.com. [218.250.43.136])
 by smtp.gmail.com with ESMTPSA id t8sm9504584pgr.21.2018.01.26.19.19.59
 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);
 Fri, 26 Jan 2018 19:20:00 -0800 (PST)
From: Alex Vong <alexvong1995@HIDDEN>
To: 30111 <at> debbugs.gnu.org
Subject: Re: [PATCH] gnu: gcc@7: Use retpoline options when building itself.
Date: Sat, 27 Jan 2018 11:19:55 +0800
Message-ID: <87lggkt2ck.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-Spam-Score: 0.2 (/)
X-Debbugs-Envelope-To: 30111
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: 0.2 (/)

--=-=-=
Content-Type: text/plain

Hello,

This patch makes gcc use retpoline options when building itself. My last
attempt to build it was successful. But after that I have changed
something, I hope it wouldn't make it fail to build. (It shouldn't,
since the options passed aren't changed.)

Are we going to add these options to other natively compiled programs as
well?


--=-=-=
Content-Type: text/x-diff; charset=utf-8
Content-Disposition: attachment;
 filename=0001-gnu-gcc-7-Use-retpoline-options-when-building-itself.patch
Content-Transfer-Encoding: quoted-printable

From f6b9caae6e13936be65550c871208a3425fe4ce4 Mon Sep 17 00:00:00 2001
From: Alex Vong <alexvong1995@HIDDEN>
Date: Thu, 25 Jan 2018 23:24:24 +0800
Subject: [PATCH] gnu: gcc@7: Use retpoline options when building itself.

* gnu/packages/gcc.scm (gcc@7)[arguments]: Add retpoline options
to #:make-flags.
---
 gnu/packages/gcc.scm | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/gnu/packages/gcc.scm b/gnu/packages/gcc.scm
index 48e7b8ee3..6344ce734 100644
--- a/gnu/packages/gcc.scm
+++ b/gnu/packages/gcc.scm
@@ -5,6 +5,7 @@
 ;;; Copyright =C2=A9 2015 Andreas Enge <andreas@HIDDEN>
 ;;; Copyright =C2=A9 2015, 2016, 2017 Efraim Flashner <efraim@HIDDEN=
il>
 ;;; Copyright =C2=A9 2016 Carlos S=C3=A1nchez de La Lama <csanchezdll@gmai=
l.com>
+;;; Copyright =C2=A9 2018 Alex Vong <alexvong1995@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -428,6 +429,45 @@ Go.  It also includes runtime support libraries for th=
ese languages.")
                 "0p71bij6bfhzyrs8676a8jmpjsfz392s2rg862sdnsk30jpacb43"))
               (patches (search-patches "gcc-strmov-store-file-names.patch"
                                        "gcc-5.0-libvtv-runpath.patch"))))
+    (arguments
+     (substitute-keyword-arguments `(#:modules ((guix build gnu-build-syst=
em)
+                                                (guix build utils)
+                                                (ice-9 regex)
+                                                (srfi srfi-1)
+                                                (srfi srfi-26))
+                                     ,@(package-arguments gcc-6))
+       ;; Use retpoline options when building itself.
+       ((#:make-flags flags)
+        `(let* ((cross-compiling? ,(%current-target-system))
+                (system (if cross-compiling?
+                            ,(%current-target-system)
+                            ,(%current-system)))
+                (retpoline-opts '("-mindirect-branch=3Dthunk"
+                                  "-mfunction-return=3Dthunk"
+                                  "-mindirect-branch-register"))
+                (append-flag
+                 (lambda (flag)
+                   (if (string-match "^((BOOT_)?CFLAGS|C(XX)?FLAGS_FOR_TAR=
GET)=3D"
+                                     flag)
+                       (string-join (cons flag retpoline-opts))
+                       flag)))
+                (add-flag
+                 (lambda (prefix flags)
+                   (if (any (cut string-prefix? prefix <>) flags)
+                       flags
+                       (cons (string-append prefix
+                                            (string-join retpoline-opts))
+                             flags))))
+                (add-gcc-flag (cut add-flag
+                                (if cross-compiling? "CFLAGS=3D" "BOOT_CFL=
AGS=3D")
+                                <>))
+                (add-c-lib-flag (cut add-flag "CFLAGS_FOR_TARGET=3D" <>))
+                (add-c++-lib-flag (cut add-flag "CXXFLAGS_FOR_TARGET=3D" <=
>)))
+           ;; Right now, the retpoline options are x86-specific.
+           (if (any (cut string-prefix? <> system) '("x86_64" "i686"))
+               (add-gcc-flag (add-c-lib-flag (add-c++-lib-flag (map append=
-flag
+                                                                    ,flags=
))))
+               ,flags)))))
     (description
      "GCC is the GNU Compiler Collection.  It provides compiler front-ends
 for several languages, including C, C++, Objective-C, Fortran, Ada, and Go.
--=20
2.15.1


--=-=-=
Content-Type: text/plain


Cheers,
Alex

--=-=-=--




Information forwarded to guix-patches@HIDDEN:
bug#30111; Package guix-patches. Full text available.
Changed bug title to '[PATCH] gnu: gcc@7: Use retpoline options when building itself.' from '[PATCH] gnu: gcc@7: Apply the 'retpoline' mitigation technique.' Request was from Alex Vong <alexvong1995@HIDDEN> to control <at> debbugs.gnu.org. Full text available.

Message received at 30111 <at> debbugs.gnu.org:


Received: (at 30111) by debbugs.gnu.org; 17 Jan 2018 23:31:55 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Jan 17 18:31:54 2018
Received: from localhost ([127.0.0.1]:60708 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1ebxBS-0001xh-OY
	for submit <at> debbugs.gnu.org; Wed, 17 Jan 2018 18:31:54 -0500
Received: from out1-smtp.messagingengine.com ([66.111.4.25]:43767)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <leo@HIDDEN>) id 1ebxBQ-0001xZ-T9
 for 30111 <at> debbugs.gnu.org; Wed, 17 Jan 2018 18:31:53 -0500
Received: from compute4.internal (compute4.nyi.internal [10.202.2.44])
 by mailout.nyi.internal (Postfix) with ESMTP id C2A2120E40;
 Wed, 17 Jan 2018 18:31:52 -0500 (EST)
Received: from frontend1 ([10.202.2.160])
 by compute4.internal (MEProxy); Wed, 17 Jan 2018 18:31:52 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=famulari.name;
 h=cc:content-type:date:from:in-reply-to:message-id:mime-version
 :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s=
 mesmtp; bh=EntO3VHd8eUJevVAP7AecWsIhA0Wd/THbIp3h6U7xZQ=; b=AZpZW
 UQrFp3RnwpIQ72iqrVLIxmBY2C2ICVqRYVoiFYg09tSLZF0K/2KMJQ2SZUoJS0J4
 MY7wRrrtn9LP6kIXKsBN0KE1GwiZqp9Ir6nLgEgLvPr/PrGcfa5+OhX8Ja1SqNsG
 /R9hS/oUCG8mBb1LsxyFhrg1ip01m1+oDeWB7E=
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=
 messagingengine.com; h=cc:content-type:date:from:in-reply-to
 :message-id:mime-version:references:subject:to:x-me-sender
 :x-me-sender:x-sasl-enc; s=fm1; bh=EntO3VHd8eUJevVAP7AecWsIhA0Wd
 /THbIp3h6U7xZQ=; b=KvmLj4n+/jdQG1nv7u4CMLXJf8RVWY8577vm/ydNkVNG9
 4tf3KsMZY45hQ+pPUl3FGJi6Vdo3WwY+YoTyLpWEyjCG2XLMtzbB4MCvtbHByXi6
 Eke5avvZIDQx0ekedEmGzlC41jsOYSX3/laICdS0uss3JYXN/7X3LuBY94eEjShj
 aNPHdb8AidkASW/DoBwe38HU5PNpi0AVE9ZAr3kop0zcQ2lKfopFsCQobypWqzju
 lIDdogvFoAIvyCoPV943DZzputgsciHOEM0Mae7Oy1F5avScV3zvRlOHPOXqXWcW
 GcAMKZ2ZoK6cm09iLnHCSppQZfp3DPhDlgJs7PK/A==
X-ME-Sender: <xms:6NxfWpG0H0dtE6SsoaOvzOUE8sO7hOQz3z5NyMT1ReaO8e6j3rjRIg>
Received: from localhost (71-93-196-183.dhcp.nrwl.ca.charter.com
 [71.93.196.183])
 by mail.messagingengine.com (Postfix) with ESMTPA id 661157E5CA;
 Wed, 17 Jan 2018 18:31:52 -0500 (EST)
Date: Wed, 17 Jan 2018 15:31:51 -0800
From: Leo Famulari <leo@HIDDEN>
To: Ludovic =?iso-8859-1?Q?Court=E8s?= <ludo@HIDDEN>
Subject: Re: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation
 technique.
Message-ID: <20180117233151.GC17805@HIDDEN>
References: <877esksi62.fsf@HIDDEN> <87d12bgpqh.fsf@HIDDEN>
 <87a7xet06p.fsf@HIDDEN> <87a7xd6ffu.fsf@HIDDEN>
 <876081u8r0.fsf@HIDDEN> <87shb46365.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/signed; micalg=pgp-sha256;
 protocol="application/pgp-signature"; boundary="XWOWbaMNXpFDWE00"
Content-Disposition: inline
In-Reply-To: <87shb46365.fsf@HIDDEN>
User-Agent: Mutt/1.9.2 (2017-12-15)
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 30111
Cc: 30111 <at> debbugs.gnu.org, Alex Vong <alexvong1995@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)


--XWOWbaMNXpFDWE00
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Wed, Jan 17, 2018 at 02:11:14PM +0100, Ludovic Court=E8s wrote:
> Hi Alex,
>=20
> Alex Vong <alexvong1995@HIDDEN> skribis:
>=20
> > ludo@HIDDEN (Ludovic Court=E8s) writes:
>=20
> [...]
>=20
> >> Do you know if a new 7.x including retpoline support is scheduled for
> >> release soon?
> >>
> > Yes, I think they will appear in 7.3 according to [0]. Also, some
> > changes appear to be in gcc-7-branch already[1]. Do you think we should
> > wait for it instead?
>=20
> Yes, perhaps we should wait for that release.
>=20
> What do people think?

It depends on whether or not the GCC team is confident in the
implementation yet. If they are still working out the kinks then I
suggest waiting.

--XWOWbaMNXpFDWE00
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEsFFZSPHn08G5gDigJkb6MLrKfwgFAlpf3OcACgkQJkb6MLrK
fwjJNQ//UuC6aSoDJvXJ0lVIARfuDBn06L0RknkTKqdagEVZOdnmtG7tiHAVUKup
HxXPdm6tKflOO7EABb/av2QjcNaDm7JsUhc/NKTNWO0imcFMdODnmX4XF2DcpRgJ
heAOhawSYLFIa5mHxj0Z6kCMKKKGz2/uDnx1tAWR5StR96ICStX++WnuSKELPG9b
5vcjbYh6NU8uFKai++lcfZPEVa8+0/d0XdUVxjDLySStsI4MCXwtDVTOEweCxFw9
AbAEMGDY2w/6cvPONn0WXApSynAIYFtTX74oJGtozbGRkfW4eu39Tm/DaDpvxB94
zxI5saZeXToFw7RLhNS2t7Z6n5QjZU4CDVZOl1AG1fR3QNfnDOVegGwC7bWE7Z4/
65WhnN0AcMHG9V/bQ7uEYR21U5nj9W98WnTddCHAkew0frDfYA1x7LS316FTpDFf
KTsUWHl3lSLjrQn7O/tY0r4KnEn5j8nw30BukwsCWFaed0UZwLWHQ5GZktOvvNEy
azaM/yTsk9zyBlLAdEsU5gzWf8aCQacxeyYcmgXM0A5KQL5+/FcI+XdHIZN5qTE/
vLgqidBkorWSH2MnW8cf5COx7wBTMrf4p0BjIo9gWRrBf4hK/lrrdlzyhUIMZzui
J8kqcoNnuhmRyhSlrcmhrOi/oT4YFl8hTxI0g00G2sRL6MIkyak=
=S5+D
-----END PGP SIGNATURE-----

--XWOWbaMNXpFDWE00--




Information forwarded to guix-patches@HIDDEN:
bug#30111; Package guix-patches. Full text available.

Message received at 30111 <at> debbugs.gnu.org:


Received: (at 30111) by debbugs.gnu.org; 17 Jan 2018 13:11:20 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Jan 17 08:11:20 2018
Received: from localhost ([127.0.0.1]:59543 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1ebnUt-0000c9-Ro
	for submit <at> debbugs.gnu.org; Wed, 17 Jan 2018 08:11:20 -0500
Received: from hera.aquilenet.fr ([185.233.100.1]:42520)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1ebnUr-0000c0-Dt
 for 30111 <at> debbugs.gnu.org; Wed, 17 Jan 2018 08:11:17 -0500
Received: from localhost (localhost [127.0.0.1])
 by hera.aquilenet.fr (Postfix) with ESMTP id 8BC9910E8C;
 Wed, 17 Jan 2018 14:11:16 +0100 (CET)
X-Virus-Scanned: Debian amavisd-new at aquilenet.fr
Received: from hera.aquilenet.fr ([127.0.0.1])
 by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id H1wTEF0ONUVD; Wed, 17 Jan 2018 14:11:15 +0100 (CET)
Received: from ribbon (unknown [IPv6:2a01:e0a:1d:7270:af76:b9b:ca24:c465])
 by hera.aquilenet.fr (Postfix) with ESMTPSA id 8D36010C9E;
 Wed, 17 Jan 2018 14:11:15 +0100 (CET)
From: ludo@HIDDEN (Ludovic =?utf-8?Q?Court=C3=A8s?=)
To: Alex Vong <alexvong1995@HIDDEN>
Subject: Re: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation
 technique.
References: <877esksi62.fsf@HIDDEN> <87d12bgpqh.fsf@HIDDEN>
 <87a7xet06p.fsf@HIDDEN> <87a7xd6ffu.fsf@HIDDEN>
 <876081u8r0.fsf@HIDDEN>
X-URL: http://www.fdn.fr/~lcourtes/
X-Revolutionary-Date: 28 =?utf-8?Q?Niv=C3=B4se?= an 226 de la =?utf-8?Q?R?=
 =?utf-8?Q?=C3=A9volution?=
X-PGP-Key-ID: 0x090B11993D9AEBB5
X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc
X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4  0CFB 090B 1199 3D9A EBB5
X-OS: x86_64-pc-linux-gnu
Date: Wed, 17 Jan 2018 14:11:14 +0100
In-Reply-To: <876081u8r0.fsf@HIDDEN> (Alex Vong's message of "Tue, 16 Jan
 2018 23:24:35 +0800")
Message-ID: <87shb46365.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: 1.0 (+)
X-Debbugs-Envelope-To: 30111
Cc: 30111 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: 1.0 (+)

Hi Alex,

Alex Vong <alexvong1995@HIDDEN> skribis:

> ludo@HIDDEN (Ludovic Court=C3=A8s) writes:

[...]

>> Do you know if a new 7.x including retpoline support is scheduled for
>> release soon?
>>
> Yes, I think they will appear in 7.3 according to [0]. Also, some
> changes appear to be in gcc-7-branch already[1]. Do you think we should
> wait for it instead?

Yes, perhaps we should wait for that release.

What do people think?

Ludo=E2=80=99.




Information forwarded to guix-patches@HIDDEN:
bug#30111; Package guix-patches. Full text available.

Message received at 30111 <at> debbugs.gnu.org:


Received: (at 30111) by debbugs.gnu.org; 16 Jan 2018 15:24:58 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Jan 16 10:24:58 2018
Received: from localhost ([127.0.0.1]:58873 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1ebT6e-0002No-63
	for submit <at> debbugs.gnu.org; Tue, 16 Jan 2018 10:24:58 -0500
Received: from mail-pg0-f44.google.com ([74.125.83.44]:43631)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <alexvong1995@HIDDEN>) id 1ebT6a-0002NY-Fw
 for 30111 <at> debbugs.gnu.org; Tue, 16 Jan 2018 10:24:54 -0500
Received: by mail-pg0-f44.google.com with SMTP id n17so2082252pgf.10
 for <30111 <at> debbugs.gnu.org>; Tue, 16 Jan 2018 07:24:52 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:cc:subject:references:date:in-reply-to:message-id
 :user-agent:mime-version:content-transfer-encoding;
 bh=5b6vnPJ0W2h8O+yK/TV56KKrXrnrHYmKlpTAZrWxTIY=;
 b=Z0mXk6vDNHSrrLPW6H4R6QV2kqcccVf/ClaMyGt9evfqyS1HoSqMH6cv2asiy14Up0
 2rmPXRDlRyjHiwxb9fTk5YENZakp9JmDq6dK/tMRQ+AQL8vcY4dmxGxY870JCpKg/xmy
 yTjyZiinnyxXYXJrWefCBwBESFXpPaPYtaEf5AxFHWuii5NOKLlHO1kni0rFRY3Ny7Vw
 t6HgBtyu/uIFR7mCTkIfkRvUuJGWZnnrnW7yTKhPUDtrwO/dC2Pnpx/FIMhkZiTbF2Vy
 qukyXO5ROqBBoOWCFT+jT7m58nl26HBlf9EXogwFgl1b3UhlM0wyE4uzULTkHdechQQx
 ZBIA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to
 :message-id:user-agent:mime-version:content-transfer-encoding;
 bh=5b6vnPJ0W2h8O+yK/TV56KKrXrnrHYmKlpTAZrWxTIY=;
 b=g3A2YGc/1QPcsRT330AXqc2qQulO0lMJ/0g5MtFRpVQ+DuVY12pGGmofic9T2ZXYOO
 rDHNWpU+xe79D99JzVlBGF4YzowlY8kQkos6XYNFly5cjqNvmTOb1B1NSbOoi1p+A9Mf
 xi+Eczw9k7QoTfg96awBWBEn8qOWdDD7TvxbLE/9Wcm5DPMajNQc9fY7zxaOLr9yqpqa
 AUi1nZp3vFdLQhyN6j5Rs5bxJn2AFcJ5nBV2+znZvFN+I+pbNc4sX9SF18tJnpm1w4ff
 cSGETmw5wAfyz4JAoV3imHBoQ13uAwE4T1+KxNDg+qp6EsDn6Cg23I8FAX5GSsyy7PKh
 pzrQ==
X-Gm-Message-State: AKGB3mIU/XyrFcHs8wX9U7M9aoHg7BmWsa5NQVFCh6iPUqTyE54BOdjx
 6Jda8DgVgbB+EqZw1jOZkGU=
X-Google-Smtp-Source: ACJfBov5wsbQc9EIK2Tn9mikLh29SAenSDe9K8rLYzF6mzueR4s1BZarEjwGor0YtSwZ2n928Qn1Hg==
X-Received: by 10.99.189.81 with SMTP id d17mr30987233pgp.370.1516116286716;
 Tue, 16 Jan 2018 07:24:46 -0800 (PST)
Received: from debian (n218250002129.netvigator.com. [218.250.2.129])
 by smtp.gmail.com with ESMTPSA id l8sm3791326pgc.58.2018.01.16.07.24.45
 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);
 Tue, 16 Jan 2018 07:24:46 -0800 (PST)
From: Alex Vong <alexvong1995@HIDDEN>
To: ludo@HIDDEN (Ludovic =?utf-8?Q?Court=C3=A8s?=)
Subject: Re: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation
 technique.
References: <877esksi62.fsf@HIDDEN> <87d12bgpqh.fsf@HIDDEN>
 <87a7xet06p.fsf@HIDDEN> <87a7xd6ffu.fsf@HIDDEN>
Date: Tue, 16 Jan 2018 23:24:35 +0800
In-Reply-To: <87a7xd6ffu.fsf@HIDDEN> ("Ludovic
 \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\=
 \=\?utf-8\?Q\?s\?\= message of "Tue, 16 Jan 2018 15:33:57 +0100")
Message-ID: <876081u8r0.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: 0.3 (/)
X-Debbugs-Envelope-To: 30111
Cc: 30111 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: 0.3 (/)

ludo@HIDDEN (Ludovic Court=C3=A8s) writes:

> Hi Alex,
>
> Alex Vong <alexvong1995@HIDDEN> skribis:
>
>> From aea3d11f59e260111bdb8bcac458c97a946fa900 Mon Sep 17 00:00:00 2001
>> From: Alex Vong <alexvong1995@HIDDEN>
>> Date: Tue, 16 Jan 2018 20:32:32 +0800
>> Subject: [PATCH] gnu: gcc@7: Apply the 'retpoline' mitigation technique.
>>
>> This is part of Spectre (branch target injection) [CVE-2017-5715]
>> mitigation. Suggested by Mark H Weaver <mhw@HIDDEN>.
>>
>> * gnu/local.mk (dist_patch_DATA): Add them.
>> * gnu/packages/gcc.scm (gcc@7): Use them.
>> * gnu/packages/patches/gcc-retpoline-Change-V-to-bare-reg-names.patch,
>> gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix8=
6_frame-to-avoi.patch,
>> gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machin=
e_function.patch,
>> gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_fra=
me-to-avoid-cop.patch,
>> gnu/packages/patches/gcc-retpoline-indirect-thunk-reg-names.patch,
>> gnu/packages/patches/gcc-retpoline-x86-Add-V-register-operand-modifier.p=
atch,
>> gnu/packages/patches/gcc-retpoline-x86-Add-mfunction-return.patch,
>> gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch-register.pat=
ch,
>> gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch.patch,
>> gnu/packages/patches/gcc-retpoline-x86-Disallow-mindirect-branch-mfuncti=
on-return-with-.patch:
>> New files.
>
> I=E2=80=99d suggest removing the test suite changes from the patches (cur=
rently
> we don=E2=80=99t run GCC=E2=80=99s test suite.)  Also, =E2=80=98guix lint=
=E2=80=99 may suggest using
> shorter file names.
>
OK, no problem.

> Do you know if a new 7.x including retpoline support is scheduled for
> release soon?
>
Yes, I think they will appear in 7.3 according to [0]. Also, some
changes appear to be in gcc-7-branch already[1]. Do you think we should
wait for it instead?

[0]: https://gcc.gnu.org/ml/gcc-patches/2018-01/msg01400.html
[1]: https://gcc.gnu.org/git/?p=3Dgcc.git;a=3Dshortlog;h=3Drefs/heads/gcc-7=
-branch

> Thanks,
> Ludo=E2=80=99.




Information forwarded to guix-patches@HIDDEN:
bug#30111; Package guix-patches. Full text available.

Message received at 30111 <at> debbugs.gnu.org:


Received: (at 30111) by debbugs.gnu.org; 16 Jan 2018 14:34:03 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Jan 16 09:34:03 2018
Received: from localhost ([127.0.0.1]:58217 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1ebSJP-0000yP-AL
	for submit <at> debbugs.gnu.org; Tue, 16 Jan 2018 09:34:03 -0500
Received: from hera.aquilenet.fr ([185.233.100.1]:54298)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1ebSJL-0000xy-4G
 for 30111 <at> debbugs.gnu.org; Tue, 16 Jan 2018 09:34:01 -0500
Received: from localhost (localhost [127.0.0.1])
 by hera.aquilenet.fr (Postfix) with ESMTP id 9CDF410DA4;
 Tue, 16 Jan 2018 15:33:58 +0100 (CET)
X-Virus-Scanned: Debian amavisd-new at aquilenet.fr
Received: from hera.aquilenet.fr ([127.0.0.1])
 by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id avDAZtBmLA3A; Tue, 16 Jan 2018 15:33:57 +0100 (CET)
Received: from ribbon (unknown [193.50.110.60])
 by hera.aquilenet.fr (Postfix) with ESMTPSA id C63F810D30;
 Tue, 16 Jan 2018 15:33:57 +0100 (CET)
From: ludo@HIDDEN (Ludovic =?utf-8?Q?Court=C3=A8s?=)
To: Alex Vong <alexvong1995@HIDDEN>
Subject: Re: [bug#30111] gnu: gcc@7: Apply the 'retpoline' mitigation
 technique.
References: <877esksi62.fsf@HIDDEN> <87d12bgpqh.fsf@HIDDEN>
 <87a7xet06p.fsf@HIDDEN>
X-URL: http://www.fdn.fr/~lcourtes/
X-Revolutionary-Date: 27 =?utf-8?Q?Niv=C3=B4se?= an 226 de la =?utf-8?Q?R?=
 =?utf-8?Q?=C3=A9volution?=
X-PGP-Key-ID: 0x090B11993D9AEBB5
X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc
X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4  0CFB 090B 1199 3D9A EBB5
X-OS: x86_64-pc-linux-gnu
Date: Tue, 16 Jan 2018 15:33:57 +0100
In-Reply-To: <87a7xet06p.fsf@HIDDEN> (Alex Vong's message of "Tue, 16 Jan
 2018 21:14:54 +0800")
Message-ID: <87a7xd6ffu.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: 1.0 (+)
X-Debbugs-Envelope-To: 30111
Cc: 30111 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: 1.0 (+)

Hi Alex,

Alex Vong <alexvong1995@HIDDEN> skribis:

> From aea3d11f59e260111bdb8bcac458c97a946fa900 Mon Sep 17 00:00:00 2001
> From: Alex Vong <alexvong1995@HIDDEN>
> Date: Tue, 16 Jan 2018 20:32:32 +0800
> Subject: [PATCH] gnu: gcc@7: Apply the 'retpoline' mitigation technique.
>
> This is part of Spectre (branch target injection) [CVE-2017-5715]
> mitigation. Suggested by Mark H Weaver <mhw@HIDDEN>.
>
> * gnu/local.mk (dist_patch_DATA): Add them.
> * gnu/packages/gcc.scm (gcc@7): Use them.
> * gnu/packages/patches/gcc-retpoline-Change-V-to-bare-reg-names.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_fram=
e-to-avoid-cop.patch,
> gnu/packages/patches/gcc-retpoline-indirect-thunk-reg-names.patch,
> gnu/packages/patches/gcc-retpoline-x86-Add-V-register-operand-modifier.pa=
tch,
> gnu/packages/patches/gcc-retpoline-x86-Add-mfunction-return.patch,
> gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch-register.patc=
h,
> gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch.patch,
> gnu/packages/patches/gcc-retpoline-x86-Disallow-mindirect-branch-mfunctio=
n-return-with-.patch:
> New files.

I=E2=80=99d suggest removing the test suite changes from the patches (curre=
ntly
we don=E2=80=99t run GCC=E2=80=99s test suite.)  Also, =E2=80=98guix lint=
=E2=80=99 may suggest using
shorter file names.

Do you know if a new 7.x including retpoline support is scheduled for
release soon?

Thanks,
Ludo=E2=80=99.




Information forwarded to guix-patches@HIDDEN:
bug#30111; Package guix-patches. Full text available.

Message received at 30111 <at> debbugs.gnu.org:


Received: (at 30111) by debbugs.gnu.org; 16 Jan 2018 13:15:19 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Jan 16 08:15:19 2018
Received: from localhost ([127.0.0.1]:58175 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1ebR5D-0007Wv-AU
	for submit <at> debbugs.gnu.org; Tue, 16 Jan 2018 08:15:19 -0500
Received: from mail-pf0-f169.google.com ([209.85.192.169]:34098)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <alexvong1995@HIDDEN>) id 1ebR5C-0007Wj-0W
 for 30111 <at> debbugs.gnu.org; Tue, 16 Jan 2018 08:15:18 -0500
Received: by mail-pf0-f169.google.com with SMTP id e76so9658410pfk.1
 for <30111 <at> debbugs.gnu.org>; Tue, 16 Jan 2018 05:15:17 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:subject:references:date:in-reply-to:message-id:user-agent
 :mime-version; bh=6nQ9aAckMMlFfgpjR38uza66YRiUOQhZ70cb27Jdn2g=;
 b=gk9BCi+C1/HPneCcNdfZouUgFhO0OqfsBz7XqYarKG4z31Ri4y6buGW4eRR/1aDbrN
 VUaGkF2jqwyO/n3SunyKWpfzQuV9rUC0v+oomgib7x13zArM4U9/CoxMfp+p8Fe+2XYU
 ZmB2HTsnZBk2xUgPy7Ko+N2e8vJdjokFUSHYdQcNL5WhaSXk2XcXw0HlQ7q3MwLuZe9/
 Vz+u3h7eX/eVjc6gCzZo5vqBHMBi3XvX7eHyRdFFJCYiSGtj3B/Lz5WfQnPewLtgmUW5
 K0mSmBSDr7etreSCs+xVWrIVlB48hbpvUIsL0otaddg/fR4H7ylQ1x4bCU4COBuesb+9
 hl4A==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:subject:references:date:in-reply-to
 :message-id:user-agent:mime-version;
 bh=6nQ9aAckMMlFfgpjR38uza66YRiUOQhZ70cb27Jdn2g=;
 b=Q0V34CDKFkfVhROjs01+QCr5WPo22ksVrlfZBXGyObVhO0JN0CtR5/p+1tgEW1mEkE
 1qn6myJJGjpy030P8SSiCOW63PQbWIK+KVN7YjNLnWZppVd91FtwbOS7inl5tht914OA
 7jxissRNMnihi5F0ehgqvc/j97QAhSxy/jedsW8QMCWIET6dKkVVGdhM84uUnyEVSTwt
 0qVAn6edRyhpJLDqyUFQZOx05PgpNBhcb00VpohhqXY9pxXEiPIt9zomT/sZlQQakNqw
 cK0+dceUW1XJEiaSy791vcsuR4uqoRwhC5hPnlGaxSkj6tq4KYbup468atSAIwjPvgEw
 xdIg==
X-Gm-Message-State: AKGB3mIfylLtkCY7pK5XkZLr+KKpzplCaKhOX+CwaaG8FvWMOib0rSKi
 0L/jhk+VvfK1q8HxT41c6jk=
X-Google-Smtp-Source: ACJfBoupBAUJbcGMPWlgVbPKYSYWTwPRzegCtRv5bVNXaZBxZNoKH6/tvchshzqGnXAupwvNwVowFA==
X-Received: by 10.98.98.5 with SMTP id w5mr34296309pfb.233.1516108512160;
 Tue, 16 Jan 2018 05:15:12 -0800 (PST)
Received: from debian (n218250002129.netvigator.com. [218.250.2.129])
 by smtp.gmail.com with ESMTPSA id u195sm3733537pgb.64.2018.01.16.05.15.08
 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);
 Tue, 16 Jan 2018 05:15:11 -0800 (PST)
From: Alex Vong <alexvong1995@HIDDEN>
To: 30111 <at> debbugs.gnu.org
Subject: Re: gnu: gcc@7: Apply the 'retpoline' mitigation technique.
References: <877esksi62.fsf@HIDDEN> <87d12bgpqh.fsf@HIDDEN>
Date: Tue, 16 Jan 2018 21:14:54 +0800
In-Reply-To: <87d12bgpqh.fsf@HIDDEN> (Alex Vong's message of "Mon, 15 Jan
 2018 22:29:10 +0800")
Message-ID: <87a7xet06p.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-Debbugs-Envelope-To: 30111
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>

--=-=-=
Content-Type: text/plain

Hello,

This is the new patch. Similar to last time, I haven't test it yet, but
I will report if it doesn't build.


--=-=-=
Content-Type: text/x-diff; charset=utf-8
Content-Disposition: inline;
 filename=0001-gnu-gcc-7-Apply-the-retpoline-mitigation-technique.patch
Content-Transfer-Encoding: quoted-printable

From aea3d11f59e260111bdb8bcac458c97a946fa900 Mon Sep 17 00:00:00 2001
From: Alex Vong <alexvong1995@HIDDEN>
Date: Tue, 16 Jan 2018 20:32:32 +0800
Subject: [PATCH] gnu: gcc@7: Apply the 'retpoline' mitigation technique.

This is part of Spectre (branch target injection) [CVE-2017-5715]
mitigation. Suggested by Mark H Weaver <mhw@HIDDEN>.

* gnu/local.mk (dist_patch_DATA): Add them.
* gnu/packages/gcc.scm (gcc@7): Use them.
* gnu/packages/patches/gcc-retpoline-Change-V-to-bare-reg-names.patch,
gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_f=
rame-to-avoi.patch,
gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_f=
unction.patch,
gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_frame-=
to-avoid-cop.patch,
gnu/packages/patches/gcc-retpoline-indirect-thunk-reg-names.patch,
gnu/packages/patches/gcc-retpoline-x86-Add-V-register-operand-modifier.patc=
h,
gnu/packages/patches/gcc-retpoline-x86-Add-mfunction-return.patch,
gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch-register.patch,
gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch.patch,
gnu/packages/patches/gcc-retpoline-x86-Disallow-mindirect-branch-mfunction-=
return-with-.patch:
New files.
---
 gnu/local.mk                                       |   12 +-
 gnu/packages/gcc.scm                               |   13 +-
 .../gcc-retpoline-Change-V-to-bare-reg-names.patch |   51 +
 ...se-reference-of-struct-ix86_frame-to-avoi.patch |   69 +
 ...ove-struct-ix86_frame-to-machine_function.patch |  252 +++
 ...ference-of-struct-ix86_frame-to-avoid-cop.patch |   83 +
 .../gcc-retpoline-indirect-thunk-reg-names.patch   |  365 ++++
 ...oline-x86-Add-V-register-operand-modifier.patch |  143 ++
 .../gcc-retpoline-x86-Add-mfunction-return.patch   | 1303 ++++++++++++
 ...tpoline-x86-Add-mindirect-branch-register.patch |  907 ++++++++
 .../gcc-retpoline-x86-Add-mindirect-branch.patch   | 2171 ++++++++++++++++=
++++
 ...w-mindirect-branch-mfunction-return-with-.patch |  308 +++
 12 files changed, 5675 insertions(+), 2 deletions(-)
 create mode 100644 gnu/packages/patches/gcc-retpoline-Change-V-to-bare-reg=
-names.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-i386-More-use-refere=
nce-of-struct-ix86_frame-to-avoi.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix8=
6_frame-to-machine_function.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Use-reference-o=
f-struct-ix86_frame-to-avoid-cop.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-indirect-thunk-reg-n=
ames.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-x86-Add-V-register-o=
perand-modifier.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-x86-Add-mfunction-re=
turn.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-br=
anch-register.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-br=
anch.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-x86-Disallow-mindire=
ct-branch-mfunction-return-with-.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index fb4babfdb..b84d0b545 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -9,7 +9,7 @@
 # Copyright =C2=A9 2016 Adonay "adfeno" Felipe Nogueira <https://libreplan=
et.org/wiki/User:Adfeno> <adfeno@HIDDEN>
 # Copyright =C2=A9 2016, 2017 Ricardo Wurmus <rekado@HIDDEN>
 # Copyright =C2=A9 2016 Ben Woodcroft <donttrustben@HIDDEN>
-# Copyright =C2=A9 2016, 2017 Alex Vong <alexvong1995@HIDDEN>
+# Copyright =C2=A9 2016, 2017, 2018 Alex Vong <alexvong1995@HIDDEN>
 # Copyright =C2=A9 2016, 2017 Efraim Flashner <efraim@HIDDEN>
 # Copyright =C2=A9 2016, 2017 Jan Nieuwenhuizen <janneke@HIDDEN>
 # Copyright =C2=A9 2017 Tobias Geerinckx-Rice <me@HIDDEN>
@@ -654,6 +654,16 @@ dist_patch_DATA =3D						\
   %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-machin=
e_function.patch	\
+  %D%/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_fra=
me-to-avoid-cop.patch	\
+  %D%/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix8=
6_frame-to-avoi.patch	\
+  %D%/packages/patches/gcc-retpoline-x86-Add-mindirect-branch.patch	\
+  %D%/packages/patches/gcc-retpoline-x86-Add-mfunction-return.patch	\
+  %D%/packages/patches/gcc-retpoline-x86-Add-mindirect-branch-register.pat=
ch	\
+  %D%/packages/patches/gcc-retpoline-x86-Add-V-register-operand-modifier.p=
atch	\
+  %D%/packages/patches/gcc-retpoline-x86-Disallow-mindirect-branch-mfuncti=
on-return-with-.patch	\
+  %D%/packages/patches/gcc-retpoline-Change-V-to-bare-reg-names.patch	\
+  %D%/packages/patches/gcc-retpoline-indirect-thunk-reg-names.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..89d2ab7fd 100644
--- a/gnu/packages/gcc.scm
+++ b/gnu/packages/gcc.scm
@@ -5,6 +5,7 @@
 ;;; Copyright =C2=A9 2015 Andreas Enge <andreas@HIDDEN>
 ;;; Copyright =C2=A9 2015, 2016, 2017 Efraim Flashner <efraim@HIDDEN=
il>
 ;;; Copyright =C2=A9 2016 Carlos S=C3=A1nchez de La Lama <csanchezdll@gmai=
l.com>
+;;; Copyright =C2=A9 2018 ALex Vong <alexvong1995@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -427,7 +428,17 @@ Go.  It also includes runtime support libraries for th=
ese 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-ix8=
6_frame-to-machine_function.patch"
+                                       "gcc-retpoline-i386-Use-reference-o=
f-struct-ix86_frame-to-avoid-cop.patch"
+                                       "gcc-retpoline-i386-More-use-refere=
nce-of-struct-ix86_frame-to-avoi.patch"
+                                       "gcc-retpoline-x86-Add-mindirect-br=
anch.patch"
+                                       "gcc-retpoline-x86-Add-mfunction-re=
turn.patch"
+                                       "gcc-retpoline-x86-Add-mindirect-br=
anch-register.patch"
+                                       "gcc-retpoline-x86-Add-V-register-o=
perand-modifier.patch"
+                                       "gcc-retpoline-x86-Disallow-mindire=
ct-branch-mfunction-return-with-.patch"
+                                       "gcc-retpoline-Change-V-to-bare-reg=
-names.patch"
+                                       "gcc-retpoline-indirect-thunk-reg-n=
ames.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-Change-V-to-bare-reg-names.=
patch b/gnu/packages/patches/gcc-retpoline-Change-V-to-bare-reg-names.patch
new file mode 100644
index 000000000..1d893a621
--- /dev/null
+++ b/gnu/packages/patches/gcc-retpoline-Change-V-to-bare-reg-names.patch
@@ -0,0 +1,51 @@
+'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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-regnames' branch of upstream source repos=
itory
+(please keep an eye for new branches or updates for existing branches):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From c26d2b96599ebc9ff24c685a2dc3b01709aa3cce Mon Sep 17 00:00:00 2001
+From: David Woodhouse <dwmw2@HIDDEN>
+Date: Sun, 14 Jan 2018 21:27:35 +0000
+Subject: [PATCH 09/10] Change %V to bare reg names
+
+---
+ gcc/config/i386/i386.c                                    | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index 318a71840c9..6d345031a82 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -18029,7 +18029,7 @@ print_reg (rtx x, int code, FILE *file)
+ 	warning (0, "unsupported size for integer register");
+       /* FALLTHRU */
+     case 4:
+-      if (LEGACY_INT_REGNO_P (regno))
++      if (LEGACY_INT_REGNO_P (regno) && code !=3D 'V')
+ 	putc (msize > 4 && TARGET_64BIT ? 'r' : 'e', file);
+       /* FALLTHRU */
+     case 2:
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c b/g=
cc/testsuite/gcc.target/i386/indirect-thunk-register-4.c
+index f0cd9b75be8..6791890944c 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c
+@@ -9,5 +9,5 @@ foo (void)
+   asm("call __x86_indirect_thunk_%V0" : : "a" (func_p));
+ }
+=20
+-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_eax" { t=
arget ia32 } } } */
+-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_rax" { t=
arget { ! ia32 } } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_ax" { ta=
rget ia32 } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_ax" { ta=
rget { ! ia32 } } } } */
+--=20
+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-M=
ore-use-reference-of-struct-ix86_frame-to-avoi.patch
new file mode 100644
index 000000000..e115e3f6c
--- /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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-regnames' branch of upstream source repos=
itory
+(please keep an eye for new branches or updates for existing branches):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From ec4a7ca4051bb5cbefe03a2e1fb690b9738b8c6d Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Tue, 28 Nov 2017 10:26:35 -0800
+Subject: [PATCH 03/10] i386: More use reference of struct ix86_frame to av=
oid
+ copy
+
+When there is no need to make a copy of ix86_frame, we can use reference
+of struct ix86_frame to avoid copy.
+
+	Backport from mainline
+	* 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 397ef7cac26..986e6d79584 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -13667,7 +13667,6 @@ ix86_expand_prologue (void)
+ {
+   struct machine_function *m =3D cfun->machine;
+   rtx insn, t;
+-  struct ix86_frame frame;
+   HOST_WIDE_INT allocate;
+   bool int_registers_saved;
+   bool sse_registers_saved;
+@@ -13691,7 +13690,7 @@ ix86_expand_prologue (void)
+   m->fs.sp_valid =3D true;
+=20
+   ix86_compute_frame_layout ();
+-  frame =3D m->frame;
++  struct ix86_frame &frame =3D cfun->machine->frame;
+=20
+   if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_d=
ecl))
+     {
+@@ -14354,13 +14353,12 @@ ix86_expand_epilogue (int style)
+ {
+   struct machine_function *m =3D cfun->machine;
+   struct machine_frame_state frame_state_save =3D m->fs;
+-  struct ix86_frame frame;
+   bool restore_regs_via_mov;
+   bool using_drap;
+=20
+   ix86_finalize_stack_realign_flags ();
+   ix86_compute_frame_layout ();
+-  frame =3D m->frame;
++  struct ix86_frame &frame =3D cfun->machine->frame;
+=20
+   m->fs.sp_valid =3D (!frame_pointer_needed
+ 		    || (crtl->sp_is_unchanging
+--=20
+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-s=
truct-ix86_frame-to-machine_function.patch
new file mode 100644
index 000000000..b55ee3407
--- /dev/null
+++ b/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-mac=
hine_function.patch
@@ -0,0 +1,252 @@
+'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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-regnames' branch of upstream source repos=
itory
+(please keep an eye for new branches or updates for existing branches):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From f23f45109139911714e2164191c0228500ebef92 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Mon, 6 Nov 2017 09:11:08 -0800
+Subject: [PATCH 01/10] i386: Move struct ix86_frame to machine_function
+
+Make ix86_frame available to i386 code generation.  This is needed to
+backport the patch set of -mindirect-branch=3D to mitigate variant #2 of
+the speculative execution vulnerabilities on x86 processors identified
+by CVE-2017-5715, aka Spectre.
+
+	Backport from mainline
+	* 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 8a3782c0298..813337242d8 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -2444,53 +2444,6 @@ struct GTY(()) stack_local_entry {
+   struct stack_local_entry *next;
+ };
+=20
+-/* 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]	       | =3D 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;
+=20
+@@ -2582,7 +2535,7 @@ static unsigned int ix86_function_arg_boundary (mach=
ine_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);
+@@ -11903,7 +11856,8 @@ ix86_can_use_return_insn_p (void)
+   if (crtl->args.pops_args && crtl->args.size >=3D 32768)
+     return 0;
+=20
+-  ix86_compute_frame_layout (&frame);
++  ix86_compute_frame_layout ();
++  frame =3D cfun->machine->frame;
+   return (frame.stack_pointer_offset =3D=3D UNITS_PER_WORD
+ 	  && (frame.nregs + frame.nsseregs) =3D=3D 0);
+ }
+@@ -12389,8 +12343,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 =3D cfun->machine->frame;
+=20
+   if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME_POINTER_REGN=
UM)
+     return frame.hard_frame_pointer_offset;
+@@ -12429,8 +12383,9 @@ ix86_builtin_setjmp_frame_value (void)
+ /* Fill structure ix86_frame about frame of currently computed function. =
 */
+=20
+ static void
+-ix86_compute_frame_layout (struct ix86_frame *frame)
++ix86_compute_frame_layout (void)
+ {
++  struct ix86_frame *frame =3D &cfun->machine->frame;
+   unsigned HOST_WIDE_INT stack_alignment_needed;
+   HOST_WIDE_INT offset;
+   unsigned HOST_WIDE_INT preferred_alignment;
+@@ -13737,7 +13692,8 @@ ix86_expand_prologue (void)
+   m->fs.sp_offset =3D INCOMING_FRAME_SP_OFFSET;
+   m->fs.sp_valid =3D true;
+=20
+-  ix86_compute_frame_layout (&frame);
++  ix86_compute_frame_layout ();
++  frame =3D m->frame;
+=20
+   if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_d=
ecl))
+     {
+@@ -14405,7 +14361,8 @@ ix86_expand_epilogue (int style)
+   bool using_drap;
+=20
+   ix86_finalize_stack_realign_flags ();
+-  ix86_compute_frame_layout (&frame);
++  ix86_compute_frame_layout ();
++  frame =3D m->frame;
+=20
+   m->fs.sp_valid =3D (!frame_pointer_needed
+ 		    || (crtl->sp_is_unchanging
+@@ -14915,7 +14872,8 @@ ix86_expand_split_stack_prologue (void)
+   gcc_assert (flag_split_stack && reload_completed);
+=20
+   ix86_finalize_stack_realign_flags ();
+-  ix86_compute_frame_layout (&frame);
++  ix86_compute_frame_layout ();
++  frame =3D cfun->machine->frame;
+   allocate =3D frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
+=20
+   /* 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 9c776dc5172..f9b91286a01 100644
+--- a/gcc/config/i386/i386.h
++++ b/gcc/config/i386/i386.h
+@@ -2451,9 +2451,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]	       | =3D 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.  =
*/
+=20
+-#ifndef USED_FOR_TARGET
+ struct GTY(()) machine_frame_state
+ {
+   /* This pair tracks the currently active CFA as reg+offset.  When reg
+@@ -2512,6 +2559,9 @@ struct GTY(()) machine_function {
+   int varargs_fpr_size;
+   int optimize_mode_switching[MAX_386_ENTITIES];
+=20
++  /* 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;
+@@ -2594,6 +2644,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)
+=20
+ /* Control behavior of x86_file_start.  */
+ #define X86_FILE_START_VERSION_DIRECTIVE false
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struc=
t-ix86_frame-to-avoid-cop.patch b/gnu/packages/patches/gcc-retpoline-i386-U=
se-reference-of-struct-ix86_frame-to-avoid-cop.patch
new file mode 100644
index 000000000..30eca1a43
--- /dev/null
+++ b/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_=
frame-to-avoid-cop.patch
@@ -0,0 +1,83 @@
+'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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-regnames' branch of upstream source repos=
itory
+(please keep an eye for new branches or updates for existing branches):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From ca658cd57c02a81327ec09474e24f0688ac1a190 Mon Sep 17 00:00:00 2001
+From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Mon, 6 Nov 2017 23:04:15 +0000
+Subject: [PATCH 02/10] i386: Use reference of struct ix86_frame to avoid c=
opy
+
+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.
+
+	Backport from mainline
+	* 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.
+---
+ 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 813337242d8..397ef7cac26 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -11843,8 +11843,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
+@@ -11857,7 +11855,7 @@ ix86_can_use_return_insn_p (void)
+     return 0;
+=20
+   ix86_compute_frame_layout ();
+-  frame =3D cfun->machine->frame;
++  struct ix86_frame &frame =3D cfun->machine->frame;
+   return (frame.stack_pointer_offset =3D=3D UNITS_PER_WORD
+ 	  && (frame.nregs + frame.nsseregs) =3D=3D 0);
+ }
+@@ -12344,7 +12342,7 @@ HOST_WIDE_INT
+ ix86_initial_elimination_offset (int from, int to)
+ {
+   ix86_compute_frame_layout ();
+-  struct ix86_frame frame =3D cfun->machine->frame;
++  struct ix86_frame &frame =3D cfun->machine->frame;
+=20
+   if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME_POINTER_REGN=
UM)
+     return frame.hard_frame_pointer_offset;
+@@ -14860,7 +14858,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;
+@@ -14873,7 +14870,7 @@ ix86_expand_split_stack_prologue (void)
+=20
+   ix86_finalize_stack_realign_flags ();
+   ix86_compute_frame_layout ();
+-  frame =3D cfun->machine->frame;
++  struct ix86_frame &frame =3D cfun->machine->frame;
+   allocate =3D frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
+=20
+   /* This is the label we will branch to if we have enough stack
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-indirect-thunk-reg-names.pa=
tch b/gnu/packages/patches/gcc-retpoline-indirect-thunk-reg-names.patch
new file mode 100644
index 000000000..6da7b48c3
--- /dev/null
+++ b/gnu/packages/patches/gcc-retpoline-indirect-thunk-reg-names.patch
@@ -0,0 +1,365 @@
+'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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-regnames' branch of upstream source repos=
itory
+(please keep an eye for new branches or updates for existing branches):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From f6d256da9cefa1409598fa5ffe632647a30ad6f9 Mon Sep 17 00:00:00 2001
+From: David Woodhouse <dwmw2@HIDDEN>
+Date: Sun, 14 Jan 2018 21:36:59 +0000
+Subject: [PATCH 10/10] indirect thunk reg names
+
+---
+ gcc/config/i386/i386.c                                    | 9 ++-------
+ 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-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-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-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-7.c   | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c | 2 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c | 2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-10.c              | 4 ++--
+ gcc/testsuite/gcc.target/i386/ret-thunk-11.c              | 4 ++--
+ gcc/testsuite/gcc.target/i386/ret-thunk-12.c              | 4 ++--
+ 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 +-
+ 25 files changed, 29 insertions(+), 34 deletions(-)
+
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index 6d345031a82..89eb68032a2 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -12052,13 +12052,8 @@ indirect_thunk_name (char name[32], int regno, bo=
ol need_bnd_p,
+       const char *bnd =3D need_bnd_p ? "_bnd" : "";
+       if (regno >=3D 0)
+ 	{
+-	  const char *reg_prefix;
+-	  if (LEGACY_INT_REGNO_P (regno))
+-	    reg_prefix =3D TARGET_64BIT ? "r" : "e";
+-	  else
+-	    reg_prefix =3D "";
+-	  sprintf (name, "__x86_indirect_thunk%s_%s%s",
+-		   bnd, reg_prefix, reg_names[regno]);
++	  sprintf (name, "__x86_indirect_thunk%s_%s",
++		   bnd, reg_names[regno]);
+ 	}
+       else
+ 	{
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-1.c
+index 9eb9b273ade..fb56b2db3b6 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+@@ -13,7 +13,7 @@ male_indirect_jump (long offset)
+=20
+ /* { 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_ax" { tar=
get 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-2.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-2.c
+index c63795e4127..337f455aa44 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+@@ -13,7 +13,7 @@ male_indirect_jump (long offset)
+=20
+ /* { 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_ax" { tar=
get 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-3.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-3.c
+index 82973cda771..2e40ec71609 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+@@ -14,7 +14,7 @@ male_indirect_jump (long offset)
+=20
+ /* { 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta=
rget 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-4.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-4.c
+index a5f3d1cbed8..309d1f6c10b 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+@@ -14,7 +14,7 @@ male_indirect_jump (long offset)
+=20
+ /* { 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta=
rget 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-7.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-7.c
+index ebfb8aab937..47674395309 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+@@ -37,7 +37,7 @@ bar (int i)
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta=
rget { ! 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_ax" { tar=
get 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-attr-1.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-1.c
+index a08022db8e4..e8cdc4fa05d 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+@@ -16,7 +16,7 @@ male_indirect_jump (long offset)
+=20
+ /* { 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_ax" { tar=
get 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-attr-2.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-2.c
+index b257c695ad1..5f333d86e18 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+@@ -14,7 +14,7 @@ male_indirect_jump (long offset)
+=20
+ /* { 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_ax" { tar=
get 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-attr-5.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-5.c
+index 4bb1c5f9220..fa067b0acc8 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+@@ -18,5 +18,5 @@ male_indirect_jump (long offset)
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x=
32 } } } } */
+ /* { 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta=
rget x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-6.c
+index 4e33a638862..442f97c123c 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+@@ -17,5 +17,5 @@ male_indirect_jump (long offset)
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x=
32 } } } } */
+ /* { 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta=
rget x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-7.c
+index 427ba3ddbb4..64b85fc7b96 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)
+ }
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta=
rget { ! x32 } } } } */
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" =
{ target x32 } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_ax" { tar=
get 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 5c20a35ecec..cb95a09ea34 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+@@ -13,7 +13,7 @@ male_indirect_jump (long offset)
+=20
+ /* { 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_ax" { tar=
get 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 b2fb6e1bcd2..b2af9e96b7e 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+@@ -13,7 +13,7 @@ male_indirect_jump (long offset)
+=20
+ /* { 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_ax" { tar=
get 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 9c84547cd7c..a9a1a8bc177 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+@@ -16,5 +16,5 @@ male_indirect_jump (long offset)
+ /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target=
 { ! x32 } } } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x=
32 } } } } */
+ /* { 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_ax" { ta=
rget 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 457849564bb..bbf3dd24f37 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+@@ -16,5 +16,5 @@ male_indirect_jump (long offset)
+ /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target=
 { ! x32 } } } } */
+ /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x=
32 } } } } */
+ /* { 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_ax" { ta=
rget 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 d4747ea0764..39acad399d3 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+@@ -37,7 +37,7 @@ bar (int i)
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta=
rget { ! 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_ax" { tar=
get 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-register-1.c b/g=
cc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
+index 7d396a31953..0660feeed73 100644
+--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
+@@ -11,7 +11,7 @@ male_indirect_jump (long offset)
+   dispatch(offset);
+ }
+=20
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" =
} } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_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)\\)"=
 } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c b/g=
cc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
+index 5320e923be2..d39e387586e 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);
+ }
+=20
+-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" =
} } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_ax" } } */
+ /* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch"  } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
+ /* { dg-final { scan-assembler-not {\t(pause|pause|nop)} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/=
gcc.target/i386/ret-thunk-10.c
+index b4f9d48065d..2f373c362d0 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
+@@ -18,6 +18,6 @@ foo (void)
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3=
2 } } } } */
+ /* { 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta=
rget { x32 } }  } } */
++/* { dg-final { scan-assembler "__x86_indirect_thunk_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 0312577a043..11e041fda7e 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
+@@ -18,6 +18,6 @@ foo (void)
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3=
2 } } } } */
+ /* { 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta=
rget { x32 } }  } } */
++/* { dg-final { scan-assembler "__x86_indirect_thunk_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 fa3181303c9..f16c1a5d0c6 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
+@@ -17,6 +17,6 @@ foo (void)
+ /* { 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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta=
rget { x32 } }  } } */
++/* { dg-final { scan-assembler "__x86_indirect_thunk_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 7a08e71c76b..b4553216f99 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
+@@ -18,5 +18,5 @@ foo (void)
+ /* { 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 "call\[ \t\]*__x86_indirect_thunk_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 dacf0c769fc..28e5434a004 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
+@@ -18,5 +18,5 @@ foo (void)
+ /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3=
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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta=
rget { 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 cf06a5f35c7..20fad48b790 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
+@@ -18,5 +18,5 @@ foo (void)
+ /* { dg-final { scan-assembler-times {\tlfence} 1 } } */
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3=
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 "call\[ \t\]*__x86_indirect_thunk_ax" { ta=
rget x32 } } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } =
*/
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/g=
cc.target/i386/ret-thunk-9.c
+index 6da5ab97081..8f0375b5def 100644
+--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
+@@ -21,5 +21,5 @@ foo (void)
+ /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target=
 { ! x32 } } } } */
+ /* { dg-final { scan-assembler-times {\tpause} 2 { 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_ax" { ta=
rget { x32 } } } } */
+ /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } =
*/
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-x86-Add-V-register-operand-=
modifier.patch b/gnu/packages/patches/gcc-retpoline-x86-Add-V-register-oper=
and-modifier.patch
new file mode 100644
index 000000000..d47f23942
--- /dev/null
+++ b/gnu/packages/patches/gcc-retpoline-x86-Add-V-register-operand-modifie=
r.patch
@@ -0,0 +1,143 @@
+'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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-regnames' branch of upstream source repos=
itory
+(please keep an eye for new branches or updates for existing branches):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 5e977dfedb93e764dc480c0e0674500590ef5604 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Sat, 6 Jan 2018 22:29:56 -0800
+Subject: [PATCH 07/10] x86: Add 'V' register operand modifier
+
+Add 'V', a special modifier which prints the name of the full integer
+register without '%'.  For
+
+extern void (*func_p) (void);
+
+void
+foo (void)
+{
+  asm ("call __x86_indirect_thunk_%V0" : : "a" (func_p));
+}
+
+it generates:
+
+foo:
+	movq	func_p(%rip), %rax
+	call	__x86_indirect_thunk_rax
+	ret
+
+gcc/
+
+	Backport from mainline
+	* config/i386/i386.c (print_reg): Print the name of the full
+	integer register without '%'.
+	(ix86_print_operand): Handle 'V'.
+	 * doc/extend.texi: Document 'V' modifier.
+
+gcc/testsuite/
+
+	Backport from mainline
+	* gcc.target/i386/indirect-thunk-register-4.c: New test.
+---
+ gcc/config/i386/i386.c                                    | 13 ++++++++++=
++-
+ gcc/doc/extend.texi                                       |  3 +++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c | 13 ++++++++++=
+++
+ 3 files changed, 28 insertions(+), 1 deletion(-)
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-=
4.c
+
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index 4bfe2fa8c1d..e32de13688a 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -17925,6 +17925,7 @@ put_condition_code (enum rtx_code code, machine_mo=
de 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 full integer register name without %.
+  */
+=20
+ void
+@@ -17935,7 +17936,7 @@ print_reg (rtx x, int code, FILE *file)
+   unsigned int regno;
+   bool duplicated;
+=20
+-  if (ASSEMBLER_DIALECT =3D=3D ASM_ATT)
++  if (ASSEMBLER_DIALECT =3D=3D ASM_ATT && code !=3D 'V')
+     putc ('%', file);
+=20
+   if (x =3D=3D pc_rtx)
+@@ -17983,6 +17984,14 @@ print_reg (rtx x, int code, FILE *file)
+       return;
+     }
+=20
++  if (code =3D=3D 'V')
++    {
++      if (GENERAL_REGNO_P (regno))
++	msize =3D GET_MODE_SIZE (word_mode);
++      else
++	error ("'V' modifier on non-integer register");
++    }
++
+   duplicated =3D code =3D=3D 'd' && TARGET_AVX;
+=20
+   switch (msize)
+@@ -18102,6 +18111,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 full integer 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.
+@@ -18326,6 +18336,7 @@ ix86_print_operand (FILE *file, rtx x, int code)
+ 	case 'X':
+ 	case 'P':
+ 	case 'p':
++	case 'V':
+ 	  break;
+=20
+ 	case 's':
+diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
+index 46e0a3623a6..9db9e0e27e9 100644
+--- a/gcc/doc/extend.texi
++++ b/gcc/doc/extend.texi
+@@ -8778,6 +8778,9 @@ The table below shows the list of supported modifier=
s and their effects.
+ @tab @code{2}
+ @end multitable
+=20
++@code{V} is a special modifier which prints the name of the full integer
++register without @code{%}.
++
+ @anchor{x86floatingpointasmoperands}
+ @subsubsection x86 Floating-Point @code{asm} Operands
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c b/g=
cc/testsuite/gcc.target/i386/indirect-thunk-register-4.c
+new file mode 100644
+index 00000000000..f0cd9b75be8
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c
+@@ -0,0 +1,13 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=3Dkeep -fno-pic" } */
++
++extern void (*func_p) (void);
++
++void
++foo (void)
++{
++  asm("call __x86_indirect_thunk_%V0" : : "a" (func_p));
++}
++
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_eax" { t=
arget ia32 } } } */
++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_rax" { t=
arget { ! ia32 } } } } */
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-x86-Add-mfunction-return.pa=
tch b/gnu/packages/patches/gcc-retpoline-x86-Add-mfunction-return.patch
new file mode 100644
index 000000000..bfd154eaa
--- /dev/null
+++ b/gnu/packages/patches/gcc-retpoline-x86-Add-mfunction-return.patch
@@ -0,0 +1,1303 @@
+'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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-regnames' branch of upstream source repos=
itory
+(please keep an eye for new branches or updates for existing branches):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From dfa5f37da1fed9d9439e396fdf49847f4d9184d4 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Sat, 6 Jan 2018 22:29:56 -0800
+Subject: [PATCH 05/10] x86: Add -mfunction-return=3D
+
+Add -mfunction-return=3D option to convert function return to call and
+return thunks.  The default is 'keep', which keeps function return
+unmodified.  'thunk' converts function return to call and return thunk.
+'thunk-inline' converts function return to inlined call and return thunk.
+'thunk-extern' converts function return to external call and return
+thunk provided in a separate object file.  You can control this behavior
+for a specific function by using the function attribute function_return.
+
+Function return thunk is the same as memory thunk for -mindirect-branch=3D
+where the return address is at the top of the stack:
+
+__x86_return_thunk:
+	call L2
+L1:
+	pause
+	lfence
+	jmp L1
+L2:
+	lea 8(%rsp), %rsp|lea 4(%esp), %esp
+	ret
+
+and function return becomes
+
+	jmp __x86_return_thunk
+
+-mindirect-branch=3D tests are updated with -mfunction-return=3Dkeep to
+avoid false test failures when -mfunction-return=3Dthunk is added to
+RUNTESTFLAGS for "make check".
+
+gcc/
+
+	Backport from mainline
+	* config/i386/i386-protos.h (ix86_output_function_return): New.
+	* config/i386/i386.c (ix86_set_indirect_branch_type): Also
+	set function_return_type.
+	(indirect_thunk_name): Add ret_p to indicate thunk for function
+	return.
+	(output_indirect_thunk_function): Pass false to
+	indirect_thunk_name.
+	(ix86_output_indirect_branch): Likewise.
+	(output_indirect_thunk_function): Create alias for function
+	return thunk if regno < 0.
+	(ix86_output_function_return): New function.
+	(ix86_handle_fndecl_attribute): Handle function_return.
+	(ix86_attribute_table): Add function_return.
+	* config/i386/i386.h (machine_function): Add
+	function_return_type.
+	* config/i386/i386.md (simple_return_internal): Use
+	ix86_output_function_return.
+	(simple_return_internal_long): Likewise.
+	* config/i386/i386.opt (mfunction-return=3D): New option.
+	(indirect_branch): Mention -mfunction-return=3D.
+	* doc/extend.texi: Document function_return function attribute.
+	* doc/invoke.texi: Document -mfunction-return=3D option.
+
+gcc/testsuite/
+
+	Backport from mainline
+	* gcc.target/i386/indirect-thunk-1.c (dg-options): Add
+	-mfunction-return=3Dkeep.
+	* gcc.target/i386/indirect-thunk-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-5.c: Likewise.
+	* gcc.target/i386/indirect-thunk-6.c: Likewise.
+	* gcc.target/i386/indirect-thunk-7.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-1.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-5.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-6.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-7.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-8.c: Likewise.
+	* gcc.target/i386/indirect-thunk-bnd-1.c: Likewise.
+	* gcc.target/i386/indirect-thunk-bnd-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-bnd-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-bnd-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-1.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-5.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-6.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-7.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-1.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-5.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-6.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-7.c: Likewise.
+	* gcc.target/i386/ret-thunk-1.c: New test.
+	* gcc.target/i386/ret-thunk-10.c: Likewise.
+	* gcc.target/i386/ret-thunk-11.c: Likewise.
+	* gcc.target/i386/ret-thunk-12.c: Likewise.
+	* gcc.target/i386/ret-thunk-13.c: Likewise.
+	* gcc.target/i386/ret-thunk-14.c: Likewise.
+	* gcc.target/i386/ret-thunk-15.c: Likewise.
+	* gcc.target/i386/ret-thunk-16.c: Likewise.
+	* gcc.target/i386/ret-thunk-2.c: Likewise.
+	* gcc.target/i386/ret-thunk-3.c: Likewise.
+	* gcc.target/i386/ret-thunk-4.c: Likewise.
+	* gcc.target/i386/ret-thunk-5.c: Likewise.
+	* gcc.target/i386/ret-thunk-6.c: Likewise.
+	* gcc.target/i386/ret-thunk-7.c: Likewise.
+	* gcc.target/i386/ret-thunk-8.c: Likewise.
+	* gcc.target/i386/ret-thunk-9.c: Likewise.
+---
+ gcc/config/i386/i386-protos.h                      |   1 +
+ gcc/config/i386/i386.c                             | 151 ++++++++++++++++=
+++--
+ gcc/config/i386/i386.h                             |   3 +
+ gcc/config/i386/i386.md                            |   9 +-
+ gcc/config/i386/i386.opt                           |   6 +-
+ gcc/doc/extend.texi                                |   9 ++
+ gcc/doc/invoke.texi                                |  13 +-
+ 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.target/i386/indirect-thunk-attr-1.c        |   2 +-
+ .../gcc.target/i386/indirect-thunk-attr-2.c        |   2 +-
+ .../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        |   2 +-
+ .../gcc.target/i386/indirect-thunk-attr-6.c        |   2 +-
+ .../gcc.target/i386/indirect-thunk-attr-7.c        |   2 +-
+ .../gcc.target/i386/indirect-thunk-attr-8.c        |   2 +-
+ .../gcc.target/i386/indirect-thunk-bnd-1.c         |   2 +-
+ .../gcc.target/i386/indirect-thunk-bnd-2.c         |   2 +-
+ .../gcc.target/i386/indirect-thunk-bnd-3.c         |   2 +-
+ .../gcc.target/i386/indirect-thunk-bnd-4.c         |   2 +-
+ .../gcc.target/i386/indirect-thunk-extern-1.c      |   2 +-
+ .../gcc.target/i386/indirect-thunk-extern-2.c      |   2 +-
+ .../gcc.target/i386/indirect-thunk-extern-3.c      |   2 +-
+ .../gcc.target/i386/indirect-thunk-extern-4.c      |   2 +-
+ .../gcc.target/i386/indirect-thunk-extern-5.c      |   2 +-
+ .../gcc.target/i386/indirect-thunk-extern-6.c      |   2 +-
+ .../gcc.target/i386/indirect-thunk-extern-7.c      |   2 +-
+ .../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-5.c      |   2 +-
+ .../gcc.target/i386/indirect-thunk-inline-6.c      |   2 +-
+ .../gcc.target/i386/indirect-thunk-inline-7.c      |   2 +-
+ gcc/testsuite/gcc.target/i386/ret-thunk-1.c        |  13 ++
+ gcc/testsuite/gcc.target/i386/ret-thunk-10.c       |  23 ++++
+ gcc/testsuite/gcc.target/i386/ret-thunk-11.c       |  23 ++++
+ gcc/testsuite/gcc.target/i386/ret-thunk-12.c       |  22 +++
+ gcc/testsuite/gcc.target/i386/ret-thunk-13.c       |  22 +++
+ gcc/testsuite/gcc.target/i386/ret-thunk-14.c       |  22 +++
+ gcc/testsuite/gcc.target/i386/ret-thunk-15.c       |  22 +++
+ gcc/testsuite/gcc.target/i386/ret-thunk-16.c       |  18 +++
+ gcc/testsuite/gcc.target/i386/ret-thunk-2.c        |  13 ++
+ 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        |  15 ++
+ gcc/testsuite/gcc.target/i386/ret-thunk-6.c        |  14 ++
+ 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        |  25 ++++
+ 56 files changed, 491 insertions(+), 50 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 bcdd9872db9..42eece35766 100644
+--- a/gcc/config/i386/i386-protos.h
++++ b/gcc/config/i386/i386-protos.h
+@@ -314,6 +314,7 @@ extern enum attr_cpu ix86_schedule;
+=20
+ extern const char * ix86_output_call_insn (rtx_insn *insn, 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);
+=20
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index f1c58faa035..4bfe2fa8c1d 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -7188,6 +7188,31 @@ ix86_set_indirect_branch_type (tree fndecl)
+       else
+ 	cfun->machine->indirect_branch_type =3D ix86_indirect_branch;
+     }
++
++  if (cfun->machine->function_return_type =3D=3D indirect_branch_unset)
++    {
++      tree attr =3D lookup_attribute ("function_return",
++				    DECL_ATTRIBUTES (fndecl));
++      if (attr !=3D NULL)
++	{
++	  tree args =3D TREE_VALUE (attr);
++	  if (args =3D=3D NULL)
++	    gcc_unreachable ();
++	  tree cst =3D TREE_VALUE (args);
++	  if (strcmp (TREE_STRING_POINTER (cst), "keep") =3D=3D 0)
++	    cfun->machine->function_return_type =3D indirect_branch_keep;
++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk") =3D=3D 0)
++	    cfun->machine->function_return_type =3D indirect_branch_thunk;
++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") =3D=3D 0)
++	    cfun->machine->function_return_type =3D indirect_branch_thunk_inline;
++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") =3D=3D 0)
++	    cfun->machine->function_return_type =3D indirect_branch_thunk_extern;
++	  else
++	    gcc_unreachable ();
++	}
++      else
++	cfun->machine->function_return_type =3D ix86_function_return;
++    }
+ }
+=20
+ /* Establish appropriate back-end context for processing the function
+@@ -11990,8 +12015,12 @@ static int indirect_thunks_bnd_used;
+ /* Fills in the label name that should be used for the indirect thunk.  */
+=20
+ 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 >=3D 0 && ret_p)
++    gcc_unreachable ();
++
+   if (USE_HIDDEN_LINKONCE)
+     {
+       const char *bnd =3D need_bnd_p ? "_bnd" : "";
+@@ -12006,7 +12035,10 @@ indirect_thunk_name (char name[32], int regno, bo=
ol need_bnd_p)
+ 		   bnd, reg_prefix, reg_names[regno]);
+ 	}
+       else
+-	sprintf (name, "__x86_indirect_thunk%s", bnd);
++	{
++	  const char *ret =3D ret_p ? "return" : "indirect";
++	  sprintf (name, "__x86_%s_thunk%s", ret, bnd);
++	}
+     }
+   else
+     {
+@@ -12019,10 +12051,20 @@ indirect_thunk_name (char name[32], int regno, b=
ool 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);
++	    }
+ 	}
+     }
+ }
+@@ -12117,7 +12159,7 @@ output_indirect_thunk_function (bool need_bnd_p, i=
nt regno)
+   tree decl;
+=20
+   /* 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 =3D build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
+ 		     get_identifier (name),
+ 		     build_function_type_list (void_type_node, NULL_TREE));
+@@ -12160,6 +12202,35 @@ output_indirect_thunk_function (bool need_bnd_p, =
int regno)
+ 	ASM_OUTPUT_LABEL (asm_out_file, name);
+       }
+=20
++  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) =3D make_node (BLOCK);
+   current_function_decl =3D decl;
+   allocate_struct_function (decl, false);
+@@ -28760,7 +28831,7 @@ ix86_output_indirect_branch_via_reg (rtx call_op, =
bool sibcall_p)
+ 	  else
+ 	    indirect_thunks_used |=3D 1 << i;
+ 	}
+-      indirect_thunk_name (thunk_name_buf, regno, need_bnd_p);
++      indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false);
+       thunk_name =3D thunk_name_buf;
+     }
+   else
+@@ -28869,7 +28940,7 @@ ix86_output_indirect_branch_via_push (rtx call_op,=
 const char *xasm,
+ 	  else
+ 	    indirect_thunk_needed =3D true;
+ 	}
+-      indirect_thunk_name (thunk_name_buf, regno, need_bnd_p);
++      indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false);
+       thunk_name =3D thunk_name_buf;
+     }
+   else
+@@ -29004,6 +29075,46 @@ ix86_output_indirect_jmp (rtx call_op, bool ret_p)
+     return "%!jmp\t%A0";
+ }
+=20
++/* Output function return.  CALL_OP is the jump target.  Add a REP
++   prefix to RET if LONG_P is true and function return is kept.  */
++
++const char *
++ix86_output_function_return (bool long_p)
++{
++  if (cfun->machine->function_return_type !=3D indirect_branch_keep)
++    {
++      char thunk_name[32];
++      bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn);
++
++      if (cfun->machine->function_return_type
++	  !=3D indirect_branch_thunk_inline)
++	{
++	  bool need_thunk =3D (cfun->machine->function_return_type
++			     =3D=3D indirect_branch_thunk);
++	  indirect_thunk_name (thunk_name, -1, need_bnd_p, true);
++	  if (need_bnd_p)
++	    {
++	      indirect_thunk_bnd_needed |=3D need_thunk;
++	      fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
++	    }
++	  else
++	    {
++	      indirect_thunk_needed |=3D 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.  */
+=20
+ const char *
+@@ -42075,6 +42186,28 @@ ix86_handle_fndecl_attribute (tree *node, tree na=
me, tree args, int,
+ 	}
+     }
+=20
++  if (is_attribute_p ("function_return", name))
++    {
++      tree cst =3D TREE_VALUE (args);
++      if (TREE_CODE (cst) !=3D STRING_CST)
++	{
++	  warning (OPT_Wattributes,
++		   "%qE attribute requires a string constant argument",
++		   name);
++	  *no_add_attrs =3D true;
++	}
++      else if (strcmp (TREE_STRING_POINTER (cst), "keep") !=3D 0
++	       && strcmp (TREE_STRING_POINTER (cst), "thunk") !=3D 0
++	       && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") !=3D 0
++	       && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") !=3D 0)
++	{
++	  warning (OPT_Wattributes,
++		   "argument to %qE attribute is not "
++		   "(keep|thunk|thunk-inline|thunk-extern)", name);
++	  *no_add_attrs =3D true;
++	}
++    }
++
+   return NULL_TREE;
+ }
+=20
+@@ -46385,6 +46518,8 @@ static const struct attribute_spec ix86_attribute_=
table[] =3D
+     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 },
+=20
+   /* 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 9d2209e605b..45593068905 100644
+--- a/gcc/config/i386/i386.h
++++ b/gcc/config/i386/i386.h
+@@ -2616,6 +2616,9 @@ struct GTY(()) machine_function {
+      "indirect_jump" or "tablejump".  */
+   BOOL_BITFIELD has_local_indirect_jump : 1;
+=20
++  /* 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 cd2e73cf9d3..d112bdb8552 100644
+--- a/gcc/config/i386/i386.md
++++ b/gcc/config/i386/i386.md
+@@ -12315,7 +12315,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")
+@@ -12337,12 +12337,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 c076d9c70ab..b07388d95a9 100644
+--- a/gcc/config/i386/i386.opt
++++ b/gcc/config/i386/i386.opt
+@@ -932,9 +932,13 @@ mindirect-branch=3D
+ Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indire=
ct_branch) Init(indirect_branch_keep)
+ Convert indirect call and jump to call and return thunks.
+=20
++mfunction-return=3D
++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_functi=
on_return) Init(indirect_branch_keep)
++Convert function return to call and return thunk.
++
+ Enum
+ Name(indirect_branch) Type(enum indirect_branch)
+-Known indirect branch choices (for use with the -mindirect-branch=3D opti=
on):
++Known indirect branch choices (for use with the -mindirect-branch=3D/-mfu=
nction-return=3D options):
+=20
+ EnumValue
+ Enum(indirect_branch) String(keep) Value(indirect_branch_keep)
+diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
+index 935381da6fa..46e0a3623a6 100644
+--- a/gcc/doc/extend.texi
++++ b/gcc/doc/extend.texi
+@@ -5550,6 +5550,15 @@ call and jump to call and return thunk.  @samp{thun=
k-inline} converts
+ indirect call and jump to inlined call and return thunk.
+ @samp{thunk-extern} converts indirect call and jump to external call
+ and return thunk provided in a separate object file.
++
++@item function_return("@var{choice}")
++@cindex @code{function_return} function attribute, x86
++On x86 targets, the @code{function_return} attribute causes the compiler
++to convert function return with @var{choice}.  @samp{keep} keeps function
++return unmodified.  @samp{thunk} converts function return to call and
++return thunk.  @samp{thunk-inline} converts function return to inlined
++call and return thunk.  @samp{thunk-extern} converts function return to
++external call and return thunk provided in a separate object file.
+ @end table
+=20
+ On the x86, the inliner does not inline a
+diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
+index 4979c8c939d..f3eb54b1668 100644
+--- a/gcc/doc/invoke.texi
++++ b/gcc/doc/invoke.texi
+@@ -1211,7 +1211,7 @@ See RS/6000 and PowerPC Options.
+ -mavx256-split-unaligned-load  -mavx256-split-unaligned-store @gol
+ -malign-data=3D@var{type}  -mstack-protector-guard=3D@var{guard} @gol
+ -mmitigate-rop  -mgeneral-regs-only @gol
+--mindirect-branch=3D@var{choice}}
++-mindirect-branch=3D@var{choice} -mfunction-return=3D=3D@var{choice}}
+=20
+ @emph{x86 Windows Options}
+ @gccoptlist{-mconsole  -mcygwin  -mno-cygwin  -mdll @gol
+@@ -25698,6 +25698,17 @@ to external call and return thunk provided in a s=
eparate object file.
+ You can control this behavior for a specific function by using the
+ function attribute @code{indirect_branch}.  @xref{Function Attributes}.
+=20
++@item -mfunction-return=3D@var{choice}
++@opindex -mfunction-return
++Convert function return with @var{choice}.  The default is @samp{keep},
++which keeps function return unmodified.  @samp{thunk} converts function
++return to call and return thunk.  @samp{thunk-inline} converts function
++return to inlined call and return thunk.  @samp{thunk-extern} converts
++function return to external call and return thunk provided in a separate
++object file.  You can control this behavior for a specific function by
++using the function attribute @code{function_return}.
++@xref{Function Attributes}.
++
+ @end table
+=20
+ 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/testsu=
ite/gcc.target/i386/indirect-thunk-1.c
+index d983e1c3e26..f076155c91a 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=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-2.c
+index 58f09b42d8a..d7984f592fe 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=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-3.c
+index f20d35c19b6..3257d0a2e16 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=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-4.c
+index 0eff8fb658a..7cab2df6474 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=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-5.c
+index a25b20dd808..b4836c38d6c 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=3Dthunk" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk" } */
+=20
+ extern void bar (void);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-6.c
+index cff114a6c29..1f06bd1af74 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=3Dthunk" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk" } */
+=20
+ extern void bar (void);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-7.c
+index afdb6007986..0b3fef86a20 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=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
+=20
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-1.c
+index d64d978b699..5f6cfc17b56 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=3Dkeep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-2.c
+index 93067454d3d..b256160ec80 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=3Dkeep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-3.c
+index 97744d65729..567c95051d6 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=3Dkeep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-4.c
+index bfce3ea5cb2..3b662af7d5d 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=3Dkeep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-5.c
+index 0833606046b..98785a38248 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=3Dkeep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-6.c
+index 2eba0fbd9b2..a498a39e404 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=3Dkeep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-7.c
+index f58427eae11..66f295d1eb6 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=3Dkeep -fno-pic" } */
+=20
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-8.c
+index 564ed39547c..d730d31bda1 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=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
+=20
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/te=
stsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+index 50fbee20a5a..aacb814d737 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=3Dthunk -fcheck-pointer-bounds -mm=
px -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fno-pic" } */
+=20
+ void (*dispatch) (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/te=
stsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+index 2976e67adce..7b44dda23df 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=3Dthunk -fcheck-pointer-bounds -mm=
px -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fno-pic" } */
+=20
+ void (*dispatch) (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/te=
stsuite/gcc.target/i386/indirect-thunk-bnd-3.c
+index da4bc98ef23..70b4fb36eea 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=3Dthunk -fcheck-pointer-bounds -mm=
px -fpic -fno-plt" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
+=20
+ void bar (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/te=
stsuite/gcc.target/i386/indirect-thunk-bnd-4.c
+index c64d12ef989..3baf03ee77c 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=3Dthunk -fcheck-pointer-bounds -mm=
px -fpic -fno-plt" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
+=20
+ 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 49f27b49465..637fc3d3f4e 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=3Dthunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 a1e3eb6fc74..ff9efe03fe6 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=3Dthunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 395634e7e5c..2686a5f2db4 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=3Dthunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 fd3f63379a1..f07f6b214ad 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=3Dthunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 ba2f92b6f34..21740ac5b7f 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=3Dthunk-extern" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-extern" } */
+=20
+ extern void bar (void);
+=20
+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 0c5a2d472c6..a77c1f470b8 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=3Dthunk-extern" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-extern" } */
+=20
+ extern void bar (void);
+=20
+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 665252327aa..e64910fd4aa 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=3Dthunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
+=20
+ 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 68c0ff713b3..365cf2ee226 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=3Dthunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 e2da1fcb683..72646a4960b 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=3Dthunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 244fec708d6..f48945e3dfc 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=3Dthunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 107ebe32f54..4b1d558fc4e 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=3Dthunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 17b04ef2229..0f687c3b027 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=3Dthunk-inline" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-inline" } */
+=20
+ extern void bar (void);
+=20
+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 d9eb11285aa..b27c6fc96a2 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=3Dthunk-inline" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-inline" } */
+=20
+ extern void bar (void);
+=20
+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 d02b1dcb1b9..2c496492eaa 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=3Dthunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
+=20
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c b/gcc/testsuite/g=
cc.target/i386/ret-thunk-1.c
+new file mode 100644
+index 00000000000..7223f67ba5e
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c
+@@ -0,0 +1,13 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dthunk" } */
++
++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 {\tpause} } } */
++/* { 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..1630e2fa2b5
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
+@@ -0,0 +1,23 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dthunk-inline -mindirect-branch=
=3Dthunk -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 {\tpause} 2 } } */
++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3=
2 } } } } */
++/* { 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..876159cf783
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
+@@ -0,0 +1,23 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dthunk-extern -mindirect-branch=
=3Dthunk -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 {\tpause} 1 } } */
++/* { 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 { ! x3=
2 } } } } */
++/* { 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..01b0a02f80b
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
+@@ -0,0 +1,22 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
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 {\tpause} 1 } } */
++/* { 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..e028c2b6a99
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
+@@ -0,0 +1,22 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i=
nline -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 {\tpause} 2 } } */
++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3=
2 } } } } */
++/* { 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..c14ee3ae4c0
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
+@@ -0,0 +1,22 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
++
++extern void (*bar) (void);
++
++__attribute__ ((function_return("thunk-inline")))
++int
++foo (void)
++{
++  bar ();
++  return 0;
++}
++
++/* { dg-final { scan-assembler-times {\tpause} 1 } } */
++/* { 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 { ! x3=
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-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..2f21e138ec2
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
+@@ -0,0 +1,22 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dkeep -f=
no-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 {\tpause} 1 } } */
++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3=
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-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..a16cad16aaa
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c
+@@ -0,0 +1,18 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dthunk-inline -mindirect-branch=
=3Dthunk-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 {\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/ret-thunk-2.c b/gcc/testsuite/g=
cc.target/i386/ret-thunk-2.c
+new file mode 100644
+index 00000000000..c6659e3ad09
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c
+@@ -0,0 +1,13 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dthunk-inline" } */
++
++void
++foo (void)
++{
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tpause} } } */
++/* { 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/g=
cc.target/i386/ret-thunk-3.c
+new file mode 100644
+index 00000000000..0f7f388f459
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c
+@@ -0,0 +1,12 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dthunk-extern" } */
++
++void
++foo (void)
++{
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_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/ret-thunk-4.c b/gcc/testsuite/g=
cc.target/i386/ret-thunk-4.c
+new file mode 100644
+index 00000000000..9ae37e835a0
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c
+@@ -0,0 +1,12 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep" } */
++
++void
++foo (void)
++{
++}
++
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_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/ret-thunk-5.c b/gcc/testsuite/g=
cc.target/i386/ret-thunk-5.c
+new file mode 100644
+index 00000000000..4bd0d2a27bc
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c
+@@ -0,0 +1,15 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep" } */
++
++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 {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c b/gcc/testsuite/g=
cc.target/i386/ret-thunk-6.c
+new file mode 100644
+index 00000000000..053841f6f7d
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c
+@@ -0,0 +1,14 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep" } */
++
++__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 {\tpause} } } */
++/* { 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/g=
cc.target/i386/ret-thunk-7.c
+new file mode 100644
+index 00000000000..262e6780112
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c
+@@ -0,0 +1,13 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep" } */
++
++__attribute__ ((function_return("thunk-extern")))
++void
++foo (void)
++{
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_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/ret-thunk-8.c b/gcc/testsuite/g=
cc.target/i386/ret-thunk-8.c
+new file mode 100644
+index 00000000000..c1658e96673
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c
+@@ -0,0 +1,14 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dthunk-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 {\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/ret-thunk-9.c b/gcc/testsuite/g=
cc.target/i386/ret-thunk-9.c
+new file mode 100644
+index 00000000000..f6ccad98da7
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
+@@ -0,0 +1,25 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mfunction-return=3Dthunk -mindirect-branch=3Dthunk =
-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 {\tpause} 1 { target { ! x32 } } } }=
 */
++/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } =
} */
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x3=
2 } } } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target=
 { ! x32 } } } } */
++/* { dg-final { scan-assembler-times {\tpause} 2 { 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 } } } =
*/
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch-re=
gister.patch b/gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch-=
register.patch
new file mode 100644
index 000000000..5fbced669
--- /dev/null
+++ b/gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch-register.=
patch
@@ -0,0 +1,907 @@
+'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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-regnames' branch of upstream source repos=
itory
+(please keep an eye for new branches or updates for existing branches):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 139dd2c61a11430263f91030910e2b63a73a11e7 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Sat, 6 Jan 2018 22:29:56 -0800
+Subject: [PATCH 06/10] x86: Add -mindirect-branch-register
+
+Add -mindirect-branch-register to force indirect branch via register.
+This is implemented by disabling patterns of indirect branch via memory,
+similar to TARGET_X32.
+
+-mindirect-branch=3D and -mfunction-return=3D tests are updated with
+-mno-indirect-branch-register to avoid false test failures when
+-mindirect-branch-register is added to RUNTESTFLAGS for "make check".
+
+gcc/
+
+	Backport from mainline
+	* config/i386/constraints.md (Bs): Disallow memory operand for
+	-mindirect-branch-register.
+	(Bw): Likewise.
+	* config/i386/predicates.md (indirect_branch_operand): Likewise.
+	(GOT_memory_operand): Likewise.
+	(call_insn_operand): Likewise.
+	(sibcall_insn_operand): Likewise.
+	(GOT32_symbol_operand): Likewise.
+	* config/i386/i386.md (indirect_jump): Call convert_memory_address
+	for -mindirect-branch-register.
+	(tablejump): Likewise.
+	(*sibcall_memory): Likewise.
+	(*sibcall_value_memory): Likewise.
+	Disallow peepholes of indirect call and jump via memory for
+	-mindirect-branch-register.
+	(*call_pop): Replace m with Bw.
+	(*call_value_pop): Likewise.
+	(*sibcall_pop_memory): Replace m with Bs.
+	* config/i386/i386.opt (mindirect-branch-register): New option.
+	* doc/invoke.texi: Document -mindirect-branch-register option.
+
+gcc/testsuite/
+
+	Backport from mainline
+	* gcc.target/i386/indirect-thunk-1.c (dg-options): Add
+	-mno-indirect-branch-register.
+	* gcc.target/i386/indirect-thunk-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-5.c: Likewise.
+	* gcc.target/i386/indirect-thunk-6.c: Likewise.
+	* gcc.target/i386/indirect-thunk-7.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-1.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-5.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-6.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-7.c: Likewise.
+	* gcc.target/i386/indirect-thunk-bnd-1.c: Likewise.
+	* gcc.target/i386/indirect-thunk-bnd-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-bnd-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-bnd-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-1.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-5.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-6.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-7.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-1.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-5.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-6.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-7.c: Likewise.
+	* gcc.target/i386/ret-thunk-10.c: Likewise.
+	* gcc.target/i386/ret-thunk-11.c: Likewise.
+	* gcc.target/i386/ret-thunk-12.c: Likewise.
+	* gcc.target/i386/ret-thunk-13.c: Likewise.
+	* gcc.target/i386/ret-thunk-14.c: Likewise.
+	* gcc.target/i386/ret-thunk-15.c: Likewise.
+	* gcc.target/i386/ret-thunk-9.c: Likewise.
+	* gcc.target/i386/indirect-thunk-register-1.c: New test.
+	* gcc.target/i386/indirect-thunk-register-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-register-3.c: Likewise.
+---
+ 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/doc/invoke.texi                                |  7 ++++-
+ 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.target/i386/indirect-thunk-attr-1.c        |  2 +-
+ .../gcc.target/i386/indirect-thunk-attr-2.c        |  2 +-
+ .../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        |  2 +-
+ .../gcc.target/i386/indirect-thunk-attr-6.c        |  2 +-
+ .../gcc.target/i386/indirect-thunk-attr-7.c        |  2 +-
+ .../gcc.target/i386/indirect-thunk-bnd-1.c         |  2 +-
+ .../gcc.target/i386/indirect-thunk-bnd-2.c         |  2 +-
+ .../gcc.target/i386/indirect-thunk-bnd-3.c         |  2 +-
+ .../gcc.target/i386/indirect-thunk-bnd-4.c         |  2 +-
+ .../gcc.target/i386/indirect-thunk-extern-1.c      |  2 +-
+ .../gcc.target/i386/indirect-thunk-extern-2.c      |  2 +-
+ .../gcc.target/i386/indirect-thunk-extern-3.c      |  2 +-
+ .../gcc.target/i386/indirect-thunk-extern-4.c      |  2 +-
+ .../gcc.target/i386/indirect-thunk-extern-5.c      |  2 +-
+ .../gcc.target/i386/indirect-thunk-extern-6.c      |  2 +-
+ .../gcc.target/i386/indirect-thunk-extern-7.c      |  2 +-
+ .../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-5.c      |  2 +-
+ .../gcc.target/i386/indirect-thunk-inline-6.c      |  2 +-
+ .../gcc.target/i386/indirect-thunk-inline-7.c      |  2 +-
+ .../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 ++++++++++++
+ 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 +-
+ 47 files changed, 154 insertions(+), 63 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 @@
+=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 =3D=3D DImode")
++       (and (match_test "TARGET_X32 && Pmode =3D=3D DImode
++			 && !ix86_indirect_branch_thunk_register")
+ 	    (match_operand 0 "GOT_memory_operand"))))
+=20
+ (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 =3D=3D DImode")
++       (and (match_test "TARGET_X32 && Pmode =3D=3D DImode
++			 && !ix86_indirect_branch_thunk_register")
+ 	    (match_operand 0 "GOT_memory_operand"))))
+=20
+ (define_constraint "Bz"
+diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
+index d112bdb8552..96941e8c5c4 100644
+--- a/gcc/config/i386/i386.md
++++ b/gcc/config/i386/i386.md
+@@ -11625,7 +11625,7 @@
+   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
+   ""
+ {
+-  if (TARGET_X32)
++  if (TARGET_X32 || ix86_indirect_branch_thunk_register)
+     operands[0] =3D convert_memory_address (word_mode, operands[0]);
+   cfun->machine->has_local_indirect_jump =3D true;
+ })
+@@ -11679,7 +11679,7 @@
+ 					 OPTAB_DIRECT);
+     }
+=20
+-  if (TARGET_X32)
++  if (TARGET_X32 || ix86_indirect_branch_thunk_register)
+     operands[0] =3D convert_memory_address (word_mode, operands[0]);
+   cfun->machine->has_local_indirect_jump =3D true;
+ })
+@@ -11871,7 +11871,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")])
+=20
+@@ -11880,7 +11880,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))
+@@ -11893,7 +11895,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)
+@@ -11915,7 +11919,7 @@
+ })
+=20
+ (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)
+@@ -11935,7 +11939,7 @@
+   [(set_attr "type" "call")])
+=20
+ (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)
+@@ -11989,7 +11993,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))])
+=20
+ ;; Call subroutine, returning value in operand 0
+@@ -12070,7 +12076,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")])
+=20
+@@ -12080,7 +12086,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)
+@@ -12095,7 +12103,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)
+@@ -12120,7 +12130,7 @@
+=20
+ (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 b07388d95a9..852033cbb67 100644
+--- a/gcc/config/i386/i386.opt
++++ b/gcc/config/i386/i386.opt
+@@ -951,3 +951,7 @@ Enum(indirect_branch) String(thunk-inline) Value(indir=
ect_branch_thunk_inline)
+=20
+ EnumValue
+ Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_ex=
tern)
++
++mindirect-branch-register
++Target Report Var(ix86_indirect_branch_thunk_register) Init(0)
++Force indirect call and jump via register.
+diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
+index 2fc2c60f6ac..a88b1d860ca 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"))))
+=20
+ ;; Return true if OP is a memory operands that can be used in sibcalls.
+@@ -664,7 +665,8 @@
+=20
+ ;; 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 =3D XEXP (op, 0);
+   return (GET_CODE (op) =3D=3D CONST
+@@ -678,9 +680,11 @@
+   (ior (match_test "constant_call_address_operand
+ 		     (op, mode =3D=3D 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 =3D=3D DImode")
++	    (and (match_test "TARGET_X32 && Pmode =3D=3D DImode
++			      && !ix86_indirect_branch_thunk_register")
+ 		 (match_operand 0 "GOT_memory_operand")))))
+=20
+ ;; Similarly, but for tail calls, in which we cannot allow memory referen=
ces.
+@@ -688,14 +692,17 @@
+   (ior (match_test "constant_call_address_operand
+ 		     (op, mode =3D=3D 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 =3D=3D DImode")
++	    (and (match_test "TARGET_X32 && Pmode =3D=3D DImode
++			      && !ix86_indirect_branch_thunk_register")
+ 		 (match_operand 0 "GOT_memory_operand")))))
+=20
+ ;; Return true if OP is a 32-bit GOT symbol operand.
+ (define_predicate "GOT32_symbol_operand"
+-  (match_test "GET_CODE (op) =3D=3D CONST
++  (match_test "!ix86_indirect_branch_thunk_register
++	       && GET_CODE (op) =3D=3D CONST
+                && GET_CODE (XEXP (op, 0)) =3D=3D UNSPEC
+                && XINT (XEXP (op, 0), 1) =3D=3D UNSPEC_GOT"))
+=20
+diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
+index f3eb54b1668..1e572b1f9a2 100644
+--- a/gcc/doc/invoke.texi
++++ b/gcc/doc/invoke.texi
+@@ -1211,7 +1211,8 @@ See RS/6000 and PowerPC Options.
+ -mavx256-split-unaligned-load  -mavx256-split-unaligned-store @gol
+ -malign-data=3D@var{type}  -mstack-protector-guard=3D@var{guard} @gol
+ -mmitigate-rop  -mgeneral-regs-only @gol
+--mindirect-branch=3D@var{choice} -mfunction-return=3D=3D@var{choice}}
++-mindirect-branch=3D@var{choice} -mfunction-return=3D=3D@var{choice} @gol
++-mindirect-branch-register}
+=20
+ @emph{x86 Windows Options}
+ @gccoptlist{-mconsole  -mcygwin  -mno-cygwin  -mdll @gol
+@@ -25709,6 +25710,10 @@ object file.  You can control this behavior for a=
 specific function by
+ using the function attribute @code{function_return}.
+ @xref{Function Attributes}.
+=20
++@item -mindirect-branch-register
++@opindex -mindirect-branch-register
++Force indirect call and jump via register.
++
+ @end table
+=20
+ 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/testsu=
ite/gcc.target/i386/indirect-thunk-1.c
+index f076155c91a..9eb9b273ade 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=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-2.c
+index d7984f592fe..c63795e4127 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=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-3.c
+index 3257d0a2e16..82973cda771 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=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mno-indirect-branch-register -mfunction-return=3Dkeep -mindirect-b=
ranch=3Dthunk -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-4.c
+index 7cab2df6474..a5f3d1cbed8 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=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mno-indirect-branch-register -mfunction-return=3Dkeep -mindirect-b=
ranch=3Dthunk -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-5.c
+index b4836c38d6c..fcaa18d10b7 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=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fpic -fno-plt -mindirect-branch=3Dthunk" } */
+=20
+ extern void bar (void);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-6.c
+index 1f06bd1af74..e4649283d10 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=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mno-indirect-branch-register -mfunction-return=3Dkeep -fpic -fno-p=
lt -mindirect-branch=3Dthunk" } */
+=20
+ extern void bar (void);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-7.c
+index 0b3fef86a20..ebfb8aab937 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=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk -fno-pic" } */
+=20
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-1.c
+index 5f6cfc17b56..a08022db8e4 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=3Dkeep -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-2.c
+index b256160ec80..b257c695ad1 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=3Dkeep -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-3.c
+index 567c95051d6..dfb1370d23d 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=3Dkeep -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-4.c
+index 3b662af7d5d..a6e3f6f9f2b 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=3Dkeep -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-5.c
+index 98785a38248..4bb1c5f9220 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=3Dkeep -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-6.c
+index a498a39e404..4e33a638862 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=3Dkeep -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-7.c
+index 66f295d1eb6..427ba3ddbb4 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=3Dkeep -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fno-pic" } */
+=20
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/te=
stsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+index aacb814d737..dc7143414fb 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=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fno-pic" } */
+=20
+ void (*dispatch) (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/te=
stsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+index 7b44dda23df..737c60946f6 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=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fno-pic" } */
+=20
+ void (*dispatch) (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/te=
stsuite/gcc.target/i386/indirect-thunk-bnd-3.c
+index 70b4fb36eea..d34485a0010 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=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" }=
 */
+=20
+ void bar (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/te=
stsuite/gcc.target/i386/indirect-thunk-bnd-4.c
+index 3baf03ee77c..0e19830de4d 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=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -fcheck-pointer-=
bounds -mmpx -fpic -fno-plt" } */
+=20
+ 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 637fc3d3f4e..5c20a35ecec 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=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-extern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 ff9efe03fe6..b2fb6e1bcd2 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=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-extern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 2686a5f2db4..9c84547cd7c 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=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-extern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 f07f6b214ad..457849564bb 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=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-extern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 21740ac5b7f..5c07e02df6a 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=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-extern" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fpic -fno-plt -mindirect-branch=3Dthunk-extern" } */
+=20
+ extern void bar (void);
+=20
+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 a77c1f470b8..3eb440693a0 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=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-extern" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fpic -fno-plt -mindirect-branch=3Dthunk-extern" } */
+=20
+ extern void bar (void);
+=20
+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 e64910fd4aa..d4747ea0764 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=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-extern -fno-pic" } */
+=20
+ 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 365cf2ee226..536abfa74e4 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=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-inline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 72646a4960b..bd2b6246aa1 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=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-inline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 f48945e3dfc..9885eebbcff 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=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-inline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 4b1d558fc4e..7b3983949d2 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=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-inline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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 0f687c3b027..c6d77e10352 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=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-inline" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */
+=20
+ extern void bar (void);
+=20
+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 b27c6fc96a2..6454827b780 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=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-inline" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */
+=20
+ extern void bar (void);
+=20
+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 2c496492eaa..cc592f89aba 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=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-inline -fno-pic" } */
+=20
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/g=
cc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
+new file mode 100644
+index 00000000000..7d396a31953
+--- /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=3Dthunk -mindirect-branch-register=
 -fno-pic" } */
++
++typedef void (*dispatch_t)(long offset);
++
++dispatch_t dispatch;
++
++void
++male_indirect_jump (long offset)
++{
++  dispatch(offset);
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" =
} } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)"=
 } } */
++/* { dg-final { scan-assembler {\tpause} } } */
++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch"  } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk\n" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk_bnd\n" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c b/g=
cc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
+new file mode 100644
+index 00000000000..e7e616bb271
+--- /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=3Dthunk-inline -mindirect-branch-r=
egister -fno-pic" } */
++
++typedef void (*dispatch_t)(long offset);
++
++dispatch_t dispatch;
++
++void
++male_indirect_jump (long offset)
++{
++  dispatch(offset);
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)"=
 } } */
++/* { dg-final { scan-assembler {\tpause} } } */
++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch"  } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c b/g=
cc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
+new file mode 100644
+index 00000000000..5320e923be2
+--- /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=3Dthunk-extern -mindirect-branch-r=
egister -fno-pic" } */
++
++typedef void (*dispatch_t)(long offset);
++
++dispatch_t dispatch;
++
++void
++male_indirect_jump (long offset)
++{
++  dispatch(offset);
++}
++
++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" =
} } */
++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch"  } } */
++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
++/* { dg-final { scan-assembler-not {\t(pause|pause|nop)} } } */
++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/=
gcc.target/i386/ret-thunk-10.c
+index 1630e2fa2b5..b4f9d48065d 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=3Dthunk-inline -mindirect-branch=
=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mfunction-return=3Dthunk-inline -mindirect-branch=3Dthunk -fno-pic=
" } */
+=20
+ extern void (*bar) (void);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/=
gcc.target/i386/ret-thunk-11.c
+index 876159cf783..0312577a043 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=3Dthunk-extern -mindirect-branch=
=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct=
ion-return=3Dthunk-extern -mindirect-branch=3Dthunk -fno-pic" } */
+=20
+ extern void (*bar) (void);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/=
gcc.target/i386/ret-thunk-12.c
+index 01b0a02f80b..fa3181303c9 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=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct=
ion-return=3Dkeep -mindirect-branch=3Dthunk -fno-pic" } */
+=20
+ extern void (*bar) (void);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/=
gcc.target/i386/ret-thunk-13.c
+index e028c2b6a99..7a08e71c76b 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=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-inline -fno-pic" } */
+=20
+ 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 c14ee3ae4c0..dacf0c769fc 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=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-extern -fno-pic" } */
+=20
+ extern void (*bar) (void);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/=
gcc.target/i386/ret-thunk-15.c
+index 2f21e138ec2..cf06a5f35c7 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=3Dkeep -mindirect-branch=3Dkeep -f=
no-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct=
ion-return=3Dkeep -mindirect-branch=3Dkeep -fno-pic" } */
+=20
+ extern void (*bar) (void);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/g=
cc.target/i386/ret-thunk-9.c
+index f6ccad98da7..6da5ab97081 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=3Dthunk -mindirect-branch=3Dthunk =
-fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mfunction-return=3Dthunk -mindirect-branch=3Dthunk -fno-pic" } */
+=20
+ extern void (*bar) (void);
+=20
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch.pa=
tch b/gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch.patch
new file mode 100644
index 000000000..e622601ea
--- /dev/null
+++ b/gnu/packages/patches/gcc-retpoline-x86-Add-mindirect-branch.patch
@@ -0,0 +1,2171 @@
+'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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-regnames' branch of upstream source repos=
itory
+(please keep an eye for new branches or updates for existing branches):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 09f7c546376f7ed6770fc64f24aed77229f95f67 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Sat, 6 Jan 2018 22:29:55 -0800
+Subject: [PATCH 04/10] x86: Add -mindirect-branch=3D
+
+Add -mindirect-branch=3D option to convert indirect call and jump to call
+and return thunks.  The default is 'keep', which keeps indirect call and
+jump unmodified.  'thunk' converts indirect call and jump to call and
+return thunk.  'thunk-inline' converts indirect call and jump to inlined
+call and return thunk.  'thunk-extern' converts indirect call and jump to
+external call and return thunk provided in a separate object file.  You
+can control this behavior for a specific function by using the function
+attribute indirect_branch.
+
+2 kinds of thunks are geneated.  Memory thunk where the function address
+is at the top of the stack:
+
+__x86_indirect_thunk:
+	call L2
+L1:
+	pause
+	lfence
+	jmp L1
+L2:
+	lea 8(%rsp), %rsp|lea 4(%esp), %esp
+	ret
+
+Indirect jmp via memory, "jmp mem", is converted to
+
+	push memory
+	jmp __x86_indirect_thunk
+
+Indirect call via memory, "call mem", is converted to
+
+	jmp L2
+L1:
+	push [mem]
+	jmp __x86_indirect_thunk
+L2:
+	call L1
+
+Register thunk where the function address is in a register, reg:
+
+__x86_indirect_thunk_reg:
+	call	L2
+L1:
+	pause
+	lfence
+	jmp	L1
+L2:
+	movq	%reg, (%rsp)|movl    %reg, (%esp)
+	ret
+
+where reg is one of (r|e)ax, (r|e)dx, (r|e)cx, (r|e)bx, (r|e)si, (r|e)di,
+(r|e)bp, r8, r9, r10, r11, r12, r13, r14 and r15.
+
+Indirect jmp via register, "jmp reg", is converted to
+
+	jmp __x86_indirect_thunk_reg
+
+Indirect call via register, "call reg", is converted to
+
+	call __x86_indirect_thunk_reg
+
+gcc/
+
+	Backport from mainline
+	* config/i386/i386-opts.h (indirect_branch): New.
+	* config/i386/i386-protos.h (ix86_output_indirect_jmp): Likewise.
+	* config/i386/i386.c (ix86_using_red_zone): Disallow red-zone
+	with local indirect jump when converting indirect call and jump.
+	(ix86_set_indirect_branch_type): New.
+	(ix86_set_current_function): Call ix86_set_indirect_branch_type.
+	(indirectlabelno): New.
+	(indirect_thunk_needed): Likewise.
+	(indirect_thunk_bnd_needed): Likewise.
+	(indirect_thunks_used): Likewise.
+	(indirect_thunks_bnd_used): Likewise.
+	(INDIRECT_LABEL): Likewise.
+	(indirect_thunk_name): Likewise.
+	(output_indirect_thunk): Likewise.
+	(output_indirect_thunk_function): Likewise.
+	(ix86_output_indirect_branch): Likewise.
+	(ix86_output_indirect_jmp): Likewise.
+	(ix86_code_end): Call output_indirect_thunk_function if needed.
+	(ix86_output_call_insn): Call ix86_output_indirect_branch if
+	needed.
+	(ix86_handle_fndecl_attribute): Handle indirect_branch.
+	(ix86_attribute_table): Add indirect_branch.
+	* config/i386/i386.h (machine_function): Add indirect_branch_type
+	and has_local_indirect_jump.
+	* config/i386/i386.md (indirect_jump): Set has_local_indirect_jump
+	to true.
+	(tablejump): Likewise.
+	(*indirect_jump): Use ix86_output_indirect_jmp.
+	(*tablejump_1): Likewise.
+	(simple_return_indirect_internal): Likewise.
+	* config/i386/i386.opt (mindirect-branch=3D): New option.
+	(indirect_branch): New.
+	(keep): Likewise.
+	(thunk): Likewise.
+	(thunk-inline): Likewise.
+	(thunk-extern): Likewise.
+	* doc/extend.texi: Document indirect_branch function attribute.
+	* doc/invoke.texi: Document -mindirect-branch=3D option.
+
+gcc/testsuite/
+
+	Backport from mainline
+	* gcc.target/i386/indirect-thunk-1.c: New test.
+	* gcc.target/i386/indirect-thunk-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-5.c: Likewise.
+	* gcc.target/i386/indirect-thunk-6.c: Likewise.
+	* gcc.target/i386/indirect-thunk-7.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-1.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-5.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-6.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-7.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-8.c: Likewise.
+	* gcc.target/i386/indirect-thunk-bnd-1.c: Likewise.
+	* gcc.target/i386/indirect-thunk-bnd-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-bnd-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-bnd-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-1.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-5.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-6.c: Likewise.
+	* gcc.target/i386/indirect-thunk-extern-7.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-1.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-2.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-3.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-4.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-5.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-6.c: Likewise.
+	* gcc.target/i386/indirect-thunk-inline-7.c: Likewise.
+---
+ gcc/config/i386/i386-opts.h                        |  13 +
+ gcc/config/i386/i386-protos.h                      |   1 +
+ gcc/config/i386/i386.c                             | 648 ++++++++++++++++=
++++-
+ gcc/config/i386/i386.h                             |   7 +
+ gcc/config/i386/i386.md                            |  26 +-
+ gcc/config/i386/i386.opt                           |  20 +
+ gcc/doc/extend.texi                                |  10 +
+ gcc/doc/invoke.texi                                |  14 +-
+ gcc/testsuite/gcc.target/i386/indirect-thunk-1.c   |  20 +
+ gcc/testsuite/gcc.target/i386/indirect-thunk-2.c   |  20 +
+ gcc/testsuite/gcc.target/i386/indirect-thunk-3.c   |  21 +
+ gcc/testsuite/gcc.target/i386/indirect-thunk-4.c   |  21 +
+ gcc/testsuite/gcc.target/i386/indirect-thunk-5.c   |  17 +
+ gcc/testsuite/gcc.target/i386/indirect-thunk-6.c   |  18 +
+ gcc/testsuite/gcc.target/i386/indirect-thunk-7.c   |  44 ++
+ .../gcc.target/i386/indirect-thunk-attr-1.c        |  23 +
+ .../gcc.target/i386/indirect-thunk-attr-2.c        |  21 +
+ .../gcc.target/i386/indirect-thunk-attr-3.c        |  23 +
+ .../gcc.target/i386/indirect-thunk-attr-4.c        |  22 +
+ .../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        |  42 ++
+ .../gcc.target/i386/indirect-thunk-bnd-1.c         |  20 +
+ .../gcc.target/i386/indirect-thunk-bnd-2.c         |  21 +
+ .../gcc.target/i386/indirect-thunk-bnd-3.c         |  19 +
+ .../gcc.target/i386/indirect-thunk-bnd-4.c         |  20 +
+ .../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 ++
+ .../gcc.target/i386/indirect-thunk-inline-1.c      |  20 +
+ .../gcc.target/i386/indirect-thunk-inline-2.c      |  20 +
+ .../gcc.target/i386/indirect-thunk-inline-3.c      |  21 +
+ .../gcc.target/i386/indirect-thunk-inline-4.c      |  21 +
+ .../gcc.target/i386/indirect-thunk-inline-5.c      |  17 +
+ .../gcc.target/i386/indirect-thunk-inline-6.c      |  18 +
+ .../gcc.target/i386/indirect-thunk-inline-7.c      |  44 ++
+ 41 files changed, 1494 insertions(+), 19 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
+ 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
+ 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
+ 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
+ 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 542cd0f3d67..efcdc3b1a14 100644
+--- a/gcc/config/i386/i386-opts.h
++++ b/gcc/config/i386/i386-opts.h
+@@ -99,4 +99,17 @@ enum stack_protector_guard {
+   SSP_GLOBAL    /* global canary */
+ };
+=20
++/* This is used to mitigate variant #2 of the speculative execution
++   vulnerabilities on x86 processors identified by CVE-2017-5715, aka
++   Spectre.  They convert indirect branches and function returns to
++   call and return thunks to avoid speculative execution via indirect
++   call, jmp and ret.  */
++enum indirect_branch {
++  indirect_branch_unset =3D 0,
++  indirect_branch_keep,
++  indirect_branch_thunk,
++  indirect_branch_thunk_inline,
++  indirect_branch_thunk_extern
++};
++
+ #endif
+diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
+index d2cccf14735..bcdd9872db9 100644
+--- a/gcc/config/i386/i386-protos.h
++++ b/gcc/config/i386/i386-protos.h
+@@ -313,6 +313,7 @@ extern enum attr_cpu ix86_schedule;
+ #endif
+=20
+ extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op);
++extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p);
+ extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load,
+ 						enum machine_mode mode);
+=20
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index 986e6d79584..f1c58faa035 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -4212,12 +4212,23 @@ make_pass_stv (gcc::context *ctxt)
+   return new pass_stv (ctxt);
+ }
+=20
+-/* 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.
++
++   TODO: If we can reserve the first 2 WORDs, for PUSH and, another
++   for CALL, in red-zone, we can allow local indirect jumps with
++   indirect thunk.  */
+=20
+ 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 =3D=3D indirect_branch_keep=
));
+ }
+ 
+ /* Return a string that documents the current -m options.  The caller is
+@@ -7148,6 +7159,37 @@ ix86_set_func_type (tree fndecl)
+     }
+ }
+=20
++/* 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 =3D=3D indirect_branch_unset)
++    {
++      tree attr =3D lookup_attribute ("indirect_branch",
++				    DECL_ATTRIBUTES (fndecl));
++      if (attr !=3D NULL)
++	{
++	  tree args =3D TREE_VALUE (attr);
++	  if (args =3D=3D NULL)
++	    gcc_unreachable ();
++	  tree cst =3D TREE_VALUE (args);
++	  if (strcmp (TREE_STRING_POINTER (cst), "keep") =3D=3D 0)
++	    cfun->machine->indirect_branch_type =3D indirect_branch_keep;
++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk") =3D=3D 0)
++	    cfun->machine->indirect_branch_type =3D indirect_branch_thunk;
++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") =3D=3D 0)
++	    cfun->machine->indirect_branch_type =3D indirect_branch_thunk_inline;
++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") =3D=3D 0)
++	    cfun->machine->indirect_branch_type =3D indirect_branch_thunk_extern;
++	  else
++	    gcc_unreachable ();
++	}
++      else
++	cfun->machine->indirect_branch_type =3D 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.  */
+@@ -7163,7 +7205,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 !=3D NULL_TREE)
+-	ix86_set_func_type (fndecl);
++	{
++	  ix86_set_func_type (fndecl);
++	  ix86_set_indirect_branch_type (fndecl);
++	}
+       return;
+     }
+=20
+@@ -7183,6 +7228,7 @@ ix86_set_current_function (tree fndecl)
+     }
+=20
+   ix86_set_func_type (fndecl);
++  ix86_set_indirect_branch_type (fndecl);
+=20
+   tree new_tree =3D DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+   if (new_tree =3D=3D NULL_TREE)
+@@ -11920,6 +11966,220 @@ ix86_setup_frame_addresses (void)
+ # endif
+ #endif
+=20
++/* Label count for call and return thunks.  It is used to make unique
++   labels in call and return thunks.  */
++static int indirectlabelno;
++
++/* True if call and return thunk functions are needed.  */
++static bool indirect_thunk_needed =3D false;
++/* True if call and return thunk functions with the BND prefix are
++   needed.  */
++static bool indirect_thunk_bnd_needed =3D false;
++
++/* Bit masks of integer registers, which contain branch target, used
++   by call and return thunks functions.  */
++static int indirect_thunks_used;
++/* Bit masks of integer registers, which contain branch target, used
++   by call and return thunks functions with the BND prefix.  */
++static int indirect_thunks_bnd_used;
++
++#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], int regno, bool need_bnd_p)
++{
++  if (USE_HIDDEN_LINKONCE)
++    {
++      const char *bnd =3D need_bnd_p ? "_bnd" : "";
++      if (regno >=3D 0)
++	{
++	  const char *reg_prefix;
++	  if (LEGACY_INT_REGNO_P (regno))
++	    reg_prefix =3D TARGET_64BIT ? "r" : "e";
++	  else
++	    reg_prefix =3D "";
++	  sprintf (name, "__x86_indirect_thunk%s_%s%s",
++		   bnd, reg_prefix, reg_names[regno]);
++	}
++      else
++	sprintf (name, "__x86_indirect_thunk%s", bnd);
++    }
++  else
++    {
++      if (regno >=3D 0)
++	{
++	  if (need_bnd_p)
++	    ASM_GENERATE_INTERNAL_LABEL (name, "LITBR", regno);
++	  else
++	    ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno);
++	}
++      else
++	{
++	  if (need_bnd_p)
++	    ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);
++	  else
++	    ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);
++	}
++    }
++}
++
++/* Output a call and return thunk for indirect branch.  If BND_P is
++   true, the BND prefix is needed.   If REGNO !=3D -1,  the function
++   address is in REGNO and the call and return thunk looks like:
++
++	call	L2
++   L1:
++	pause
++	jmp	L1
++   L2:
++	mov	%REG, (%sp)
++	ret
++
++   Otherwise, the function address is on the top of stack and the
++   call and return thunk looks like:
++
++	call L2
++  L1:
++	pause
++	jmp L1
++  L2:
++	lea WORD_SIZE(%sp), %sp
++	ret
++ */
++
++static void
++output_indirect_thunk (bool need_bnd_p, int regno)
++{
++  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);
++
++  /* Pause + lfence.  */
++  fprintf (asm_out_file, "\tpause\n\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);
++
++  if (regno >=3D 0)
++    {
++      /* MOV.  */
++      rtx xops[2];
++      xops[0] =3D gen_rtx_MEM (word_mode, stack_pointer_rtx);
++      xops[1] =3D gen_rtx_REG (word_mode, regno);
++      output_asm_insn ("mov\t{%1, %0|%0, %1}", xops);
++    }
++  else
++    {
++      /* LEA.  */
++      rtx xops[2];
++      xops[0] =3D stack_pointer_rtx;
++      xops[1] =3D 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);
++}
++
++/* Output a funtion with a call and return thunk for indirect branch.
++   If BND_P is true, the BND prefix is needed.   If REGNO !=3D -1,  the
++   function address is in REGNO.  Otherwise, the function address is
++   on the top of stack.  */
++
++static void
++output_indirect_thunk_function (bool need_bnd_p, int regno)
++{
++  char name[32];
++  tree decl;
++
++  /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd.  */
++  indirect_thunk_name (name, regno, need_bnd_p);
++  decl =3D build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
++		     get_identifier (name),
++		     build_function_type_list (void_type_node, NULL_TREE));
++  DECL_RESULT (decl) =3D build_decl (BUILTINS_LOCATION, RESULT_DECL,
++				   NULL_TREE, void_type_node);
++  TREE_PUBLIC (decl) =3D 1;
++  TREE_STATIC (decl) =3D 1;
++  DECL_IGNORED_P (decl) =3D 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) =3D 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) =3D make_node (BLOCK);
++  current_function_decl =3D 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 =3D true;
++  first_function_block_is_cold =3D 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, regno);
++
++  final_end_function ();
++  init_insn_lengths ();
++  free_after_compilation (cfun);
++  set_cfun (NULL);
++  current_function_decl =3D NULL;
++}
++
+ static int pic_labels_used;
+=20
+ /* Fills in the label name that should be used for a pc thunk for
+@@ -11946,11 +12206,32 @@ ix86_code_end (void)
+   rtx xops[2];
+   int regno;
+=20
++  if (indirect_thunk_needed)
++    output_indirect_thunk_function (false, -1);
++  if (indirect_thunk_bnd_needed)
++    output_indirect_thunk_function (true, -1);
++
++  for (regno =3D FIRST_REX_INT_REG; regno <=3D LAST_REX_INT_REG; regno++)
++    {
++      int i =3D 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 =3D AX_REG; regno <=3D SP_REG; regno++)
+     {
+       char name[32];
+       tree decl;
+=20
++      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;
+=20
+@@ -28446,12 +28727,292 @@ ix86_nopic_noplt_attribute_p (rtx call_op)
+   return false;
+ }
+=20
++/* Output indirect branch via a call and return thunk.  CALL_OP is a
++   register which contains the branch target.  XASM is the assembly
++   template for CALL_OP.  Branch is a tail call if SIBCALL_P is true.
++   A normal call is converted to:
++
++	call __x86_indirect_thunk_reg
++
++   and a tail call is converted to:
++
++	jmp __x86_indirect_thunk_reg
++ */
++
++static void
++ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
++{
++  char thunk_name_buf[32];
++  char *thunk_name;
++  bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn);
++  int regno =3D REGNO (call_op);
++
++  if (cfun->machine->indirect_branch_type
++      !=3D indirect_branch_thunk_inline)
++    {
++      if (cfun->machine->indirect_branch_type =3D=3D indirect_branch_thun=
k)
++	{
++	  int i =3D regno;
++	  if (i >=3D FIRST_REX_INT_REG)
++	    i -=3D (FIRST_REX_INT_REG - LAST_INT_REG - 1);
++	  if (need_bnd_p)
++	    indirect_thunks_bnd_used |=3D 1 << i;
++	  else
++	    indirect_thunks_used |=3D 1 << i;
++	}
++      indirect_thunk_name (thunk_name_buf, regno, need_bnd_p);
++      thunk_name =3D thunk_name_buf;
++    }
++  else
++    thunk_name =3D NULL;
++
++  if (sibcall_p)
++    {
++      if (thunk_name !=3D 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, regno);
++    }
++  else
++    {
++      if (thunk_name !=3D 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];
++
++      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 (thunk_name !=3D 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, regno);
++
++      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);
++    }
++}
++
++/* Output indirect branch via a call and return thunk.  CALL_OP is
++   the branch target.  XASM is the assembly template for CALL_OP.
++   Branch is a tail call if SIBCALL_P is true.  A normal call is
++   converted to:
++
++	jmp L2
++   L1:
++	push CALL_OP
++	jmp __x86_indirect_thunk
++   L2:
++	call L1
++
++   and a tail call is converted to:
++
++	push CALL_OP
++	jmp __x86_indirect_thunk
++ */
++
++static void
++ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm,
++				      bool sibcall_p)
++{
++  char thunk_name_buf[32];
++  char *thunk_name;
++  char push_buf[64];
++  bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn);
++  int regno =3D -1;
++
++  if (cfun->machine->indirect_branch_type
++      !=3D indirect_branch_thunk_inline)
++    {
++      if (cfun->machine->indirect_branch_type =3D=3D indirect_branch_thun=
k)
++	{
++	  if (need_bnd_p)
++	    indirect_thunk_bnd_needed =3D true;
++	  else
++	    indirect_thunk_needed =3D true;
++	}
++      indirect_thunk_name (thunk_name_buf, regno, need_bnd_p);
++      thunk_name =3D thunk_name_buf;
++    }
++  else
++    thunk_name =3D NULL;
++
++  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 !=3D 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, regno);
++    }
++  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);
++
++      /* An external function may be called via GOT, instead of PLT.  */
++      if (MEM_P (call_op))
++	{
++	  struct ix86_address parts;
++	  rtx addr =3D XEXP (call_op, 0);
++	  if (ix86_decompose_address (addr, &parts)
++	      && parts.base =3D=3D 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 =3D gen_rtx_MULT (Pmode, parts.index,
++				       GEN_INT (parts.scale));
++		  addr =3D gen_rtx_PLUS (Pmode, stack_pointer_rtx,
++				       addr);
++		}
++	      else
++		addr =3D stack_pointer_rtx;
++
++	      rtx disp;
++	      if (parts.disp !=3D NULL_RTX)
++		disp =3D plus_constant (Pmode, parts.disp,
++				      UNITS_PER_WORD);
++	      else
++		disp =3D GEN_INT (UNITS_PER_WORD);
++
++	      addr =3D gen_rtx_PLUS (Pmode, addr, disp);
++	      call_op =3D gen_rtx_MEM (GET_MODE (call_op), addr);
++	    }
++	}
++
++      output_asm_insn (push_buf, &call_op);
++
++      if (thunk_name !=3D 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, regno);
++
++      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);
++    }
++}
++
++/* Output indirect branch via a call and return thunk.  CALL_OP is
++   the branch target.  XASM is the assembly template for CALL_OP.
++   Branch is a tail call if SIBCALL_P is true.   */
++
++static void
++ix86_output_indirect_branch (rtx call_op, const char *xasm,
++			     bool sibcall_p)
++{
++  if (REG_P (call_op))
++    ix86_output_indirect_branch_via_reg (call_op, sibcall_p);
++  else
++    ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p);
++}
++/* Output indirect jump.  CALL_OP is the jump target.  Jump is a
++   function return if RET_P is true.  */
++
++const char *
++ix86_output_indirect_jmp (rtx call_op, bool ret_p)
++{
++  if (cfun->machine->indirect_branch_type !=3D 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 !=3D 0)
++	gcc_unreachable ();
++
++      ix86_output_indirect_branch (call_op, "%0", true);
++      return "";
++    }
++  else
++    return "%!jmp\t%A0";
++}
++
+ /* Output the assembly for a call instruction.  */
+=20
+ const char *
+ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
+ {
+   bool direct_p =3D constant_call_address_operand (call_op, VOIDmode);
++  bool output_indirect_p
++    =3D (!TARGET_SEH
++       && cfun->machine->indirect_branch_type !=3D indirect_branch_keep);
+   bool seh_nop_p =3D false;
+   const char *xasm;
+=20
+@@ -28461,10 +29022,21 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_=
op)
+ 	{
+ 	  if (ix86_nopic_noplt_attribute_p (call_op))
+ 	    {
++	      direct_p =3D false;
+ 	      if (TARGET_64BIT)
+-		xasm =3D "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
++		{
++		  if (output_indirect_p)
++		    xasm =3D "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
++		  else
++		    xasm =3D "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]=
]}";
++		}
+ 	      else
+-		xasm =3D "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
++		{
++		  if (output_indirect_p)
++		    xasm =3D "{%p0@GOT|[DWORD PTR %p0@GOT]}";
++		  else
++		    xasm =3D "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
++		}
+ 	    }
+ 	  else
+ 	    xasm =3D "%!jmp\t%P0";
+@@ -28474,9 +29046,17 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_o=
p)
+       else if (TARGET_SEH)
+ 	xasm =3D "%!rex.W jmp\t%A0";
+       else
+-	xasm =3D "%!jmp\t%A0";
++	{
++	  if (output_indirect_p)
++	    xasm =3D "%0";
++	  else
++	    xasm =3D "%!jmp\t%A0";
++	}
+=20
+-      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 "";
+     }
+=20
+@@ -28514,18 +29094,37 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_=
op)
+     {
+       if (ix86_nopic_noplt_attribute_p (call_op))
+ 	{
++	  direct_p =3D false;
+ 	  if (TARGET_64BIT)
+-	    xasm =3D "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]=
]}";
++	    {
++	      if (output_indirect_p)
++		xasm =3D "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
++	      else
++		xasm =3D "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
++	    }
+ 	  else
+-	    xasm =3D "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
++	    {
++	      if (output_indirect_p)
++		xasm =3D "{%p0@GOT|[DWORD PTR %p0@GOT]}";
++	      else
++		xasm =3D "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
++	    }
+ 	}
+       else
+ 	xasm =3D "%!call\t%P0";
+     }
+   else
+-    xasm =3D "%!call\t%A0";
++    {
++      if (output_indirect_p)
++	xasm =3D "%0";
++      else
++	xasm =3D "%!call\t%A0";
++    }
+=20
+-  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);
+=20
+   if (seh_nop_p)
+     return "nop";
+@@ -41444,7 +42043,7 @@ ix86_handle_struct_attribute (tree *node, tree nam=
e, tree, int,
+ }
+=20
+ 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) !=3D FUNCTION_DECL)
+@@ -41453,6 +42052,29 @@ ix86_handle_fndecl_attribute (tree *node, tree na=
me, tree, int,
+                name);
+       *no_add_attrs =3D true;
+     }
++
++  if (is_attribute_p ("indirect_branch", name))
++    {
++      tree cst =3D TREE_VALUE (args);
++      if (TREE_CODE (cst) !=3D STRING_CST)
++	{
++	  warning (OPT_Wattributes,
++		   "%qE attribute requires a string constant argument",
++		   name);
++	  *no_add_attrs =3D true;
++	}
++      else if (strcmp (TREE_STRING_POINTER (cst), "keep") !=3D 0
++	       && strcmp (TREE_STRING_POINTER (cst), "thunk") !=3D 0
++	       && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") !=3D 0
++	       && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") !=3D 0)
++	{
++	  warning (OPT_Wattributes,
++		   "argument to %qE attribute is not "
++		   "(keep|thunk|thunk-inline|thunk-extern)", name);
++	  *no_add_attrs =3D true;
++	}
++    }
++
+   return NULL_TREE;
+ }
+=20
+@@ -45761,6 +46383,8 @@ static const struct attribute_spec ix86_attribute_=
table[] =3D
+     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 },
+=20
+   /* 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 f9b91286a01..9d2209e605b 100644
+--- a/gcc/config/i386/i386.h
++++ b/gcc/config/i386/i386.h
+@@ -2609,6 +2609,13 @@ struct GTY(()) machine_function {
+   /* Function type.  */
+   ENUM_BITFIELD(function_type) func_type : 2;
+=20
++  /* 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;
++
+   /* 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 dbe88f40c8f..cd2e73cf9d3 100644
+--- a/gcc/config/i386/i386.md
++++ b/gcc/config/i386/i386.md
+@@ -11627,13 +11627,18 @@
+ {
+   if (TARGET_X32)
+     operands[0] =3D convert_memory_address (word_mode, operands[0]);
++  cfun->machine->has_local_indirect_jump =3D true;
+ })
+=20
+ (define_insn "*indirect_jump"
+   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
+   ""
+-  "%!jmp\t%A0"
+-  [(set_attr "type" "ibr")
++  "* return ix86_output_indirect_jmp (operands[0], false);"
++  [(set (attr "type")
++     (if_then_else (match_test "(cfun->machine->indirect_branch_type
++				 !=3D indirect_branch_keep)")
++	(const_string "multi")
++	(const_string "ibr")))
+    (set_attr "length_immediate" "0")
+    (set_attr "maybe_prefix_bnd" "1")])
+=20
+@@ -11676,14 +11681,19 @@
+=20
+   if (TARGET_X32)
+     operands[0] =3D convert_memory_address (word_mode, operands[0]);
++  cfun->machine->has_local_indirect_jump =3D true;
+ })
+=20
+ (define_insn "*tablejump_1"
+   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
+    (use (label_ref (match_operand 1)))]
+   ""
+-  "%!jmp\t%A0"
+-  [(set_attr "type" "ibr")
++  "* return ix86_output_indirect_jmp (operands[0], false);"
++  [(set (attr "type")
++     (if_then_else (match_test "(cfun->machine->indirect_branch_type
++				 !=3D indirect_branch_keep)")
++	(const_string "multi")
++	(const_string "ibr")))
+    (set_attr "length_immediate" "0")
+    (set_attr "maybe_prefix_bnd" "1")])
+ 
+@@ -12354,8 +12364,12 @@
+   [(simple_return)
+    (use (match_operand:SI 0 "register_operand" "r"))]
+   "reload_completed"
+-  "%!jmp\t%A0"
+-  [(set_attr "type" "ibr")
++  "* return ix86_output_indirect_jmp (operands[0], true);"
++  [(set (attr "type")
++     (if_then_else (match_test "(cfun->machine->indirect_branch_type
++				 !=3D indirect_branch_keep)")
++	(const_string "multi")
++	(const_string "ibr")))
+    (set_attr "length_immediate" "0")
+    (set_attr "maybe_prefix_bnd" "1")])
+=20
+diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
+index 9384e29b1de..c076d9c70ab 100644
+--- a/gcc/config/i386/i386.opt
++++ b/gcc/config/i386/i386.opt
+@@ -927,3 +927,23 @@ Attempt to avoid generating instruction sequences con=
taining ret bytes.
+ mgeneral-regs-only
+ Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flag=
s) Save
+ Generate code which uses only the general registers.
++
++mindirect-branch=3D
++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indire=
ct_branch) Init(indirect_branch_keep)
++Convert indirect call and jump to call and return thunks.
++
++Enum
++Name(indirect_branch) Type(enum indirect_branch)
++Known indirect branch choices (for use with the -mindirect-branch=3D opti=
on):
++
++EnumValue
++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_in=
line)
++
++EnumValue
++Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_ex=
tern)
+diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
+index ba309d01a9b..935381da6fa 100644
+--- a/gcc/doc/extend.texi
++++ b/gcc/doc/extend.texi
+@@ -5540,6 +5540,16 @@ Specify which floating-point unit to use.  You must=
 specify the
+ @code{target("fpmath=3Dsse,387")} option as
+ @code{target("fpmath=3Dsse+387")} because the comma would separate
+ different options.
++
++@item indirect_branch("@var{choice}")
++@cindex @code{indirect_branch} function attribute, x86
++On x86 targets, the @code{indirect_branch} attribute causes the compiler
++to convert indirect call and jump with @var{choice}.  @samp{keep}
++keeps indirect call and jump unmodified.  @samp{thunk} converts indirect
++call and jump to call and return thunk.  @samp{thunk-inline} converts
++indirect call and jump to inlined call and return thunk.
++@samp{thunk-extern} converts indirect call and jump to external call
++and return thunk provided in a separate object file.
+ @end table
+=20
+ On the x86, the inliner does not inline a
+diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
+index 7311c10a754..4979c8c939d 100644
+--- a/gcc/doc/invoke.texi
++++ b/gcc/doc/invoke.texi
+@@ -1210,7 +1210,8 @@ See RS/6000 and PowerPC Options.
+ -msse2avx  -mfentry  -mrecord-mcount  -mnop-mcount  -m8bit-idiv @gol
+ -mavx256-split-unaligned-load  -mavx256-split-unaligned-store @gol
+ -malign-data=3D@var{type}  -mstack-protector-guard=3D@var{guard} @gol
+--mmitigate-rop  -mgeneral-regs-only}
++-mmitigate-rop  -mgeneral-regs-only @gol
++-mindirect-branch=3D@var{choice}}
+=20
+ @emph{x86 Windows Options}
+ @gccoptlist{-mconsole  -mcygwin  -mno-cygwin  -mdll @gol
+@@ -25686,6 +25687,17 @@ Generate code that uses only the general-purpose =
registers.  This
+ prevents the compiler from using floating-point, vector, mask and bound
+ registers.
+=20
++@item -mindirect-branch=3D@var{choice}
++@opindex -mindirect-branch
++Convert indirect call and jump with @var{choice}.  The default is
++@samp{keep}, which keeps indirect call and jump unmodified.
++@samp{thunk} converts indirect call and jump to call and return thunk.
++@samp{thunk-inline} converts indirect call and jump to inlined call
++and return thunk.  @samp{thunk-extern} converts indirect call and jump
++to external call and return thunk provided in a separate object file.
++You can control this behavior for a specific function by using the
++function attribute @code{indirect_branch}.  @xref{Function Attributes}.
++
+ @end table
+=20
+ 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/testsu=
ite/gcc.target/i386/indirect-thunk-1.c
+new file mode 100644
+index 00000000000..d983e1c3e26
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+@@ -0,0 +1,20 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk -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} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-2.c
+new file mode 100644
+index 00000000000..58f09b42d8a
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+@@ -0,0 +1,20 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk -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 {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-3.c
+new file mode 100644
+index 00000000000..f20d35c19b6
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+@@ -0,0 +1,21 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk -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 "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 {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-4.c
+new file mode 100644
+index 00000000000..0eff8fb658a
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+@@ -0,0 +1,21 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk -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 "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 {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-5.c
+new file mode 100644
+index 00000000000..a25b20dd808
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target *-*-linux* } } */
++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=3Dthunk" } */
++
++extern void bar (void);
++
++void
++foo (void)
++{
++  bar ();
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { 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 {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-6.c
+new file mode 100644
+index 00000000000..cff114a6c29
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
+@@ -0,0 +1,18 @@
++/* { dg-do compile { target *-*-linux* } } */
++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=3Dthunk" } */
++
++extern void bar (void);
++
++int
++foo (void)
++{
++  bar ();
++  return 0;
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { 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 {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-7.c
+new file mode 100644
+index 00000000000..afdb6007986
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+@@ -0,0 +1,44 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk -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\]+\\(,%" { ta=
rget { ! 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} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-1.c
+new file mode 100644
+index 00000000000..d64d978b699
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+@@ -0,0 +1,23 @@
++/* { 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 "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} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-2.c
+new file mode 100644
+index 00000000000..93067454d3d
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.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")))
++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 {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-3.c
+new file mode 100644
+index 00000000000..97744d65729
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+@@ -0,0 +1,23 @@
++/* { 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-times "jmp\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
++/* { 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/t=
estsuite/gcc.target/i386/indirect-thunk-attr-4.c
+new file mode 100644
+index 00000000000..bfce3ea5cb2
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+@@ -0,0 +1,22 @@
++/* { 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-times "jmp\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
++/* { 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/t=
estsuite/gcc.target/i386/indirect-thunk-attr-5.c
+new file mode 100644
+index 00000000000..0833606046b
+--- /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-times "jmp\[ \t\]*\.LIND" 1 { target { ! x=
32 } } } } */
++/* { 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/t=
estsuite/gcc.target/i386/indirect-thunk-attr-6.c
+new file mode 100644
+index 00000000000..2eba0fbd9b2
+--- /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-times "jmp\[ \t\]*\.LIND" 1 { target { ! x=
32 } } } } */
++/* { 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/t=
estsuite/gcc.target/i386/indirect-thunk-attr-7.c
+new file mode 100644
+index 00000000000..f58427eae11
+--- /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\]+\\(,%" { ta=
rget { ! 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" } } */
++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-8.c
+new file mode 100644
+index 00000000000..564ed39547c
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
+@@ -0,0 +1,42 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk -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 {\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-bnd-1.c b/gcc/te=
stsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+new file mode 100644
+index 00000000000..50fbee20a5a
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { ! x32 } } } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mm=
px -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 {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/te=
stsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+new file mode 100644
+index 00000000000..2976e67adce
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+@@ -0,0 +1,21 @@
++/* { dg-do compile { target { ! x32 } } } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mm=
px -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 {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/te=
stsuite/gcc.target/i386/indirect-thunk-bnd-3.c
+new file mode 100644
+index 00000000000..da4bc98ef23
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mm=
px -fpic -fno-plt" } */
++
++void bar (char *);
++char buf[10];
++
++void
++foo (void)
++{
++  bar (buf);
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { 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 {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/te=
stsuite/gcc.target/i386/indirect-thunk-bnd-4.c
+new file mode 100644
+index 00000000000..c64d12ef989
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mm=
px -fpic -fno-plt" } */
++
++void bar (char *);
++char buf[10];
++
++int
++foo (void)
++{
++  bar (buf);
++  return 0;
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { 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 {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
+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..49f27b49465
+--- /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=3Dthunk-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 "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
+new file mode 100644
+index 00000000000..a1e3eb6fc74
+--- /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=3Dthunk-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 "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
+new file mode 100644
+index 00000000000..395634e7e5c
+--- /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=3Dthunk-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 "jmp\[ \t\]*__x86_indirect_thunk" { target=
 { ! x32 } } } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x=
32 } } } } */
++/* { 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
+new file mode 100644
+index 00000000000..fd3f63379a1
+--- /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=3Dthunk-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 "jmp\[ \t\]*__x86_indirect_thunk" { target=
 { ! x32 } } } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x=
32 } } } } */
++/* { 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-5.c b/gcc=
/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
+new file mode 100644
+index 00000000000..ba2f92b6f34
+--- /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=3Dthunk-extern" } */
++
++extern void bar (void);
++
++void
++foo (void)
++{
++  bar ();
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { 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..0c5a2d472c6
+--- /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=3Dthunk-extern" } */
++
++extern void bar (void);
++
++int
++foo (void)
++{
++  bar ();
++  return 0;
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { 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..665252327aa
+--- /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=3Dthunk-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\]+\\(,%" { ta=
rget { ! 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
+new file mode 100644
+index 00000000000..68c0ff713b3
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+@@ -0,0 +1,20 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk-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 "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
++/* { 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
+new file mode 100644
+index 00000000000..e2da1fcb683
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+@@ -0,0 +1,20 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk-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 "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
++/* { 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
+new file mode 100644
+index 00000000000..244fec708d6
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+@@ -0,0 +1,21 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk-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-times "jmp\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times {\tpause} 1 } } */
++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
++/* { 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
+new file mode 100644
+index 00000000000..107ebe32f54
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+@@ -0,0 +1,21 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk-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-times "jmp\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times {\tpause} 1 } } */
++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
++/* { 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
+new file mode 100644
+index 00000000000..17b04ef2229
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target *-*-linux* } } */
++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */
++
++extern void bar (void);
++
++void
++foo (void)
++{
++  bar ();
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
++/* { dg-final { scan-assembler {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
++/* { 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..d9eb11285aa
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
+@@ -0,0 +1,18 @@
++/* { dg-do compile { target *-*-linux* } } */
++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */
++
++extern void bar (void);
++
++int
++foo (void)
++{
++  bar ();
++  return 0;
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
++/* { dg-final { scan-assembler-times {\tpause} 1 } } */
++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
++/* { 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..d02b1dcb1b9
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+@@ -0,0 +1,44 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk-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\]+\\(,%" { ta=
rget { ! 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 {\tpause} } } */
++/* { dg-final { scan-assembler {\tlfence} } } */
++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-x86-Disallow-mindirect-bran=
ch-mfunction-return-with-.patch b/gnu/packages/patches/gcc-retpoline-x86-Di=
sallow-mindirect-branch-mfunction-return-with-.patch
new file mode 100644
index 000000000..1dae0b493
--- /dev/null
+++ b/gnu/packages/patches/gcc-retpoline-x86-Disallow-mindirect-branch-mfun=
ction-return-with-.patch
@@ -0,0 +1,308 @@
+'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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-regnames' branch of upstream source repos=
itory
+(please keep an eye for new branches or updates for existing branches):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 13dce7cceef28026c4fc2e505d724526141fe4c1 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Sat, 13 Jan 2018 18:01:54 -0800
+Subject: [PATCH 08/10] x86: Disallow -mindirect-branch=3D/-mfunction-retur=
n=3D
+ with -mcmodel=3Dlarge
+
+Since the thunk function may not be reachable in large code model,
+-mcmodel=3Dlarge is incompatible with -mindirect-branch=3Dthunk,
+-mindirect-branch=3Dthunk-extern, -mfunction-return=3Dthunk and
+-mfunction-return=3Dthunk-extern.  Issue an error when they are used with
+-mcmodel=3Dlarge.
+
+gcc/
+
+	Backport from mainline
+	* config/i386/i386.c (ix86_set_indirect_branch_type): Disallow
+	-mcmodel=3Dlarge with -mindirect-branch=3Dthunk,
+	-mindirect-branch=3Dthunk-extern, -mfunction-return=3Dthunk and
+	-mfunction-return=3Dthunk-extern.
+	* doc/invoke.texi: Document -mcmodel=3Dlarge is incompatible with
+	-mindirect-branch=3Dthunk, -mindirect-branch=3Dthunk-extern,
+	-mfunction-return=3Dthunk and -mfunction-return=3Dthunk-extern.
+
+gcc/testsuite/
+
+	Backport from mainline
+	* gcc.target/i386/indirect-thunk-10.c: New test.
+	* gcc.target/i386/indirect-thunk-8.c: Likewise.
+	* gcc.target/i386/indirect-thunk-9.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-10.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-11.c: Likewise.
+	* gcc.target/i386/indirect-thunk-attr-9.c: Likewise.
+	* gcc.target/i386/ret-thunk-17.c: Likewise.
+	* gcc.target/i386/ret-thunk-18.c: Likewise.
+	* gcc.target/i386/ret-thunk-19.c: Likewise.
+	* gcc.target/i386/ret-thunk-20.c: Likewise.
+	* gcc.target/i386/ret-thunk-21.c: Likewise.
+---
+ gcc/config/i386/i386.c                             | 26 +++++++++++++++++=
+++++
+ gcc/doc/invoke.texi                                | 11 +++++++++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-10.c  |  7 ++++++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-8.c   |  7 ++++++
+ gcc/testsuite/gcc.target/i386/indirect-thunk-9.c   |  7 ++++++
+ .../gcc.target/i386/indirect-thunk-attr-10.c       |  9 ++++++++
+ .../gcc.target/i386/indirect-thunk-attr-11.c       |  9 ++++++++
+ .../gcc.target/i386/indirect-thunk-attr-9.c        |  9 ++++++++
+ gcc/testsuite/gcc.target/i386/ret-thunk-17.c       |  7 ++++++
+ gcc/testsuite/gcc.target/i386/ret-thunk-18.c       |  8 +++++++
+ gcc/testsuite/gcc.target/i386/ret-thunk-19.c       |  8 +++++++
+ gcc/testsuite/gcc.target/i386/ret-thunk-20.c       |  9 ++++++++
+ gcc/testsuite/gcc.target/i386/ret-thunk-21.c       |  9 ++++++++
+ 13 files changed, 126 insertions(+)
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-10.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-8.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-9.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-17.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-18.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-19.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-20.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-21.c
+
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index e32de13688a..318a71840c9 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -7187,6 +7187,19 @@ ix86_set_indirect_branch_type (tree fndecl)
+ 	}
+       else
+ 	cfun->machine->indirect_branch_type =3D ix86_indirect_branch;
++
++      /* -mcmodel=3Dlarge is not compatible with -mindirect-branch=3Dthunk
++	 nor -mindirect-branch=3Dthunk-extern.  */
++      if ((ix86_cmodel =3D=3D CM_LARGE || ix86_cmodel =3D=3D CM_LARGE_PIC)
++	  && ((cfun->machine->indirect_branch_type
++	       =3D=3D indirect_branch_thunk_extern)
++	      || (cfun->machine->indirect_branch_type
++		  =3D=3D indirect_branch_thunk)))
++	error ("%<-mindirect-branch=3D%s%> and %<-mcmodel=3Dlarge%> are not "
++	       "compatible",
++	       ((cfun->machine->indirect_branch_type
++		 =3D=3D indirect_branch_thunk_extern)
++		? "thunk-extern" : "thunk"));
+     }
+=20
+   if (cfun->machine->function_return_type =3D=3D indirect_branch_unset)
+@@ -7212,6 +7225,19 @@ ix86_set_indirect_branch_type (tree fndecl)
+ 	}
+       else
+ 	cfun->machine->function_return_type =3D ix86_function_return;
++
++      /* -mcmodel=3Dlarge is not compatible with -mfunction-return=3Dthunk
++	 nor -mfunction-return=3Dthunk-extern.  */
++      if ((ix86_cmodel =3D=3D CM_LARGE || ix86_cmodel =3D=3D CM_LARGE_PIC)
++	  && ((cfun->machine->function_return_type
++	       =3D=3D indirect_branch_thunk_extern)
++	      || (cfun->machine->function_return_type
++		  =3D=3D indirect_branch_thunk)))
++	error ("%<-mfunction-return=3D%s%> and %<-mcmodel=3Dlarge%> are not "
++	       "compatible",
++	       ((cfun->machine->function_return_type
++		 =3D=3D indirect_branch_thunk_extern)
++		? "thunk-extern" : "thunk"));
+     }
+ }
+=20
+diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
+index 1e572b1f9a2..6f3c344476c 100644
+--- a/gcc/doc/invoke.texi
++++ b/gcc/doc/invoke.texi
+@@ -25699,6 +25699,11 @@ to external call and return thunk provided in a s=
eparate object file.
+ You can control this behavior for a specific function by using the
+ function attribute @code{indirect_branch}.  @xref{Function Attributes}.
+=20
++Note that @option{-mcmodel=3Dlarge} is incompatible with
++@option{-mindirect-branch=3Dthunk} nor
++@option{-mindirect-branch=3Dthunk-extern} since the thunk function may
++not be reachable in large code model.
++
+ @item -mfunction-return=3D@var{choice}
+ @opindex -mfunction-return
+ Convert function return with @var{choice}.  The default is @samp{keep},
+@@ -25710,6 +25715,12 @@ object file.  You can control this behavior for a=
 specific function by
+ using the function attribute @code{function_return}.
+ @xref{Function Attributes}.
+=20
++Note that @option{-mcmodel=3Dlarge} is incompatible with
++@option{-mfunction-return=3Dthunk} nor
++@option{-mfunction-return=3Dthunk-extern} since the thunk function may
++not be reachable in large code model.
++
++
+ @item -mindirect-branch-register
+ @opindex -mindirect-branch-register
+ Force indirect call and jump via register.
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c b/gcc/tests=
uite/gcc.target/i386/indirect-thunk-10.c
+new file mode 100644
+index 00000000000..a0674bd2363
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c
+@@ -0,0 +1,7 @@
++/* { dg-do compile { target { lp64 } } } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk-inline -mfunction-return=
=3Dkeep -mcmodel=3Dlarge" } */
++
++void
++bar (void)
++{
++}
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-8.c
+new file mode 100644
+index 00000000000..7a80a8986e8
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c
+@@ -0,0 +1,7 @@
++/* { dg-do compile { target { lp64 } } } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk -mfunction-return=3Dkeep -=
mcmodel=3Dlarge" } */
++
++void
++bar (void)
++{ /* { dg-error "'-mindirect-branch=3Dthunk' and '-mcmodel=3Dlarge' are n=
ot compatible" } */
++}
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c b/gcc/testsu=
ite/gcc.target/i386/indirect-thunk-9.c
+new file mode 100644
+index 00000000000..d4d45c5114d
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c
+@@ -0,0 +1,7 @@
++/* { dg-do compile { target { lp64 } } } */
++/* { dg-options "-O2 -mindirect-branch=3Dthunk-extern -mfunction-return=
=3Dkeep -mcmodel=3Dlarge" } */
++
++void
++bar (void)
++{ /* { dg-error "'-mindirect-branch=3Dthunk-extern' and '-mcmodel=3Dlarge=
' are not compatible" } */
++}
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c b/gcc/=
testsuite/gcc.target/i386/indirect-thunk-attr-10.c
+new file mode 100644
+index 00000000000..3a2aeaddbc5
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c
+@@ -0,0 +1,9 @@
++/* { dg-do compile { target { lp64 } } } */
++/* { dg-options "-O2 -mindirect-branch=3Dkeep -mfunction-return=3Dkeep -m=
cmodel=3Dlarge" } */
++/* { dg-additional-options "-fPIC" { target fpic } } */
++
++__attribute__ ((indirect_branch("thunk-extern")))
++void
++bar (void)
++{ /* { dg-error "'-mindirect-branch=3Dthunk-extern' and '-mcmodel=3Dlarge=
' are not compatible" } */
++}
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c b/gcc/=
testsuite/gcc.target/i386/indirect-thunk-attr-11.c
+new file mode 100644
+index 00000000000..8e52f032b6c
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c
+@@ -0,0 +1,9 @@
++/* { dg-do compile { target { lp64 } } } */
++/* { dg-options "-O2 -mindirect-branch=3Dkeep -mfunction-return=3Dkeep -m=
cmodel=3Dlarge" } */
++/* { dg-additional-options "-fPIC" { target fpic } } */
++
++__attribute__ ((indirect_branch("thunk-inline")))
++void
++bar (void)
++{
++}
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c b/gcc/t=
estsuite/gcc.target/i386/indirect-thunk-attr-9.c
+new file mode 100644
+index 00000000000..bdaa4f6911b
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c
+@@ -0,0 +1,9 @@
++/* { dg-do compile { target { lp64 } } } */
++/* { dg-options "-O2 -mindirect-branch=3Dkeep -mfunction-return=3Dkeep -m=
cmodel=3Dlarge" } */
++/* { dg-additional-options "-fPIC" { target fpic } } */
++
++__attribute__ ((indirect_branch("thunk")))
++void
++bar (void)
++{ /* { dg-error "'-mindirect-branch=3Dthunk' and '-mcmodel=3Dlarge' are n=
ot compatible" } */
++}
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-17.c b/gcc/testsuite/=
gcc.target/i386/ret-thunk-17.c
+new file mode 100644
+index 00000000000..0605e2c6542
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-17.c
+@@ -0,0 +1,7 @@
++/* { dg-do compile { target { lp64 } } } */
++/* { dg-options "-O2 -mfunction-return=3Dthunk -mindirect-branch=3Dkeep -=
mcmodel=3Dlarge" } */
++
++void
++bar (void)
++{ /* { dg-error "'-mfunction-return=3Dthunk' and '-mcmodel=3Dlarge' are n=
ot compatible" } */
++}
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-18.c b/gcc/testsuite/=
gcc.target/i386/ret-thunk-18.c
+new file mode 100644
+index 00000000000..307019dc242
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-18.c
+@@ -0,0 +1,8 @@
++/* { dg-do compile { target { lp64 } } } */
++/* { dg-options "-O2 -mfunction-return=3Dthunk-extern -mindirect-branch=
=3Dkeep -mcmodel=3Dlarge" } */
++/* { dg-additional-options "-fPIC" { target fpic } } */
++
++void
++bar (void)
++{ /* { dg-error "'-mfunction-return=3Dthunk-extern' and '-mcmodel=3Dlarge=
' are not compatible" } */
++}
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-19.c b/gcc/testsuite/=
gcc.target/i386/ret-thunk-19.c
+new file mode 100644
+index 00000000000..772617f4010
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-19.c
+@@ -0,0 +1,8 @@
++/* { dg-do compile { target { lp64 } } } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dkeep -m=
cmodel=3Dlarge" } */
++
++__attribute__ ((function_return("thunk")))
++void
++bar (void)
++{ /* { dg-error "'-mfunction-return=3Dthunk' and '-mcmodel=3Dlarge' are n=
ot compatible" } */
++}
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-20.c b/gcc/testsuite/=
gcc.target/i386/ret-thunk-20.c
+new file mode 100644
+index 00000000000..1e9f9bd5a66
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-20.c
+@@ -0,0 +1,9 @@
++/* { dg-do compile { target { lp64 } } } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dkeep -m=
cmodel=3Dlarge" } */
++/* { dg-additional-options "-fPIC" { target fpic } } */
++
++__attribute__ ((function_return("thunk-extern")))
++void
++bar (void)
++{ /* { dg-error "'-mfunction-return=3Dthunk-extern' and '-mcmodel=3Dlarge=
' are not compatible" } */
++}
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-21.c b/gcc/testsuite/=
gcc.target/i386/ret-thunk-21.c
+new file mode 100644
+index 00000000000..eea07f7abe1
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-21.c
+@@ -0,0 +1,9 @@
++/* { dg-do compile { target { lp64 } } } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dkeep -m=
cmodel=3Dlarge" } */
++/* { dg-additional-options "-fPIC" { target fpic } } */
++
++__attribute__ ((function_return("thunk-inline")))
++void
++bar (void)
++{
++}
+--=20
+2.15.1
+
--=20
2.15.1


--=-=-=
Content-Type: text/plain


Cheers,
Alex

--=-=-=--




Information forwarded to guix-patches@HIDDEN:
bug#30111; Package guix-patches. Full text available.

Message received at 30111 <at> debbugs.gnu.org:


Received: (at 30111) by debbugs.gnu.org; 15 Jan 2018 14:29:35 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Jan 15 09:29:35 2018
Received: from localhost ([127.0.0.1]:56829 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1eb5lX-0006AH-8e
	for submit <at> debbugs.gnu.org; Mon, 15 Jan 2018 09:29:35 -0500
Received: from mail-pg0-f51.google.com ([74.125.83.51]:38198)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <alexvong1995@HIDDEN>) id 1eb5lV-0006A1-BJ
 for 30111 <at> debbugs.gnu.org; Mon, 15 Jan 2018 09:29:33 -0500
Received: by mail-pg0-f51.google.com with SMTP id y27so2052476pgc.5
 for <30111 <at> debbugs.gnu.org>; Mon, 15 Jan 2018 06:29:33 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:subject:references:date:in-reply-to:message-id:user-agent
 :mime-version:content-transfer-encoding;
 bh=CUP48WvMIt5WLsQZRi5XOtBhXIfAwI1z6/sRK4XwnNc=;
 b=i1b5R4odkBsdeuKyIxbYlBm2r3pcKSB+gO6o8LOM6QKvRxRSLj5Hm8ZDyoc9MPcp+Y
 Z++DIEvphpYHkYX+TbRrfPjyPyljBJJQjasoAvucJPPu5i+CDcwJ/ROHoWSfrb2h16xQ
 D31fR6ZJxynlhPZsGTNFmpDKRAEKHWM6fCmqcMIIvtTW8e45PrTglUGM2ViAjLgeP6bo
 jWxgAT42BGi3rsnFEG4UL7suulcQs9unofUGIBeE3zFkoZvxgbPsK4ZG3FhbBlBwsV1v
 QAwH2ROJv/j9yDTcmWbcUqxPpwaXoJLN2Gz1909DKdoWTixFkVenc/akpB8+0Xb5Ik5v
 0UqA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:subject:references:date:in-reply-to
 :message-id:user-agent:mime-version:content-transfer-encoding;
 bh=CUP48WvMIt5WLsQZRi5XOtBhXIfAwI1z6/sRK4XwnNc=;
 b=p23Eli2aFkUxuUEBIUINrlDGVlM3OuSbbHe0yatQLe0uJP8f6KQrQ9QE0693xUll0K
 6dNuiIWO6YgjMiMgMW0eXGGhje7ma0S5KkUdN9SixbuGkRS3FWO3KDcZlc3ckZSqDHMt
 n96Jub7iEBPIOKv8IjOruPkEdFzBbBzXm4/3KED06AAYWuSbpOhQUphg5BXAJ26b2FvK
 oyJEUTnn2Qp+n8qFiAwLHMsgg+cuCZhzW6Ye8ladMWo8LngrIdUQYljaJjUrWss0RoQb
 uo8S07bw9whfQgSlxh9J7x2KvVlsT3IOl9jYmYBKKaNamy4VAn8vLqpVpORWH4MrvfFb
 Msgg==
X-Gm-Message-State: AKwxyteUBIcnnjWp4VdBFDpa2leI1ZLad32x5lRTn/pOMevUDN/Bg5vo
 rziJyGdddPrX611xlh8rHxU=
X-Google-Smtp-Source: ACJfBotLkPDBPo4N3BwZUaXSRsjmnqAR8IEmD7Rluz0tOXlEE443bcwVleYy5v9Brm2DBhMohaFzVw==
X-Received: by 10.98.106.1 with SMTP id f1mr15343263pfc.162.1516026566588;
 Mon, 15 Jan 2018 06:29:26 -0800 (PST)
Received: from debian (n058152179035.netvigator.com. [58.152.179.35])
 by smtp.gmail.com with ESMTPSA id l190sm41434827pfc.73.2018.01.15.06.29.20
 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);
 Mon, 15 Jan 2018 06:29:25 -0800 (PST)
From: Alex Vong <alexvong1995@HIDDEN>
To: 30111 <at> debbugs.gnu.org
Subject: Re: gnu: gcc@7: Apply the 'retpoline' mitigation technique.
References: <877esksi62.fsf@HIDDEN>
Date: Mon, 15 Jan 2018 22:29:10 +0800
In-Reply-To: <877esksi62.fsf@HIDDEN> (Alex Vong's message of "Sun, 14 Jan
 2018 21:07:17 +0800")
Message-ID: <87d12bgpqh.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Debbugs-Envelope-To: 30111
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>

Hello,

Please do not review the last patch. It seems the author[0] has
refactor the commits and place them into the new 'retpoline-regnames'
branch. I think these commits get sent to gcc-patches for review[1].

[0]: http://git.infradead.org/users/dwmw2/gcc-retpoline.git
[1]: https://gcc.gnu.org/ml/gcc-patches/2018-01/

Alex Vong <alexvong1995@HIDDEN> writes:

> 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 gcc@7.
>
> 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 <alexvong1995@HIDDEN>
> Date: Sun, 14 Jan 2018 20:12:19 +0800
> Subject: [PATCH] gnu: gcc@7: Apply the 'retpoline' mitigation technique.
>
> This is part of Spectre (branch target injection) [CVE-2017-5715]
> mitigation. Suggested by Mark H Weaver <mhw@HIDDEN>.
>
> * gnu/local.mk (dist_patch_DATA): Add them.
> * gnu/packages/gcc.scm (gcc@7): Use them.
> * gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-t=
ests.patch,
> gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_retu=
rn-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-test=
s.patch,
> gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.patc=
h,
> gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.patc=
h,
> gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch,
> gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-in=
direct-branch-.patch,
> gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-f=
check-pointer-.patch,
> gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-j=
ump.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-indir=
ect-branch-via.patch,
> gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.p=
atch,
> 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_fram=
e-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_branc=
h-attribute-with-tests.patch
>  create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mfunction-retu=
rn-and-function_return-attribute.patch
>  create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mfunction-retu=
rn-keep-to-indirect-branch-tests.patch
>  create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-bran=
ch-loop.patch
>  create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-bran=
ch-register-and-tests.patch
>  create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-bran=
ch-thunk-extern.patch
>  create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-bran=
ch-thunk-inline.patch
>  create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mindirect-bran=
ch-thunk.patch
>  create mode 100644 gnu/packages/patches/gcc-retpoline-Add-mno-indirect-b=
ranch-register-to-indirect-branch-.patch
>  create mode 100644 gnu/packages/patches/gcc-retpoline-Add-tests-for-mind=
irect-branch-thunk-fcheck-pointer-.patch
>  create mode 100644 gnu/packages/patches/gcc-retpoline-Disable-red-zone-w=
ith-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-registe=
r-operand-modifier.patch
>  create mode 100644 gnu/packages/patches/gcc-retpoline-i386-More-use-refe=
rence-of-struct-ix86_frame-to-avoi.patch
>  create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Move-struct-i=
x86_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 =C2=A9 2016 Adonay "adfeno" Felipe Nogueira <https://librepl=
anet.org/wiki/User:Adfeno> <adfeno@HIDDEN>
>  # Copyright =C2=A9 2016, 2017 Ricardo Wurmus <rekado@HIDDEN>
>  # Copyright =C2=A9 2016 Ben Woodcroft <donttrustben@HIDDEN>
> -# Copyright =C2=A9 2016, 2017 Alex Vong <alexvong1995@HIDDEN>
> +# Copyright =C2=A9 2016, 2017, 2018 Alex Vong <alexvong1995@HIDDEN>
>  # Copyright =C2=A9 2016, 2017 Efraim Flashner <efraim@HIDDEN>
>  # Copyright =C2=A9 2016, 2017 Jan Nieuwenhuizen <janneke@HIDDEN>
>  # Copyright =C2=A9 2017 Tobias Geerinckx-Rice <me@HIDDEN>
> @@ -652,6 +652,23 @@ dist_patch_DATA =3D						\
>    %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-mach=
ine_function.patch	\
> +  %D%/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_f=
rame-to-avoid-cop.patch	\
> +  %D%/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-i=
x86_frame-to-avoi.patch	\
> +  %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.patch	\
> +  %D%/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thun=
k-fcheck-pointer-.patch	\
> +  %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inline.p=
atch	\
> +  %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.p=
atch	\
> +  %D%/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-=
tests.patch	\
> +  %D%/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-in=
direct-branch-via.patch	\
> +  %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch	\
> +  %D%/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_r=
eturn-attribute.patch	\
> +  %D%/packages/patches/gcc-retpoline-Add-mfunction-return-keep-to-indire=
ct-branch-tests.patch	\
> +  %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-register-and-t=
ests.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-indirec=
t-jump.patch	\
> +  %D%/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifie=
r.patch	\
> +  %D%/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thu=
nk_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 =C2=A9 2015 Andreas Enge <andreas@HIDDEN>
>  ;;; Copyright =C2=A9 2015, 2016, 2017 Efraim Flashner <efraim@HIDDEN=
o.il>
>  ;;; Copyright =C2=A9 2016 Carlos S=C3=A1nchez de La Lama <csanchezdll@gm=
ail.com>
> +;;; Copyright =C2=A9 2018 ALex Vong <alexvong1995@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.patc=
h"
> -                                       "gcc-5.0-libvtv-runpath.patch"))))
> +                                       "gcc-5.0-libvtv-runpath.patch"
> +                                       "gcc-retpoline-i386-Move-struct-i=
x86_frame-to-machine_function.patch"
> +                                       "gcc-retpoline-i386-Use-reference=
-of-struct-ix86_frame-to-avoid-cop.patch"
> +                                       "gcc-retpoline-i386-More-use-refe=
rence-of-struct-ix86_frame-to-avoi.patch"
> +                                       "gcc-retpoline-Add-mindirect-bran=
ch-thunk.patch"
> +                                       "gcc-retpoline-Add-tests-for-mind=
irect-branch-thunk-fcheck-pointer-.patch"
> +                                       "gcc-retpoline-Add-mindirect-bran=
ch-thunk-inline.patch"
> +                                       "gcc-retpoline-Add-mindirect-bran=
ch-thunk-extern.patch"
> +                                       "gcc-retpoline-Add-indirect_branc=
h-attribute-with-tests.patch"
> +                                       "gcc-retpoline-Use-__x86.indirect=
_thunk.reg-for-indirect-branch-via.patch"
> +                                       "gcc-retpoline-Add-mindirect-bran=
ch-loop.patch"
> +                                       "gcc-retpoline-Add-mfunction-retu=
rn-and-function_return-attribute.patch"
> +                                       "gcc-retpoline-Add-mfunction-retu=
rn-keep-to-indirect-branch-tests.patch"
> +                                       "gcc-retpoline-Add-mindirect-bran=
ch-register-and-tests.patch"
> +                                       "gcc-retpoline-Add-mno-indirect-b=
ranch-register-to-indirect-branch-.patch"
> +                                       "gcc-retpoline-Disable-red-zone-w=
ith-local-indirect-jump.patch"
> +                                       "gcc-retpoline-i386-Add-V-registe=
r-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-en=
ds
>  for several languages, including C, C++, Objective-C, Fortran, Ada, and =
Go.
> diff --git a/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attri=
bute-with-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-indirect_bra=
nch-attribute-with-tests.patch
> new file mode 100644
> index 000000000..5129a8273
> --- /dev/null
> +++ b/gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-wi=
th-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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@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 {
> + };
> +=20
> + enum indirect_branch {
> ++  indirect_branch_unset =3D 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)
> +     }
> + }
> +=20
> ++/* 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 =3D=3D indirect_branch_unset)
> ++    {
> ++      tree attr =3D lookup_attribute ("indirect_branch",
> ++				    DECL_ATTRIBUTES (fndecl));
> ++      if (attr !=3D NULL)
> ++	{
> ++	  tree args =3D TREE_VALUE (attr);
> ++	  if (args =3D=3D NULL)
> ++	    gcc_unreachable ();
> ++	  tree cst =3D TREE_VALUE (args);
> ++	  if (strcmp (TREE_STRING_POINTER (cst), "keep") =3D=3D 0)
> ++	    cfun->machine->indirect_branch_type =3D indirect_branch_keep;
> ++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk") =3D=3D 0)
> ++	    cfun->machine->indirect_branch_type =3D indirect_branch_thunk;
> ++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") =3D=3D 0)
> ++	    cfun->machine->indirect_branch_type =3D indirect_branch_thunk_inli=
ne;
> ++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") =3D=3D 0)
> ++	    cfun->machine->indirect_branch_type =3D indirect_branch_thunk_exte=
rn;
> ++	  else
> ++	    gcc_unreachable ();
> ++	}
> ++      else
> ++	cfun->machine->indirect_branch_type =3D 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 !=3D NULL_TREE)
> +-	ix86_set_func_type (fndecl);
> ++	{
> ++	  ix86_set_func_type (fndecl);
> ++	  ix86_set_indirect_branch_type (fndecl);
> ++	}
> +       return;
> +     }
> +=20
> +@@ -7172,6 +7206,7 @@ ix86_set_current_function (tree fndecl)
> +     }
> +=20
> +   ix86_set_func_type (fndecl);
> ++  ix86_set_indirect_branch_type (fndecl);
> +=20
> +   tree new_tree =3D DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
> +   if (new_tree =3D=3D NULL_TREE)
> +@@ -28605,9 +28640,11 @@ ix86_output_indirect_branch (rtx call_op, const=
 char *xasm,
> +   char push_buf[64];
> +   bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn);
> +=20
> +-  if (ix86_indirect_branch !=3D indirect_branch_thunk_inline)
> ++  if (cfun->machine->indirect_branch_type
> ++      !=3D indirect_branch_thunk_inline)
> +     {
> +-      bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_t=
hunk;
> ++      bool need_thunk
> ++	=3D cfun->machine->indirect_branch_type =3D=3D indirect_branch_thunk;
> +       if (need_bnd_p)
> + 	indirect_thunk_bnd_needed |=3D need_thunk;
> +       else
> +@@ -28716,7 +28753,7 @@ const char *
> + ix86_output_indirect_jmp (rtx call_op)
> + {
> +   if (ix86_red_zone_size =3D=3D 0
> +-      && ix86_indirect_branch !=3D indirect_branch_keep)
> ++      && cfun->machine->indirect_branch_type !=3D 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 =3D constant_call_address_operand (call_op, VOIDmode);
> +   bool output_indirect_p
> +     =3D (!TARGET_SEH
> +-       && ix86_indirect_branch !=3D indirect_branch_keep);
> ++       && cfun->machine->indirect_branch_type !=3D indirect_branch_keep=
);
> +   bool seh_nop_p =3D false;
> +   const char *xasm;
> +=20
> +@@ -41749,7 +41786,7 @@ ix86_handle_struct_attribute (tree *node, tree n=
ame, tree, int,
> + }
> +=20
> + 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) !=3D FUNCTION_DECL)
> +@@ -41758,6 +41795,29 @@ ix86_handle_fndecl_attribute (tree *node, tree =
name, tree, int,
> +                name);
> +       *no_add_attrs =3D true;
> +     }
> ++
> ++  if (is_attribute_p ("indirect_branch", name))
> ++    {
> ++      tree cst =3D TREE_VALUE (args);
> ++      if (TREE_CODE (cst) !=3D STRING_CST)
> ++	{
> ++	  warning (OPT_Wattributes,
> ++		   "%qE attribute requires a string constant argument",
> ++		   name);
> ++	  *no_add_attrs =3D true;
> ++	}
> ++      else if (strcmp (TREE_STRING_POINTER (cst), "keep") !=3D 0
> ++	       && strcmp (TREE_STRING_POINTER (cst), "thunk") !=3D 0
> ++	       && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") !=3D 0
> ++	       && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") !=3D 0)
> ++	{
> ++	  warning (OPT_Wattributes,
> ++		   "argument to %qE attribute is not "
> ++		   "(keep|thunk|thunk-inline|thunk-extern)", name);
> ++	  *no_add_attrs =3D true;
> ++	}
> ++    }
> ++
> +   return NULL_TREE;
> + }
> +=20
> +@@ -46052,6 +46112,8 @@ static const struct attribute_spec ix86_attribut=
e_table[] =3D
> +     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 },
> +=20
> +   /* 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;
> +=20
> ++  /* 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=3Dthunk -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" } } */
> +--=20
> +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-mf=
unction-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-functio=
n_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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@HIDDEN>
> +Date: Tue, 5 Dec 2017 13:29:06 -0800
> +Subject: [PATCH 11/17] Add -mfunction-return=3D and function_return attr=
ibute
> +
> +Add -mfunction-return=3D and function_return attribute tests
> +
> +-mfunction-return=3Dthunk
> +  Convert function return instruction to PC-relative call thunk.
> +-mfunction-return=3Dthunk-inline
> +  Convert function return instruction to PC-relative call thunk with
> +  thunk inlined.
> +-mfunction-return=3Dthunk-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;
> +=20
> + 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 loa=
d,
> + 						enum machine_mode mode);
> +=20
> +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 =3D ix86_indirect_branch;
> +     }
> ++
> ++  if (cfun->machine->function_return_type =3D=3D indirect_branch_unset)
> ++    {
> ++      tree attr =3D lookup_attribute ("function_return",
> ++				    DECL_ATTRIBUTES (fndecl));
> ++      if (attr !=3D NULL)
> ++	{
> ++	  tree args =3D TREE_VALUE (attr);
> ++	  if (args =3D=3D NULL)
> ++	    gcc_unreachable ();
> ++	  tree cst =3D TREE_VALUE (args);
> ++	  if (strcmp (TREE_STRING_POINTER (cst), "keep") =3D=3D 0)
> ++	    cfun->machine->function_return_type =3D indirect_branch_keep;
> ++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk") =3D=3D 0)
> ++	    cfun->machine->function_return_type =3D indirect_branch_thunk;
> ++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") =3D=3D 0)
> ++	    cfun->machine->function_return_type =3D indirect_branch_thunk_inli=
ne;
> ++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") =3D=3D 0)
> ++	    cfun->machine->function_return_type =3D indirect_branch_thunk_exte=
rn;
> ++	  else
> ++	    gcc_unreachable ();
> ++	}
> ++      else
> ++	cfun->machine->function_return_type =3D ix86_function_return;
> ++    }
> + }
> +=20
> + /* 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. =
 */
> +=20
> + 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 >=3D 0 && ret_p)
> ++    gcc_unreachable ();
> ++
> +   if (USE_HIDDEN_LINKONCE)
> +     {
> +       const char *bnd =3D 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 =3D 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;
> +=20
> +   /* 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 =3D 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);
> +       }
> +=20
> ++  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) =3D make_node (BLOCK);
> +   current_function_decl =3D decl;
> +   allocate_struct_function (decl, false);
> +@@ -28736,7 +28807,7 @@ ix86_output_indirect_branch (rtx call_op, const =
char *xasm,
> + 		indirect_thunk_needed =3D true;
> + 	    }
> + 	}
> +-      indirect_thunk_name (thunk_name_buf, regno, need_bnd_p);
> ++      indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false);
> +       thunk_name =3D thunk_name_buf;
> +     }
> +   else
> +@@ -28860,6 +28931,43 @@ ix86_output_indirect_jmp (rtx call_op)
> +     return "%!jmp\t%A0";
> + }
> +=20
> ++const char *
> ++ix86_output_function_return (bool long_p)
> ++{
> ++  if (cfun->machine->function_return_type !=3D indirect_branch_keep)
> ++    {
> ++      char thunk_name[32];
> ++      bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn=
);
> ++
> ++      if (cfun->machine->function_return_type
> ++	  !=3D indirect_branch_thunk_inline)
> ++	{
> ++	  bool need_thunk =3D (cfun->machine->function_return_type
> ++			     =3D=3D indirect_branch_thunk);
> ++	  indirect_thunk_name (thunk_name, -1, need_bnd_p, true);
> ++	  if (need_bnd_p)
> ++	    {
> ++	      indirect_thunk_bnd_needed |=3D need_thunk;
> ++	      fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
> ++	    }
> ++	  else
> ++	    {
> ++	      indirect_thunk_needed |=3D 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.  */
> +=20
> + const char *
> +@@ -41916,6 +42024,28 @@ ix86_handle_fndecl_attribute (tree *node, tree =
name, tree args, int,
> + 	}
> +     }
> +=20
> ++  if (is_attribute_p ("function_return", name))
> ++    {
> ++      tree cst =3D TREE_VALUE (args);
> ++      if (TREE_CODE (cst) !=3D STRING_CST)
> ++	{
> ++	  warning (OPT_Wattributes,
> ++		   "%qE attribute requires a string constant argument",
> ++		   name);
> ++	  *no_add_attrs =3D true;
> ++	}
> ++      else if (strcmp (TREE_STRING_POINTER (cst), "keep") !=3D 0
> ++	       && strcmp (TREE_STRING_POINTER (cst), "thunk") !=3D 0
> ++	       && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") !=3D 0
> ++	       && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") !=3D 0)
> ++	{
> ++	  warning (OPT_Wattributes,
> ++		   "argument to %qE attribute is not "
> ++		   "(keep|thunk|thunk-inline|thunk-extern)", name);
> ++	  *no_add_attrs =3D true;
> ++	}
> ++    }
> ++
> +   return NULL_TREE;
> + }
> +=20
> +@@ -46212,6 +46342,8 @@ static const struct attribute_spec ix86_attribut=
e_table[] =3D
> +     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 },
> +=20
> +   /* 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;
> +=20
> ++  /* 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=3D
> + Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indi=
rect_branch) Init(indirect_branch_keep)
> + Update indirect call and jump.
> +=20
> ++mfunction-return=3D
> ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_func=
tion_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=3D op=
tion):
> ++Known indirect branch choices (for use with the -mindirect-branch=3D/-m=
function-return=3D options):
> +=20
> + 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=3Dthunk" } */
> ++
> ++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/testsuit=
e/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=3Dthunk-inline -mindirect-branch=
=3Dthunk -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" { targ=
et { ! 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:" { targe=
t { 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/testsuit=
e/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=3Dthunk-extern -mindirect-branch=
=3Dthunk -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" { targ=
et { ! 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:" { targe=
t { 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/testsuit=
e/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=3Dkeep -mindirect-branch=3Dthunk=
 -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" { targ=
et { ! 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:" { targe=
t { 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/testsuit=
e/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=3Dkeep -mindirect-branch=3Dthunk=
-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/testsuit=
e/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=3Dkeep -mindirect-branch=3Dthunk=
-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" { targ=
et { ! 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/testsuit=
e/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=3Dkeep -mindirect-branch=3Dkeep =
-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" { targ=
et { ! 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/testsuit=
e/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=3Dthunk-inline -mindirect-branch=
=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dkeep" } */
> ++
> ++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=3Dkeep" } */
> ++
> ++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=3Dkeep" } */
> ++
> ++__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=3Dkeep" } */
> ++
> ++__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=3Dthunk-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=3Dthunk -mindirect-branch=3Dthun=
k -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" { targ=
et { ! 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 } } =
} */
> +--=20
> +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-mf=
unction-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-ind=
irect-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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@HIDDEN>
> +Date: Wed, 6 Dec 2017 09:58:42 -0800
> +Subject: [PATCH 12/17] Add -mfunction-return=3Dkeep to indirect branch t=
ests
> +
> +---
> + 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/test=
suite/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=3Dthunk -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
 -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/test=
suite/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=3Dthunk -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
 -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/test=
suite/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=3Dthunk -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
 -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/test=
suite/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=3Dthunk -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
 -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/test=
suite/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=3Dthunk" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect=
-branch=3Dthunk" } */
> +=20
> + extern void bar (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/test=
suite/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=3Dthunk" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect=
-branch=3Dthunk" } */
> +=20
> + extern void bar (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/test=
suite/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=3Dthunk -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
 -fno-pic" } */
> +=20
> + 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=3Dkeep -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dkeep -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dkeep -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dkeep -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dkeep -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dkeep -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dkeep -fno-pic" } */
> +=20
> + 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=3Dthunk -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
 -fno-pic" } */
> +=20
> + 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=3Dthunk -fcheck-pointer-bounds -=
mmpx -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
 -fcheck-pointer-bounds -mmpx -fno-pic" } */
> +=20
> + 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=3Dthunk -fcheck-pointer-bounds -=
mmpx -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
 -fcheck-pointer-bounds -mmpx -fno-pic" } */
> +=20
> + 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=3Dthunk -fcheck-pointer-bounds -=
mmpx -fpic -fno-plt" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
 -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
> +=20
> + 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=3Dthunk -fcheck-pointer-bounds -=
mmpx -fpic -fno-plt" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
 -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
> +=20
> + void bar (char *);
> + char buf[10];
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/g=
cc/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=3Dthunk-extern -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
-extern -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/g=
cc/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=3Dthunk-extern -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
-extern -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/g=
cc/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=3Dthunk-extern -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
-extern -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/g=
cc/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=3Dthunk-extern -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
-extern -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/g=
cc/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=3Dthunk-extern" }=
 */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect=
-branch=3Dthunk-extern" } */
> +=20
> + extern void bar (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/g=
cc/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=3Dthunk-extern" }=
 */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect=
-branch=3Dthunk-extern" } */
> +=20
> + extern void bar (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/g=
cc/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=3Dthunk-extern -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
-extern -fno-pic" } */
> +=20
> + void func0 (void);
> + void func1 (void);
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/g=
cc/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=3Dthunk-inline -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
-inline -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/g=
cc/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=3Dthunk-inline -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
-inline -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/g=
cc/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=3Dthunk-inline -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
-inline -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/g=
cc/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=3Dthunk-inline -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
-inline -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/g=
cc/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=3Dthunk-inline" }=
 */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect=
-branch=3Dthunk-inline" } */
> +=20
> + extern void bar (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/g=
cc/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=3Dthunk-inline" }=
 */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect=
-branch=3Dthunk-inline" } */
> +=20
> + extern void bar (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/g=
cc/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=3Dthunk-inline -fno-pic" } */
> ++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk=
-inline -fno-pic" } */
> +=20
> + void func0 (void);
> + void func1 (void);
> +--=20
> +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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@HIDDEN>
> +Date: Thu, 16 Nov 2017 14:46:20 -0800
> +Subject: [PATCH 10/17] Add -mindirect-branch-loop=3D
> +
> +Add -mindirect-branch-loop=3D 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
> + };
> +=20
> ++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 reg=
no)
> +=20
> +   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
> +=20
> +-  /* 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 ();
> ++    }
> +=20
> +   /* 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(in=
direct_branch_thunk_inline)
> +=20
> + EnumValue
> + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_=
extern)
> ++
> ++mindirect-branch-loop=3D
> ++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=3D option):
> ++
> ++EnumValue
> ++Enum(indirect_branch_loop) String(lfence) Value(indirect_branch_loop_lf=
ence)
> ++
> ++EnumValue
> ++Enum(indirect_branch_loop) String(pause) Value(indirect_branch_loop_pau=
se)
> ++
> ++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=3Dthunk -mindirect-branch-loop=
=3Dpause -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" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { 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=3Dthunk -mindirect-branch-loop=
=3Dnop -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" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { 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=3Dthunk -mindirect-branch-loop=
=3Dlfence -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" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { 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=3Dthunk-inline -mindirect-branch=
-loop=3Dpause -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=3Dthunk-extern -mindirect-branch=
-loop=3Dpause -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" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { 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" } } */
> +--=20
> +2.15.1
> +
> diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-regi=
ster-and-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-bra=
nch-register-and-tests.patch
> new file mode 100644
> index 000000000..de9e373fd
> --- /dev/null
> +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-register-an=
d-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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@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-registe=
r-1.c
> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-registe=
r-2.c
> + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-registe=
r-3.c
> +
> +diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraint=
s.md
> +index 38d604fdace..697caf704dd 100644
> +--- a/gcc/config/i386/constraints.md
> ++++ b/gcc/config/i386/constraints.md
> +@@ -198,16 +198,20 @@
> +=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 =3D=3D DImode")
> ++       (and (match_test "TARGET_X32 && Pmode =3D=3D DImode
> ++			 && !ix86_indirect_branch_thunk_register")
> + 	    (match_operand 0 "GOT_memory_operand"))))
> +=20
> + (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 =3D=3D DImode")
> ++       (and (match_test "TARGET_X32 && Pmode =3D=3D DImode
> ++			 && !ix86_indirect_branch_thunk_register")
> + 	    (match_operand 0 "GOT_memory_operand"))))
> +=20
> + (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] =3D convert_memory_address (word_mode, operands[0]);
> + })
> +=20
> +@@ -11657,7 +11657,7 @@
> + 					 OPTAB_DIRECT);
> +     }
> +=20
> +-  if (TARGET_X32)
> ++  if (TARGET_X32 || ix86_indirect_branch_thunk_register)
> +     operands[0] =3D convert_memory_address (word_mode, operands[0]);
> + })
> +=20
> +@@ -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")])
> +=20
> +@@ -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 @@
> + })
> +=20
> + (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")])
> +=20
> + (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))])
> +=20
> + ;; 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")])
> +=20
> +@@ -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 @@
> +=20
> + (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(in=
direct_branch_thunk_inline)
> + EnumValue
> + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_=
extern)
> +=20
> ++mindirect-branch-register
> ++Target Report Var(ix86_indirect_branch_thunk_register) Init(0)
> ++Force indirect call and jump via register.
> ++
> + mindirect-branch-loop=3D
> + Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86=
_indirect_branch_loop) Undocumented Init(indirect_branch_loop_lfence)
> +=20
> +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"))))
> +=20
> + ;; Return true if OP is a memory operands that can be used in sibcalls.
> +@@ -664,7 +665,8 @@
> +=20
> + ;; 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 =3D XEXP (op, 0);
> +   return (GET_CODE (op) =3D=3D CONST
> +@@ -678,9 +680,11 @@
> +   (ior (match_test "constant_call_address_operand
> + 		     (op, mode =3D=3D 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 =3D=3D DImode")
> ++	    (and (match_test "TARGET_X32 && Pmode =3D=3D DImode
> ++			      && !ix86_indirect_branch_thunk_register")
> + 		 (match_operand 0 "GOT_memory_operand")))))
> +=20
> + ;; Similarly, but for tail calls, in which we cannot allow memory refer=
ences.
> +@@ -688,14 +692,17 @@
> +   (ior (match_test "constant_call_address_operand
> + 		     (op, mode =3D=3D 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 =3D=3D DImode")
> ++	    (and (match_test "TARGET_X32 && Pmode =3D=3D DImode
> ++			      && !ix86_indirect_branch_thunk_register")
> + 		 (match_operand 0 "GOT_memory_operand")))))
> +=20
> + ;; Return true if OP is a 32-bit GOT symbol operand.
> + (define_predicate "GOT32_symbol_operand"
> +-  (match_test "GET_CODE (op) =3D=3D CONST
> ++  (match_test "!ix86_indirect_branch_thunk_register
> ++	       && GET_CODE (op) =3D=3D CONST
> +                && GET_CODE (XEXP (op, 0)) =3D=3D UNSPEC
> +                && XINT (XEXP (op, 0), 1) =3D=3D UNSPEC_GOT"))
> +=20
> +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=3Dthunk -mindirect-branch-regist=
er -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)a=
x" } } */
> ++/* { 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=3Dthunk-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=3Dthunk-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)a=
x" } } */
> ++/* { 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" } } */
> +--=20
> +2.15.1
> +
> diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thun=
k-extern.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-th=
unk-extern.patch
> new file mode 100644
> index 000000000..18b2dfaea
> --- /dev/null
> +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-exter=
n.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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@HIDDEN>
> +Date: Mon, 27 Nov 2017 08:38:41 -0800
> +Subject: [PATCH 07/17] Add -mindirect-branch=3Dthunk-extern
> +
> +Add -mindirect-branch=3Dthunk-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
> + };
> +=20
> + #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_b=
ranch_thunk)
> +=20
> + 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/g=
cc/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=3Dthunk-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/g=
cc/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=3Dthunk-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/g=
cc/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=3Dthunk-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/g=
cc/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=3Dthunk-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/g=
cc/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=3Dthunk-extern" }=
 */
> ++
> ++extern void bar (void);
> ++
> ++void
> ++foo (void)
> ++{
> ++  bar ();
> ++}
> ++
> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> ++/* { 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/g=
cc/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=3Dthunk-extern" }=
 */
> ++
> ++extern void bar (void);
> ++
> ++int
> ++foo (void)
> ++{
> ++  bar ();
> ++  return 0;
> ++}
> ++
> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> ++/* { 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/g=
cc/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=3Dthunk-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" } } */
> +--=20
> +2.15.1
> +
> diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thun=
k-inline.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-th=
unk-inline.patch
> new file mode 100644
> index 000000000..bb12c0e95
> --- /dev/null
> +++ b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-inlin=
e.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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@HIDDEN>
> +Date: Wed, 15 Nov 2017 11:20:31 -0800
> +Subject: [PATCH 06/17] Add -mindirect-branch=3Dthunk-inline
> +
> +Add -mindirect-branch=3Dthunk-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 {
> +=20
> + enum indirect_branch {
> +   indirect_branch_keep,
> +-  indirect_branch_thunk
> ++  indirect_branch_thunk,
> ++  indirect_branch_thunk_inline
> + };
> +=20
> + #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 =3D ix86_bnd_prefixed_insn_p (current_output_insn);
> +=20
> +-  bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thunk;
> +-  if (need_bnd_p)
> +-    indirect_thunk_bnd_needed |=3D need_thunk;
> ++  if (ix86_indirect_branch !=3D indirect_branch_thunk_inline)
> ++    {
> ++      bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_t=
hunk;
> ++      if (need_bnd_p)
> ++	indirect_thunk_bnd_needed |=3D need_thunk;
> ++      else
> ++	indirect_thunk_needed |=3D need_thunk;
> ++      indirect_thunk_name (thunk_name_buf, need_bnd_p);
> ++      thunk_name =3D thunk_name_buf;
> ++    }
> +   else
> +-    indirect_thunk_needed |=3D need_thunk;
> +-  indirect_thunk_name (thunk_name, need_bnd_p);
> ++    thunk_name =3D NULL;
> +=20
> +   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, cons=
t char *xasm,
> +=20
> +       output_asm_insn (push_buf, &call_op);
> +=20
> +-      if (need_bnd_p)
> +-	fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
> ++      if (thunk_name !=3D 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);
> +=20
> +       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
> +=20
> +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_br=
anch_keep)
> +=20
> + 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/g=
cc/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=3Dthunk-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/g=
cc/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=3Dthunk-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/g=
cc/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=3Dthunk-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/g=
cc/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=3Dthunk-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/g=
cc/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=3Dthunk-inline" }=
 */
> ++
> ++extern void bar (void);
> ++
> ++void
> ++foo (void)
> ++{
> ++  bar ();
> ++}
> ++
> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> ++/* { 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/g=
cc/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=3Dthunk-inline" }=
 */
> ++
> ++extern void bar (void);
> ++
> ++int
> ++foo (void)
> ++{
> ++  bar ();
> ++  return 0;
> ++}
> ++
> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> ++/* { 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/g=
cc/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=3Dthunk-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" } } */
> +--=20
> +2.15.1
> +
> diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thun=
k.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk.pat=
ch
> 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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@HIDDEN>
> +Date: Wed, 1 Nov 2017 16:05:50 -0700
> +Subject: [PATCH 04/17] Add -mindirect-branch=3Dthunk
> +
> +Add tests for -mindirect-branch=3Dthunk
> +---
> + 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 */
> + };
> +=20
> ++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
> +=20
> + 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 loa=
d,
> + 						enum machine_mode mode);
> +=20
> +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
> +=20
> ++static int indirectlabelno;
> ++static bool indirect_thunk_needed =3D false;
> ++static bool indirect_thunk_bnd_needed =3D 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 =3D 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] =3D stack_pointer_rtx;
> ++  xops[1] =3D 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 =3D build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
> ++		     get_identifier (name),
> ++		     build_function_type_list (void_type_node, NULL_TREE));
> ++  DECL_RESULT (decl) =3D build_decl (BUILTINS_LOCATION, RESULT_DECL,
> ++				   NULL_TREE, void_type_node);
> ++  TREE_PUBLIC (decl) =3D 1;
> ++  TREE_STATIC (decl) =3D 1;
> ++  DECL_IGNORED_P (decl) =3D 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) =3D 1;
> ++    }
> ++  else
> ++#endif
> ++    if (USE_HIDDEN_LINKONCE)
> ++      {
> ++	cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (dec=
l));
> ++
> ++	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) =3D make_node (BLOCK);
> ++  current_function_decl =3D 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 =3D true;
> ++  first_function_block_is_cold =3D 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 =3D NULL;
> ++}
> ++
> + static int pic_labels_used;
> +=20
> + /* 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;
> +=20
> ++  if (indirect_thunk_needed)
> ++    output_indirect_thunk_function (false);
> ++  if (indirect_thunk_bnd_needed)
> ++    output_indirect_thunk_function (true);
> ++
> +   for (regno =3D AX_REG; regno <=3D SP_REG; regno++)
> +     {
> +       char name[32];
> +@@ -28452,12 +28596,132 @@ ix86_nopic_noplt_attribute_p (rtx call_op)
> +   return false;
> + }
> +=20
> ++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 =3D ix86_bnd_prefixed_insn_p (current_output_insn);
> ++
> ++  bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thunk;
> ++  if (need_bnd_p)
> ++    indirect_thunk_bnd_needed |=3D need_thunk;
> ++  else
> ++    indirect_thunk_needed |=3D 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 !=3D 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 =3D XEXP (call_op, 0);
> ++	  if (ix86_decompose_address (addr, &parts)
> ++	      && parts.base =3D=3D 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 =3D gen_rtx_MULT (Pmode, parts.index,
> ++				       GEN_INT (parts.scale));
> ++		  addr =3D gen_rtx_PLUS (Pmode, stack_pointer_rtx,
> ++				       addr);
> ++		}
> ++	      else
> ++		addr =3D stack_pointer_rtx;
> ++
> ++	      rtx disp;
> ++	      if (parts.disp !=3D NULL_RTX)
> ++		disp =3D plus_constant (Pmode, parts.disp,
> ++				      UNITS_PER_WORD);
> ++	      else
> ++		disp =3D GEN_INT (UNITS_PER_WORD);
> ++
> ++	      addr =3D gen_rtx_PLUS (Pmode, addr, disp);
> ++	      call_op =3D 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 =3D=3D 0
> ++      && ix86_indirect_branch !=3D indirect_branch_keep)
> ++    {
> ++      ix86_output_indirect_branch (call_op, "%0", true);
> ++      return "";
> ++    }
> ++  else
> ++    return "%!jmp\t%A0";
> ++}
> ++
> + /* Output the assembly for a call instruction.  */
> +=20
> + const char *
> + ix86_output_call_insn (rtx_insn *insn, rtx call_op)
> + {
> +   bool direct_p =3D constant_call_address_operand (call_op, VOIDmode);
> ++  bool output_indirect_p
> ++    =3D (!TARGET_SEH
> ++       && ix86_indirect_branch !=3D indirect_branch_keep);
> +   bool seh_nop_p =3D false;
> +   const char *xasm;
> +=20
> +@@ -28467,10 +28731,21 @@ ix86_output_call_insn (rtx_insn *insn, rtx cal=
l_op)
> + 	{
> + 	  if (ix86_nopic_noplt_attribute_p (call_op))
> + 	    {
> ++	      direct_p =3D false;
> + 	      if (TARGET_64BIT)
> +-		xasm =3D "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}=
";
> ++		{
> ++		  if (output_indirect_p)
> ++		    xasm =3D "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
> ++		  else
> ++		    xasm =3D "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[ri=
p]]}";
> ++		}
> + 	      else
> +-		xasm =3D "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
> ++		{
> ++		  if (output_indirect_p)
> ++		    xasm =3D "{%p0@GOT|[DWORD PTR %p0@GOT]}";
> ++		  else
> ++		    xasm =3D "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
> ++		}
> + 	    }
> + 	  else
> + 	    xasm =3D "%!jmp\t%P0";
> +@@ -28480,9 +28755,17 @@ ix86_output_call_insn (rtx_insn *insn, rtx call=
_op)
> +       else if (TARGET_SEH)
> + 	xasm =3D "%!rex.W jmp\t%A0";
> +       else
> +-	xasm =3D "%!jmp\t%A0";
> ++	{
> ++	  if (output_indirect_p)
> ++	    xasm =3D "%0";
> ++	  else
> ++	    xasm =3D "%!jmp\t%A0";
> ++	}
> +=20
> +-      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 "";
> +     }
> +=20
> +@@ -28520,18 +28803,37 @@ ix86_output_call_insn (rtx_insn *insn, rtx cal=
l_op)
> +     {
> +       if (ix86_nopic_noplt_attribute_p (call_op))
> + 	{
> ++	  direct_p =3D false;
> + 	  if (TARGET_64BIT)
> +-	    xasm =3D "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[ri=
p]]}";
> ++	    {
> ++	      if (output_indirect_p)
> ++		xasm =3D "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
> ++	      else
> ++		xasm =3D "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]=
}";
> ++	    }
> + 	  else
> +-	    xasm =3D "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
> ++	    {
> ++	      if (output_indirect_p)
> ++		xasm =3D "{%p0@GOT|[DWORD PTR %p0@GOT]}";
> ++	      else
> ++		xasm =3D "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
> ++	    }
> + 	}
> +       else
> + 	xasm =3D "%!call\t%P0";
> +     }
> +   else
> +-    xasm =3D "%!call\t%A0";
> ++    {
> ++      if (output_indirect_p)
> ++	xasm =3D "%0";
> ++      else
> ++	xasm =3D "%!call\t%A0";
> ++    }
> +=20
> +-  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);
> +=20
> +   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 c=
ontaining ret bytes.
> + mgeneral-regs-only
> + Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_fl=
ags) Save
> + Generate code which uses only the general registers.
> ++
> ++mindirect-branch=3D
> ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indi=
rect_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=3D op=
tion):
> ++
> ++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
> + -malign-data=3D@var{type}  -mstack-protector-guard=3D@var{guard} @gol
> +--mmitigate-rop  -mgeneral-regs-only}
> ++-mmitigate-rop  -mgeneral-regs-only -mindirect-branch=3D@var{choice}}
> +=20
> + @emph{x86 Windows Options}
> + @gccoptlist{-mconsole  -mcygwin  -mno-cygwin  -mdll @gol
> +@@ -25648,6 +25648,13 @@ Generate code that uses only the general-purpos=
e registers.  This
> + prevents the compiler from using floating-point, vector, mask and bound
> + registers.
> +=20
> ++@item -mindirect-branch=3D@var{choice}
> ++@opindex -mindirect-branch
> ++Update indirect call and jump with @var{choice}.  The default is
> ++@samp{keep}, which keeps indirect call and jump unmodified.
> ++@samp{thunk} converts indirect call and jump to push and
> ++PC-relative call thunk.
> ++
> + @end table
> +=20
> + 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/test=
suite/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=3Dthunk -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/test=
suite/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=3Dthunk -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/test=
suite/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=3Dthunk -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/test=
suite/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=3Dthunk -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/test=
suite/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=3Dthunk" } */
> ++
> ++extern void bar (void);
> ++
> ++void
> ++foo (void)
> ++{
> ++  bar ();
> ++}
> ++
> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> ++/* { 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/test=
suite/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=3Dthunk" } */
> ++
> ++extern void bar (void);
> ++
> ++int
> ++foo (void)
> ++{
> ++  bar ();
> ++  return 0;
> ++}
> ++
> ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> ++/* { 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/test=
suite/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=3Dthunk -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} } } */
> +--=20
> +2.15.1
> +
> diff --git a/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-r=
egister-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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@HIDDEN>
> +Date: Tue, 12 Dec 2017 12:34:26 -0800
> +Subject: [PATCH 14/17] Add -mno-indirect-branch-register to indirect bra=
nch
> + 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/test=
suite/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=3Dkeep -mindirect-branch=3Dthunk=
 -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/test=
suite/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=3Dkeep -mindirect-branch=3Dthunk=
 -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/test=
suite/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=3Dkeep -mindirect-branch=3Dthunk=
 -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch=
-register -mno-indirect-branch-register -mfunction-return=3Dkeep -mindirect=
-branch=3Dthunk -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/test=
suite/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=3Dkeep -mindirect-branch=3Dthunk=
 -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch=
-register -mno-indirect-branch-register -mfunction-return=3Dkeep -mindirect=
-branch=3Dthunk -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/test=
suite/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=3Dkeep -fpic -fno-plt -mindirect=
-branch=3Dthunk" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -fpic -fno-plt -mindirect-branch=3Dthunk" } */
> +=20
> + extern void bar (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/test=
suite/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=3Dkeep -fpic -fno-plt -mindirect=
-branch=3Dthunk" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch=
-register -mno-indirect-branch-register -mfunction-return=3Dkeep -fpic -fno=
-plt -mindirect-branch=3Dthunk" } */
> +=20
> + extern void bar (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/test=
suite/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=3Dkeep -mindirect-branch=3Dthunk=
 -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk -fno-pic" } */
> +=20
> + 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=3Dkeep -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dkeep -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dkeep -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dkeep -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dkeep -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dkeep -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dkeep -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -fno-pic" } */
> +=20
> + 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=3Dkeep -mindirect-branch=3Dthunk=
 -fcheck-pointer-bounds -mmpx -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fno-pic" } */
> +=20
> + 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=3Dkeep -mindirect-branch=3Dthunk=
 -fcheck-pointer-bounds -mmpx -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fno-pic" } */
> +=20
> + 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=3Dkeep -mindirect-branch=3Dthunk=
 -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt"=
 } */
> +=20
> + 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=3Dkeep -mindirect-branch=3Dthunk=
 -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch=
-register -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -fcheck-pointe=
r-bounds -mmpx -fpic -fno-plt" } */
> +=20
> + void bar (char *);
> + char buf[10];
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/g=
cc/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=3Dkeep -mindirect-branch=3Dthunk=
-extern -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk-extern -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/g=
cc/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=3Dkeep -mindirect-branch=3Dthunk=
-extern -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk-extern -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/g=
cc/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=3Dkeep -mindirect-branch=3Dthunk=
-extern -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk-extern -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/g=
cc/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=3Dkeep -mindirect-branch=3Dthunk=
-extern -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk-extern -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/g=
cc/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=3Dkeep -fpic -fno-plt -mindirect=
-branch=3Dthunk-extern" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -fpic -fno-plt -mindirect-branch=3Dthunk-extern" } */
> +=20
> + extern void bar (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/g=
cc/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=3Dkeep -fpic -fno-plt -mindirect=
-branch=3Dthunk-extern" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -fpic -fno-plt -mindirect-branch=3Dthunk-extern" } */
> +=20
> + extern void bar (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/g=
cc/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=3Dkeep -mindirect-branch=3Dthunk=
-extern -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk-extern -fno-pic" } */
> +=20
> + void func0 (void);
> + void func1 (void);
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/g=
cc/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=3Dkeep -mindirect-branch=3Dthunk=
-inline -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk-inline -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/g=
cc/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=3Dkeep -mindirect-branch=3Dthunk=
-inline -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk-inline -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/g=
cc/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=3Dkeep -mindirect-branch=3Dthunk=
-inline -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk-inline -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/g=
cc/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=3Dkeep -mindirect-branch=3Dthunk=
-inline -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk-inline -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/g=
cc/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=3Dkeep -fpic -fno-plt -mindirect=
-branch=3Dthunk-inline" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */
> +=20
> + extern void bar (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/g=
cc/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=3Dkeep -fpic -fno-plt -mindirect=
-branch=3Dthunk-inline" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */
> +=20
> + extern void bar (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/g=
cc/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=3Dkeep -mindirect-branch=3Dthunk=
-inline -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk-inline -fno-pic" } */
> +=20
> + 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=3Dthunk -mindirect-branch-loop=
=3Dpause -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3D=
thunk -mindirect-branch-loop=3Dpause -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dthunk -mindirect-branch-loop=
=3Dnop -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3D=
thunk -mindirect-branch-loop=3Dnop -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dthunk -mindirect-branch-loop=
=3Dlfence -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3D=
thunk -mindirect-branch-loop=3Dlfence -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dthunk-inline -mindirect-branch=
-loop=3Dpause -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3D=
thunk-inline -mindirect-branch-loop=3Dpause -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +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=3Dthunk-extern -mindirect-branch=
-loop=3Dpause -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3D=
thunk-extern -mindirect-branch-loop=3Dpause -fno-pic" } */
> +=20
> + typedef void (*dispatch_t)(long offset);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuit=
e/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=3Dthunk-inline -mindirect-branch=
=3Dthunk -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch=
-register -mfunction-return=3Dthunk-inline -mindirect-branch=3Dthunk -fno-p=
ic" } */
> +=20
> + extern void (*bar) (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuit=
e/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=3Dthunk-extern -mindirect-branch=
=3Dthunk -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch=
-register -mno-indirect-branch-register -mno-indirect-branch-register -mfun=
ction-return=3Dthunk-extern -mindirect-branch=3Dthunk -fno-pic" } */
> +=20
> + extern void (*bar) (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuit=
e/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=3Dkeep -mindirect-branch=3Dthunk=
 -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch=
-register -mno-indirect-branch-register -mno-indirect-branch-register -mfun=
ction-return=3Dkeep -mindirect-branch=3Dthunk -fno-pic" } */
> +=20
> + extern void (*bar) (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuit=
e/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=3Dkeep -mindirect-branch=3Dthunk=
-inline -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk-inline -fno-pic" } */
> +=20
> + 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/testsuit=
e/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=3Dkeep -mindirect-branch=3Dthunk=
-extern -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3D=
keep -mindirect-branch=3Dthunk-extern -fno-pic" } */
> +=20
> + extern void (*bar) (void);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuit=
e/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=3Dkeep -mindirect-branch=3Dkeep =
-fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch=
-register -mno-indirect-branch-register -mno-indirect-branch-register -mfun=
ction-return=3Dkeep -mindirect-branch=3Dkeep -fno-pic" } */
> +=20
> + extern void (*bar) (void);
> +=20
> +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=3Dthunk -mindirect-branch=3Dthun=
k -fno-pic" } */
> ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch=
-register -mfunction-return=3Dthunk -mindirect-branch=3Dthunk -fno-pic" } */
> +=20
> + extern void (*bar) (void);
> +=20
> +--=20
> +2.15.1
> +
> diff --git a/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-b=
ranch-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-t=
hunk-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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@HIDDEN>
> +Date: Mon, 4 Dec 2017 12:58:20 -0800
> +Subject: [PATCH 05/17] Add tests for -mindirect-branch=3Dthunk
> + -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=3Dthunk -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=3Dthunk -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=3Dthunk -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)\[ \t\]*bar@GOT" } } */
> ++/* { 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=3Dthunk -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)\[ \t\]*bar@GOT" } } */
> ++/* { 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} } } */
> +--=20
> +2.15.1
> +
> diff --git a/gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-loc=
al-indirect-jump.patch b/gnu/packages/patches/gcc-retpoline-Disable-red-zon=
e-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-indi=
rect-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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@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
> +=20
> + 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 loa=
d,
> + 						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);
> + }
> +=20
> +-/* 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.  */
> +=20
> + 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 =3D=3D indirect_branch_ke=
ep));
> + }
> + 
> + /* Return a string that documents the current -m options.  The caller is
> +@@ -28919,11 +28926,16 @@ ix86_output_indirect_branch (rtx call_op, cons=
t char *xasm,
> + }
> +=20
> + const char *
> +-ix86_output_indirect_jmp (rtx call_op)
> ++ix86_output_indirect_jmp (rtx call_op, bool ret_p)
> + {
> +-  if (ix86_red_zone_size =3D=3D 0
> +-      && cfun->machine->indirect_branch_type !=3D indirect_branch_keep)
> ++  if (cfun->machine->indirect_branch_type !=3D 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 !=3D 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;
> +=20
> ++  /* 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;
> +=20
> +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] =3D convert_memory_address (word_mode, operands[0]);
> ++  cfun->machine->has_local_indirect_jump =3D true;
> + })
> +=20
> + (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 @@
> +=20
> +   if (TARGET_X32 || ix86_indirect_branch_thunk_register)
> +     operands[0] =3D convert_memory_address (word_mode, operands[0]);
> ++  cfun->machine->has_local_indirect_jump =3D true;
> + })
> +=20
> + (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")])
> +--=20
> +2.15.1
> +
> diff --git a/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_in=
direct_thunk_rax-etc.-to-re.patch b/gnu/packages/patches/gcc-retpoline-Rena=
me-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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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 <dwmw2@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 =3D TARGET_64BIT ? "r" : "e";
> + 	  else
> + 	    reg_prefix =3D "";
> +-	  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 =3D 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;
> +=20
> +-  /* 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 =3D build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
> + 		     get_identifier (name),
> +@@ -12165,7 +12165,7 @@ output_indirect_thunk_function (bool need_bnd_p,=
 int regno)
> +=20
> +   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];
> +=20
> +       indirect_thunk_name (alias, regno, need_bnd_p, true);
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/test=
suite/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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target=
 { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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/test=
suite/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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target=
 { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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/test=
suite/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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target=
 { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)=
ax" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a=
x" { 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/test=
suite/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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target=
 { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)=
ax" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a=
x" { 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/test=
suite/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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> +-/* { 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/test=
suite/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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> +-/* { 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/test=
suite/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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { =
target { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target=
 { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target=
 { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)=
ax" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a=
x" { 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" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)=
ax" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a=
x" { 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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { =
target { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { 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)
> +     }
> + }
> +=20
> +-/* { 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)
> +=20
> + /* { 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)
> +=20
> + /* { 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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> +-/* { 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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> +-/* { 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/g=
cc/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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target=
 { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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/g=
cc/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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target=
 { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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/g=
cc/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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target=
 { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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)a=
x" { target x32 } } } */
> + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/g=
cc/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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target=
 { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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)a=
x" { target x32 } } } */
> + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/g=
cc/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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> +-/* { 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/g=
cc/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)\[ \t\]*bar@GOT" } } */
> + /* { 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/g=
cc/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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { =
target { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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/g=
cc/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/g=
cc/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/g=
cc/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/g=
cc/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/g=
cc/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)\[ \t\]*bar@GOT" } } */
> + /* { 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/g=
cc/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)\[ \t\]*bar@GOT" } } */
> + /* { 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/g=
cc/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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target=
 { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target=
 { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target=
 { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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)
> + }
> +=20
> + /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target=
 { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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);
> + }
> +=20
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" } } */
> ++/* { 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);
> + }
> +=20
> +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" } } */
> ++/* { 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)
> + {
> + }
> +=20
> +-/* { 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/testsuit=
e/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)
> +=20
> + /* { 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" { targ=
et { ! 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:" { targe=
t { x32 } }  } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! x32 } }  } } */
> ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32=
 } }  } } */
> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a=
x" { 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/testsuit=
e/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;
> + }
> +=20
> +-/* { 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" { targ=
et { ! 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:" { targe=
t { x32 } }  } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32=
 } }  } } */
> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a=
x" { 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/testsuit=
e/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;
> + }
> +=20
> +-/* { 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" { targ=
et { ! 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:" { targe=
t { x32 } }  } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32=
 } }  } } */
> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a=
x" { 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/testsuit=
e/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;
> + }
> +=20
> +-/* { 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/testsuit=
e/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)
> + }
> +=20
> + /* { 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" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)=
ax" { target { x32 } }  } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a=
x" { 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/testsuit=
e/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;
> + }
> +=20
> +-/* { 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" { targ=
et { ! x32 } } } } */
> +-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)=
ax" { target x32 } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)a=
x" { 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/testsuit=
e/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;
> + }
> +=20
> +-/* { 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)
> + {
> + }
> +=20
> +-/* { 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)
> + {
> + }
> +=20
> +-/* { 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)
> + {
> + }
> +=20
> +-/* { 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)
> + {
> + }
> +=20
> +-/* { 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)
> + {
> + }
> +=20
> +-/* { 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;
> + }
> +=20
> +-/* { 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" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { targ=
et { ! 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)a=
x" { target { x32 } } } } */
> + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } =
} */
> +--=20
> +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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@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 =3D false;
> + static bool indirect_thunk_bnd_needed =3D false;
> +=20
> ++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 =3D fals=
e;
> + /* Fills in the label name that should be used for the indirect thunk. =
 */
> +=20
> + 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 =3D need_bnd_p ? "_bnd" : "";
> +-      sprintf (name, "__x86.indirect_thunk%s", bnd);
> ++      if (regno >=3D 0)
> ++	{
> ++	  const char *reg_prefix;
> ++	  if (LEGACY_INT_REGNO_P (regno))
> ++	    reg_prefix =3D TARGET_64BIT ? "r" : "e";
> ++	  else
> ++	    reg_prefix =3D "";
> ++	  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 >=3D 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);
> ++	}
> +     }
> + }
> +=20
> + 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)
> +=20
> +   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
> +=20
> +-  /* LEA.  */
> +-  rtx xops[2];
> +-  xops[0] =3D stack_pointer_rtx;
> +-  xops[1] =3D plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
> +-  output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);
> ++  if (regno >=3D 0)
> ++    {
> ++      /* MOV.  */
> ++      rtx xops[2];
> ++      xops[0] =3D gen_rtx_MEM (word_mode, stack_pointer_rtx);
> ++      xops[1] =3D gen_rtx_REG (word_mode, regno);
> ++      output_asm_insn ("mov\t{%1, %0|%0, %1}", xops);
> ++    }
> ++  else
> ++    {
> ++      /* LEA.  */
> ++      rtx xops[2];
> ++      xops[0] =3D stack_pointer_rtx;
> ++      xops[1] =3D plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WO=
RD);
> ++      output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);
> ++    }
> +=20
> +   if (need_bnd_p)
> +     fputs ("\tbnd ret\n", asm_out_file);
> +@@ -12015,12 +12050,13 @@ output_indirect_thunk (bool need_bnd_p)
> + }
> +=20
> + 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;
> +=20
> +-  indirect_thunk_name (name, need_bnd_p);
> ++  /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd.  */
> ++  indirect_thunk_name (name, regno, need_bnd_p);
> +   decl =3D 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);
> +=20
> +-  output_indirect_thunk (need_bnd_p);
> ++  output_indirect_thunk (need_bnd_p, regno);
> +=20
> +   final_end_function ();
> +   init_insn_lengths ();
> +@@ -12110,15 +12146,31 @@ ix86_code_end (void)
> +   int regno;
> +=20
> +   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 =3D FIRST_REX_INT_REG; regno <=3D LAST_REX_INT_REG; regno+=
+)
> ++    {
> ++      int i =3D 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);
> ++    }
> +=20
> +   for (regno =3D AX_REG; regno <=3D SP_REG; regno++)
> +     {
> +       char name[32];
> +       tree decl;
> +=20
> ++      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;
> +=20
> +@@ -28639,17 +28691,37 @@ ix86_output_indirect_branch (rtx call_op, cons=
t char *xasm,
> +   char *thunk_name;
> +   char push_buf[64];
> +   bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn);
> ++  int regno;
> ++
> ++  if (REG_P (call_op))
> ++    regno =3D REGNO (call_op);
> ++  else
> ++    regno =3D -1;
> +=20
> +   if (cfun->machine->indirect_branch_type
> +       !=3D indirect_branch_thunk_inline)
> +     {
> +-      bool need_thunk
> +-	=3D cfun->machine->indirect_branch_type =3D=3D indirect_branch_thunk;
> +-      if (need_bnd_p)
> +-	indirect_thunk_bnd_needed |=3D need_thunk;
> +-      else
> +-	indirect_thunk_needed |=3D need_thunk;
> +-      indirect_thunk_name (thunk_name_buf, need_bnd_p);
> ++      if (cfun->machine->indirect_branch_type =3D=3D indirect_branch_th=
unk)
> ++	{
> ++	  if (regno >=3D 0)
> ++	    {
> ++	      int i =3D regno;
> ++	      if (i >=3D FIRST_REX_INT_REG)
> ++		i -=3D (FIRST_REX_INT_REG - LAST_INT_REG - 1);
> ++	      if (need_bnd_p)
> ++		indirect_thunks_bnd_used |=3D 1 << i;
> ++	      else
> ++		indirect_thunks_used |=3D 1 << i;
> ++	    }
> ++	  else
> ++	    {
> ++	      if (need_bnd_p)
> ++		indirect_thunk_bnd_needed =3D true;
> ++	      else
> ++		indirect_thunk_needed =3D true;
> ++	    }
> ++	}
> ++      indirect_thunk_name (thunk_name_buf, regno, need_bnd_p);
> +       thunk_name =3D thunk_name_buf;
> +     }
> +   else
> +@@ -28660,7 +28732,8 @@ ix86_output_indirect_branch (rtx call_op, const =
char *xasm,
> +=20
> +   if (sibcall_p)
> +     {
> +-      output_asm_insn (push_buf, &call_op);
> ++      if (regno < 0)
> ++	output_asm_insn (push_buf, &call_op);
> +       if (thunk_name !=3D NULL)
> + 	{
> + 	  if (need_bnd_p)
> +@@ -28669,10 +28742,19 @@ ix86_output_indirect_branch (rtx call_op, cons=
t 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 >=3D 0 && thunk_name !=3D 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];
> +=20
> +@@ -28725,7 +28807,8 @@ ix86_output_indirect_branch (rtx call_op, const =
char *xasm,
> + 	    }
> + 	}
> +=20
> +-      output_asm_insn (push_buf, &call_op);
> ++      if (regno < 0)
> ++	output_asm_insn (push_buf, &call_op);
> +=20
> +       if (thunk_name !=3D 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);
> +=20
> +       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
> +=20
> +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/test=
suite/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)
> + }
> +=20
> + /* { 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" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { 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/test=
suite/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)
> + }
> +=20
> + /* { 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" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { 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/test=
suite/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)
> + }
> +=20
> + /* { 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" { targ=
et { ! 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/test=
suite/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)
> + }
> +=20
> + /* { 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" { targ=
et { ! 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/test=
suite/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)
> + }
> +=20
> + /* { 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" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { 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)
> + }
> +=20
> + /* { 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" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { 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)
> + }
> +=20
> + /* { 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" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { 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)
> + }
> +=20
> + /* { 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)
> + }
> +=20
> + /* { 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)
> + }
> +=20
> + /* { 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" { targ=
et { ! 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)
> + }
> +=20
> + /* { 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" { targ=
et { ! 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)
> + }
> +=20
> + /* { 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)a=
x" { 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/g=
cc/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)
> + }
> +=20
> + /* { 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" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { 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/g=
cc/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)
> + }
> +=20
> + /* { 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" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { 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/g=
cc/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)
> + }
> +=20
> + /* { 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" { targ=
et { ! 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/g=
cc/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)
> + }
> +=20
> + /* { 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" { targ=
et { ! 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/g=
cc/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)
> + }
> +=20
> + /* { 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" { targ=
et { ! x32 } } } } */
> ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)a=
x" { 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/g=
cc/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)
> + }
> +=20
> + /* { 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/g=
cc/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)
> + }
> +=20
> + /* { 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/g=
cc/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)
> + }
> +=20
> + /* { 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/g=
cc/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)
> + }
> +=20
> + /* { 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/g=
cc/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)
> + }
> +=20
> + /* { 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" } } */
> +--=20
> +2.15.1
> +
> diff --git a/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-opera=
nd-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-modi=
fier.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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@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 o=
p.
> +    If CODE is 'd', duplicate the operand for AVX instruction.
> ++   If CODE is 'V', print naked register name without %.
> +  */
> +=20
> + void
> +@@ -17896,7 +17897,7 @@ print_reg (rtx x, int code, FILE *file)
> +   unsigned int regno;
> +   bool duplicated;
> +=20
> +-  if (ASSEMBLER_DIALECT =3D=3D ASM_ATT)
> ++  if (ASSEMBLER_DIALECT =3D=3D ASM_ATT && code !=3D 'V')
> +     putc ('%', file);
> +=20
> +   if (x =3D=3D 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;
> +=20
> + 	case 's':
> +--=20
> +2.15.1
> +
> diff --git a/gnu/packages/patches/gcc-retpoline-i386-More-use-reference-o=
f-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-struc=
t-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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@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 =3D 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 =3D true;
> +=20
> +   ix86_compute_frame_layout ();
> +-  frame =3D m->frame;
> ++  struct ix86_frame &frame =3D cfun->machine->frame;
> +=20
> +   if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function=
_decl))
> +     {
> +@@ -14343,13 +14342,12 @@ ix86_expand_epilogue (int style)
> + {
> +   struct machine_function *m =3D cfun->machine;
> +   struct machine_frame_state frame_state_save =3D m->fs;
> +-  struct ix86_frame frame;
> +   bool restore_regs_via_mov;
> +   bool using_drap;
> +=20
> +   ix86_finalize_stack_realign_flags ();
> +   ix86_compute_frame_layout ();
> +-  frame =3D m->frame;
> ++  struct ix86_frame &frame =3D cfun->machine->frame;
> +=20
> +   m->fs.sp_valid =3D (!frame_pointer_needed
> + 		    || (crtl->sp_is_unchanging
> +--=20
> +2.15.1
> +
> diff --git a/gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_fra=
me-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-m=
achine_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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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" <hjl.tools@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;
> + };
> +=20
> +-/* 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]	       | =3D 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;
> +=20
> +@@ -2579,7 +2532,7 @@ static unsigned int ix86_function_arg_boundary (ma=
chine_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 >=3D 32768)
> +     return 0;
> +=20
> +-  ix86_compute_frame_layout (&frame);
> ++  ix86_compute_frame_layout ();
> ++  frame =3D cfun->machine->frame;
> +   return (frame.stack_pointer_offset =3D=3D UNITS_PER_WORD
> + 	  && (frame.nregs + frame.nsseregs) =3D=3D 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 =3D cfun->machine->frame;
> +=20
> +   if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME_POINTER_RE=
GNUM)
> +     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=
.  */
> +=20
> + static void
> +-ix86_compute_frame_layout (struct ix86_frame *frame)
> ++ix86_compute_frame_layout (void)
> + {
> ++  struct ix86_frame *frame =3D &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 =3D INCOMING_FRAME_SP_OFFSET;
> +   m->fs.sp_valid =3D true;
> +=20
> +-  ix86_compute_frame_layout (&frame);
> ++  ix86_compute_frame_layout ();
> ++  frame =3D m->frame;
> +=20
> +   if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function=
_decl))
> +     {
> +@@ -14394,7 +14350,8 @@ ix86_expand_epilogue (int style)
> +   bool using_drap;
> +=20
> +   ix86_finalize_stack_realign_flags ();
> +-  ix86_compute_frame_layout (&frame);
> ++  ix86_compute_frame_layout ();
> ++  frame =3D m->frame;
> +=20
> +   m->fs.sp_valid =3D (!frame_pointer_needed
> + 		    || (crtl->sp_is_unchanging
> +@@ -14904,7 +14861,8 @@ ix86_expand_split_stack_prologue (void)
> +   gcc_assert (flag_split_stack && reload_completed);
> +=20
> +   ix86_finalize_stack_realign_flags ();
> +-  ix86_compute_frame_layout (&frame);
> ++  ix86_compute_frame_layout ();
> ++  frame =3D cfun->machine->frame;
> +   allocate =3D frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
> +=20
> +   /* 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]	       | =3D 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.=
  */
> +=20
> +-#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];
> +=20
> ++  /* 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 (S=
P_REG))
> + #define ix86_static_chain_on_stack (cfun->machine->static_chain_on_stac=
k)
> ++#define ix86_red_zone_size (cfun->machine->frame.red_zone_size)
> +=20
> + /* Control behavior of x86_file_start.  */
> + #define X86_FILE_START_VERSION_DIRECTIVE false
> +--=20
> +2.15.1
> +
> diff --git a/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-str=
uct-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-ix8=
6_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-f=
or-cpu_4.html
> +https://support.google.com/faqs/answer/7625886
> +https://spectreattack.com/
> +https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2017-5715
> +
> +Patch copied from the 'retpoline-20180107' branch of upstream source rep=
ository
> +(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 <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
> +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/trunk@254480 138bc75d-0d04-041=
0-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;
> +=20
> +   ix86_compute_frame_layout ();
> +-  frame =3D cfun->machine->frame;
> ++  struct ix86_frame &frame =3D cfun->machine->frame;
> +   return (frame.stack_pointer_offset =3D=3D UNITS_PER_WORD
> + 	  && (frame.nregs + frame.nsseregs) =3D=3D 0);
> + }
> +@@ -12333,7 +12331,7 @@ HOST_WIDE_INT
> + ix86_initial_elimination_offset (int from, int to)
> + {
> +   ix86_compute_frame_layout ();
> +-  struct ix86_frame frame =3D cfun->machine->frame;
> ++  struct ix86_frame &frame =3D cfun->machine->frame;
> +=20
> +   if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME_POINTER_RE=
GNUM)
> +     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)
> +=20
> +   ix86_finalize_stack_realign_flags ();
> +   ix86_compute_frame_layout ();
> +-  frame =3D cfun->machine->frame;
> ++  struct ix86_frame &frame =3D cfun->machine->frame;
> +   allocate =3D frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
> +=20
> +   /* This is the label we will branch to if we have enough stack
> +--=20
> +2.15.1
> +




Information forwarded to guix-patches@HIDDEN:
bug#30111; Package guix-patches. Full text available.
Changed bug title to '[PATCH] gnu: gcc@7: Apply the 'retpoline' mitigation technique.' from 'gnu: gcc@7: Apply the 'retpoline' mitigation technique.' Request was from Alex Vong <alexvong1995@HIDDEN> to control <at> debbugs.gnu.org. Full text available.
Added tag(s) patch and security. Request was from Alex Vong <alexvong1995@HIDDEN> to control <at> debbugs.gnu.org. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 14 Jan 2018 13:09:03 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sun Jan 14 08:09:03 2018
Received: from localhost ([127.0.0.1]:55439 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1eai22-0000jb-TA
	for submit <at> debbugs.gnu.org; Sun, 14 Jan 2018 08:09:02 -0500
Received: from eggs.gnu.org ([208.118.235.92]:43900)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <alexvong1995@HIDDEN>) id 1eai21-0000j5-5v
 for submit <at> debbugs.gnu.org; Sun, 14 Jan 2018 08:09:01 -0500
Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
 (envelope-from <alexvong1995@HIDDEN>) id 1eai1V-0005Wh-8E
 for submit <at> debbugs.gnu.org; Sun, 14 Jan 2018 08:08:56 -0500
X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org
X-Spam-Level: *
X-Spam-Status: No, score=1.1 required=5.0 tests=BAYES_50,
 FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,T_DKIM_INVALID autolearn=disabled
 version=3.3.2
Received: from lists.gnu.org ([2001:4830:134:3::11]:32792)
 by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
 (Exim 4.71) (envelope-from <alexvong1995@HIDDEN>)
 id 1eai1U-0005Vc-4w
 for submit <at> debbugs.gnu.org; Sun, 14 Jan 2018 08:08:29 -0500
Received: from eggs.gnu.org ([2001:4830:134:3::10]:34754)
 by lists.gnu.org with esmtp (Exim 4.71)
 (envelope-from <alexvong1995@HIDDEN>) id 1eai13-0000ZH-4u
 for guix-patches@HIDDEN; Sun, 14 Jan 2018 08:08:27 -0500
Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
 (envelope-from <alexvong1995@HIDDEN>) id 1eai0a-0004mk-VF
 for guix-patches@HIDDEN; Sun, 14 Jan 2018 08:08:01 -0500
Received: from mail-pf0-x22c.google.com ([2607:f8b0:400e:c00::22c]:37772)
 by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16)
 (Exim 4.71) (envelope-from <alexvong1995@HIDDEN>)
 id 1eai0Z-0004lL-6d
 for guix-patches@HIDDEN; Sun, 14 Jan 2018 08:07:32 -0500
Received: by mail-pf0-x22c.google.com with SMTP id p1so6890605pfh.4
 for <guix-patches@HIDDEN>; Sun, 14 Jan 2018 05:07:30 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:subject:date:message-id:user-agent:mime-version;
 bh=pl3/n3YyJ/Il7XlsKVujC2Wl66yxNWYNKnIbJnOUoAo=;
 b=SACf7gB79AN1nv10ieHBWGlClbBMf4Gmi6k6ocqXe1+uTk+dkQvtKuq22lDsqE0OmO
 p6+4vVOHrj0ODNnvfrOM648ru1o3rs65ESMe9P8/j0ANMwaHJxOWhdToBKUJpKgvPXib
 Sml3pc4Lm5A6ReS12my+Ygkd3LX7+kGbmHMv9pM4UJZvvrN6e8mqfyLyzz3F6rPt5dwM
 RMf21fpGreON0z9aRRxi6gheDRbi2HFjzmY+BlL4U3qwUQtt0sjhpYYPdjtQHraNLA8z
 3tnxOU0breRSttpWJOt1XnNni2G3iwCC0d33gG+qqiVkg78AGuEH11VAUL6bUDrhXjnT
 rAIA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:subject:date:message-id:user-agent
 :mime-version;
 bh=pl3/n3YyJ/Il7XlsKVujC2Wl66yxNWYNKnIbJnOUoAo=;
 b=gk6TyhiXew2mU9xXjT4WZ0pF6BnU1Yq3TPX3JoyzlDhfuqTeHA5fG35N4EKevhNE6n
 C1YmR8cC4ItLJsWO+diosufv/K/6H7JcV+PfM1sM/zDem1fdJFRgtrjCrW22JeCEqK9N
 o/FuZc1JnEXm/WPYG4Rsw5d0ppHZDiAT4rfx7Qbiu/YjFpFL8UBNyfzEi1qMYh7NOGxo
 j3gGgi0KgInDRqd1oTpkUBmX9j8s7iC171vWievzCTFydqx9/hpHwNSUPrWj2HKbTupk
 LQ+e267IByE0tOfiC1mY+jAN0r6LTwYgooeoNol6+dRba4rEehMbkTs7+oIa7hETiEJE
 jyhQ==
X-Gm-Message-State: AKGB3mIcgDn5CfTAfwhFGqUM5kWoQjdWqCs6EmtGpMpOPmDQZK6NIbgz
 +9Zrw2h0NwfW/40R6y1yHBI=
X-Google-Smtp-Source: ACJfBoshrrPicVx45N6RNrwbPDPnLPmMDaqjtAZb2ZCal8ZLGWfjmlIQUaaSoct5ZP5t1h8vPCPBBw==
X-Received: by 10.98.204.144 with SMTP id j16mr24208277pfk.101.1515935250179; 
 Sun, 14 Jan 2018 05:07:30 -0800 (PST)
Received: from debian (n218103180243.netvigator.com. [218.103.180.243])
 by smtp.gmail.com with ESMTPSA id d24sm27329615pfb.30.2018.01.14.05.07.26
 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);
 Sun, 14 Jan 2018 05:07:28 -0800 (PST)
From: Alex Vong <alexvong1995@HIDDEN>
To: guix-patches@HIDDEN
Subject: gnu: gcc@7: Apply the 'retpoline' mitigation technique.
Date: Sun, 14 Jan 2018 21:07:17 +0800
Message-ID: <877esksi62.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-detected-operating-system: by eggs.gnu.org: Genre and OS details not
 recognized.
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x
X-Received-From: 2001:4830:134:3::11
X-Debbugs-Envelope-To: submit
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>

--=-=-=
Content-Type: text/plain

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 gcc@7.

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.


--=-=-=
Content-Type: text/x-diff; charset=utf-8
Content-Disposition: inline;
 filename=0001-gnu-gcc-7-Apply-the-retpoline-mitigation-technique.patch
Content-Transfer-Encoding: quoted-printable

From 5be54f7ebe9b0ab6dc65ea974584be0850604b14 Mon Sep 17 00:00:00 2001
From: Alex Vong <alexvong1995@HIDDEN>
Date: Sun, 14 Jan 2018 20:12:19 +0800
Subject: [PATCH] gnu: gcc@7: Apply the 'retpoline' mitigation technique.

This is part of Spectre (branch target injection) [CVE-2017-5715]
mitigation. Suggested by Mark H Weaver <mhw@HIDDEN>.

* gnu/local.mk (dist_patch_DATA): Add them.
* gnu/packages/gcc.scm (gcc@7): Use them.
* gnu/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-tes=
ts.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-br=
anch-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-indi=
rect-branch-.patch,
gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-branch-thunk-fch=
eck-pointer-.patch,
gnu/packages/patches/gcc-retpoline-Disable-red-zone-with-local-indirect-jum=
p.patch,
gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indirect_thunk_ra=
x-etc.-to-re.patch,
gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indirec=
t-branch-via.patch,
gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifier.pat=
ch,
gnu/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix86_f=
rame-to-avoi.patch,
gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix86_frame-to-machine_f=
unction.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-bra=
nch-register-to-indirect-branch-.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-Add-tests-for-mindir=
ect-branch-thunk-fcheck-pointer-.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-Disable-red-zone-wit=
h-local-indirect-jump.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x=
86_indirect_thunk_rax-etc.-to-re.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_t=
hunk.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-refere=
nce-of-struct-ix86_frame-to-avoi.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Move-struct-ix8=
6_frame-to-machine_function.patch
 create mode 100644 gnu/packages/patches/gcc-retpoline-i386-Use-reference-o=
f-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 =C2=A9 2016 Adonay "adfeno" Felipe Nogueira <https://libreplan=
et.org/wiki/User:Adfeno> <adfeno@HIDDEN>
 # Copyright =C2=A9 2016, 2017 Ricardo Wurmus <rekado@HIDDEN>
 # Copyright =C2=A9 2016 Ben Woodcroft <donttrustben@HIDDEN>
-# Copyright =C2=A9 2016, 2017 Alex Vong <alexvong1995@HIDDEN>
+# Copyright =C2=A9 2016, 2017, 2018 Alex Vong <alexvong1995@HIDDEN>
 # Copyright =C2=A9 2016, 2017 Efraim Flashner <efraim@HIDDEN>
 # Copyright =C2=A9 2016, 2017 Jan Nieuwenhuizen <janneke@HIDDEN>
 # Copyright =C2=A9 2017 Tobias Geerinckx-Rice <me@HIDDEN>
@@ -652,6 +652,23 @@ dist_patch_DATA =3D						\
   %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-machin=
e_function.patch	\
+  %D%/packages/patches/gcc-retpoline-i386-Use-reference-of-struct-ix86_fra=
me-to-avoid-cop.patch	\
+  %D%/packages/patches/gcc-retpoline-i386-More-use-reference-of-struct-ix8=
6_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.pat=
ch	\
+  %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-thunk-extern.pat=
ch	\
+  %D%/packages/patches/gcc-retpoline-Add-indirect_branch-attribute-with-te=
sts.patch	\
+  %D%/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.reg-for-indi=
rect-branch-via.patch	\
+  %D%/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.patch	\
+  %D%/packages/patches/gcc-retpoline-Add-mfunction-return-and-function_ret=
urn-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-tes=
ts.patch	\
+  %D%/packages/patches/gcc-retpoline-Add-mno-indirect-branch-register-to-i=
ndirect-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 =C2=A9 2015 Andreas Enge <andreas@HIDDEN>
 ;;; Copyright =C2=A9 2015, 2016, 2017 Efraim Flashner <efraim@HIDDEN=
il>
 ;;; Copyright =C2=A9 2016 Carlos S=C3=A1nchez de La Lama <csanchezdll@gmai=
l.com>
+;;; Copyright =C2=A9 2018 ALex Vong <alexvong1995@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -427,7 +428,24 @@ Go.  It also includes runtime support libraries for th=
ese 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-ix8=
6_frame-to-machine_function.patch"
+                                       "gcc-retpoline-i386-Use-reference-o=
f-struct-ix86_frame-to-avoid-cop.patch"
+                                       "gcc-retpoline-i386-More-use-refere=
nce-of-struct-ix86_frame-to-avoi.patch"
+                                       "gcc-retpoline-Add-mindirect-branch=
-thunk.patch"
+                                       "gcc-retpoline-Add-tests-for-mindir=
ect-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_t=
hunk.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-bra=
nch-register-to-indirect-branch-.patch"
+                                       "gcc-retpoline-Disable-red-zone-wit=
h-local-indirect-jump.patch"
+                                       "gcc-retpoline-i386-Add-V-register-=
operand-modifier.patch"
+                                       "gcc-retpoline-Rename-thunks-to-__x=
86_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-attribu=
te-with-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-indirect_branc=
h-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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From e9794727bb0384be6d27ad1edaefc71c23cc0d86 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@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 {
+ };
+=20
+ enum indirect_branch {
++  indirect_branch_unset =3D 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)
+     }
+ }
+=20
++/* 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 =3D=3D indirect_branch_unset)
++    {
++      tree attr =3D lookup_attribute ("indirect_branch",
++				    DECL_ATTRIBUTES (fndecl));
++      if (attr !=3D NULL)
++	{
++	  tree args =3D TREE_VALUE (attr);
++	  if (args =3D=3D NULL)
++	    gcc_unreachable ();
++	  tree cst =3D TREE_VALUE (args);
++	  if (strcmp (TREE_STRING_POINTER (cst), "keep") =3D=3D 0)
++	    cfun->machine->indirect_branch_type =3D indirect_branch_keep;
++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk") =3D=3D 0)
++	    cfun->machine->indirect_branch_type =3D indirect_branch_thunk;
++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") =3D=3D 0)
++	    cfun->machine->indirect_branch_type =3D indirect_branch_thunk_inline;
++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") =3D=3D 0)
++	    cfun->machine->indirect_branch_type =3D indirect_branch_thunk_extern;
++	  else
++	    gcc_unreachable ();
++	}
++      else
++	cfun->machine->indirect_branch_type =3D 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 !=3D NULL_TREE)
+-	ix86_set_func_type (fndecl);
++	{
++	  ix86_set_func_type (fndecl);
++	  ix86_set_indirect_branch_type (fndecl);
++	}
+       return;
+     }
+=20
+@@ -7172,6 +7206,7 @@ ix86_set_current_function (tree fndecl)
+     }
+=20
+   ix86_set_func_type (fndecl);
++  ix86_set_indirect_branch_type (fndecl);
+=20
+   tree new_tree =3D DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+   if (new_tree =3D=3D NULL_TREE)
+@@ -28605,9 +28640,11 @@ ix86_output_indirect_branch (rtx call_op, const c=
har *xasm,
+   char push_buf[64];
+   bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn);
+=20
+-  if (ix86_indirect_branch !=3D indirect_branch_thunk_inline)
++  if (cfun->machine->indirect_branch_type
++      !=3D indirect_branch_thunk_inline)
+     {
+-      bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thu=
nk;
++      bool need_thunk
++	=3D cfun->machine->indirect_branch_type =3D=3D indirect_branch_thunk;
+       if (need_bnd_p)
+ 	indirect_thunk_bnd_needed |=3D need_thunk;
+       else
+@@ -28716,7 +28753,7 @@ const char *
+ ix86_output_indirect_jmp (rtx call_op)
+ {
+   if (ix86_red_zone_size =3D=3D 0
+-      && ix86_indirect_branch !=3D indirect_branch_keep)
++      && cfun->machine->indirect_branch_type !=3D 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 =3D constant_call_address_operand (call_op, VOIDmode);
+   bool output_indirect_p
+     =3D (!TARGET_SEH
+-       && ix86_indirect_branch !=3D indirect_branch_keep);
++       && cfun->machine->indirect_branch_type !=3D indirect_branch_keep);
+   bool seh_nop_p =3D false;
+   const char *xasm;
+=20
+@@ -41749,7 +41786,7 @@ ix86_handle_struct_attribute (tree *node, tree nam=
e, tree, int,
+ }
+=20
+ 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) !=3D FUNCTION_DECL)
+@@ -41758,6 +41795,29 @@ ix86_handle_fndecl_attribute (tree *node, tree na=
me, tree, int,
+                name);
+       *no_add_attrs =3D true;
+     }
++
++  if (is_attribute_p ("indirect_branch", name))
++    {
++      tree cst =3D TREE_VALUE (args);
++      if (TREE_CODE (cst) !=3D STRING_CST)
++	{
++	  warning (OPT_Wattributes,
++		   "%qE attribute requires a string constant argument",
++		   name);
++	  *no_add_attrs =3D true;
++	}
++      else if (strcmp (TREE_STRING_POINTER (cst), "keep") !=3D 0
++	       && strcmp (TREE_STRING_POINTER (cst), "thunk") !=3D 0
++	       && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") !=3D 0
++	       && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") !=3D 0)
++	{
++	  warning (OPT_Wattributes,
++		   "argument to %qE attribute is not "
++		   "(keep|thunk|thunk-inline|thunk-extern)", name);
++	  *no_add_attrs =3D true;
++	}
++    }
++
+   return NULL_TREE;
+ }
+=20
+@@ -46052,6 +46112,8 @@ static const struct attribute_spec ix86_attribute_=
table[] =3D
+     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 },
+=20
+   /* 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;
+=20
++  /* 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/t=
estsuite/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/t=
estsuite/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/t=
estsuite/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/t=
estsuite/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/t=
estsuite/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/t=
estsuite/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/t=
estsuite/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\]+\\(,%" { ta=
rget { ! 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/t=
estsuite/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=3Dthunk -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" } } */
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-and-fu=
nction_return-attribute.patch b/gnu/packages/patches/gcc-retpoline-Add-mfun=
ction-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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 29d5a3f23c18c96944dd3230a41380a6edcd25fd Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Tue, 5 Dec 2017 13:29:06 -0800
+Subject: [PATCH 11/17] Add -mfunction-return=3D and function_return attrib=
ute
+
+Add -mfunction-return=3D and function_return attribute tests
+
+-mfunction-return=3Dthunk
+  Convert function return instruction to PC-relative call thunk.
+-mfunction-return=3Dthunk-inline
+  Convert function return instruction to PC-relative call thunk with
+  thunk inlined.
+-mfunction-return=3Dthunk-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;
+=20
+ 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);
+=20
+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 =3D ix86_indirect_branch;
+     }
++
++  if (cfun->machine->function_return_type =3D=3D indirect_branch_unset)
++    {
++      tree attr =3D lookup_attribute ("function_return",
++				    DECL_ATTRIBUTES (fndecl));
++      if (attr !=3D NULL)
++	{
++	  tree args =3D TREE_VALUE (attr);
++	  if (args =3D=3D NULL)
++	    gcc_unreachable ();
++	  tree cst =3D TREE_VALUE (args);
++	  if (strcmp (TREE_STRING_POINTER (cst), "keep") =3D=3D 0)
++	    cfun->machine->function_return_type =3D indirect_branch_keep;
++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk") =3D=3D 0)
++	    cfun->machine->function_return_type =3D indirect_branch_thunk;
++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") =3D=3D 0)
++	    cfun->machine->function_return_type =3D indirect_branch_thunk_inline;
++	  else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") =3D=3D 0)
++	    cfun->machine->function_return_type =3D indirect_branch_thunk_extern;
++	  else
++	    gcc_unreachable ();
++	}
++      else
++	cfun->machine->function_return_type =3D ix86_function_return;
++    }
+ }
+=20
+ /* 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.  */
+=20
+ 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 >=3D 0 && ret_p)
++    gcc_unreachable ();
++
+   if (USE_HIDDEN_LINKONCE)
+     {
+       const char *bnd =3D need_bnd_p ? "_bnd" : "";
+@@ -11974,7 +12003,10 @@ indirect_thunk_name (char name[32], int regno, bo=
ol need_bnd_p)
+ 		   bnd, reg_prefix, reg_names[regno]);
+ 	}
+       else
+-	sprintf (name, "__x86.indirect_thunk%s", bnd);
++	{
++	  const char *ret =3D 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, b=
ool 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, i=
nt regno)
+   tree decl;
+=20
+   /* 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 =3D 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);
+       }
+=20
++  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) =3D make_node (BLOCK);
+   current_function_decl =3D decl;
+   allocate_struct_function (decl, false);
+@@ -28736,7 +28807,7 @@ ix86_output_indirect_branch (rtx call_op, const ch=
ar *xasm,
+ 		indirect_thunk_needed =3D true;
+ 	    }
+ 	}
+-      indirect_thunk_name (thunk_name_buf, regno, need_bnd_p);
++      indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false);
+       thunk_name =3D thunk_name_buf;
+     }
+   else
+@@ -28860,6 +28931,43 @@ ix86_output_indirect_jmp (rtx call_op)
+     return "%!jmp\t%A0";
+ }
+=20
++const char *
++ix86_output_function_return (bool long_p)
++{
++  if (cfun->machine->function_return_type !=3D indirect_branch_keep)
++    {
++      char thunk_name[32];
++      bool need_bnd_p =3D ix86_bnd_prefixed_insn_p (current_output_insn);
++
++      if (cfun->machine->function_return_type
++	  !=3D indirect_branch_thunk_inline)
++	{
++	  bool need_thunk =3D (cfun->machine->function_return_type
++			     =3D=3D indirect_branch_thunk);
++	  indirect_thunk_name (thunk_name, -1, need_bnd_p, true);
++	  if (need_bnd_p)
++	    {
++	      indirect_thunk_bnd_needed |=3D need_thunk;
++	      fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
++	    }
++	  else
++	    {
++	      indirect_thunk_needed |=3D 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.  */
+=20
+ const char *
+@@ -41916,6 +42024,28 @@ ix86_handle_fndecl_attribute (tree *node, tree na=
me, tree args, int,
+ 	}
+     }
+=20
++  if (is_attribute_p ("function_return", name))
++    {
++      tree cst =3D TREE_VALUE (args);
++      if (TREE_CODE (cst) !=3D STRING_CST)
++	{
++	  warning (OPT_Wattributes,
++		   "%qE attribute requires a string constant argument",
++		   name);
++	  *no_add_attrs =3D true;
++	}
++      else if (strcmp (TREE_STRING_POINTER (cst), "keep") !=3D 0
++	       && strcmp (TREE_STRING_POINTER (cst), "thunk") !=3D 0
++	       && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") !=3D 0
++	       && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") !=3D 0)
++	{
++	  warning (OPT_Wattributes,
++		   "argument to %qE attribute is not "
++		   "(keep|thunk|thunk-inline|thunk-extern)", name);
++	  *no_add_attrs =3D true;
++	}
++    }
++
+   return NULL_TREE;
+ }
+=20
+@@ -46212,6 +46342,8 @@ static const struct attribute_spec ix86_attribute_=
table[] =3D
+     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 },
+=20
+   /* 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;
+=20
++  /* 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=3D
+ Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indire=
ct_branch) Init(indirect_branch_keep)
+ Update indirect call and jump.
+=20
++mfunction-return=3D
++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_functi=
on_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=3D opti=
on):
++Known indirect branch choices (for use with the -mindirect-branch=3D/-mfu=
nction-return=3D options):
+=20
+ 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/g=
cc.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=3Dthunk" } */
++
++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=3Dthunk-inline -mindirect-branch=
=3Dthunk -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 { ! x3=
2 } } } } */
++/* { 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=3Dthunk-extern -mindirect-branch=
=3Dthunk -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 { ! x3=
2 } } } } */
++/* { 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=3Dkeep -mindirect-branch=3Dthunk -=
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=3Dkeep -mindirect-branch=3Dthunk-i=
nline -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 { ! x3=
2 } } } } */
++/* { 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=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -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 { ! x3=
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-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=3Dkeep -mindirect-branch=3Dkeep -f=
no-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 { ! x3=
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-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=3Dthunk-inline -mindirect-branch=
=3Dthunk-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/g=
cc.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=3Dthunk-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/g=
cc.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=3Dthunk-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/g=
cc.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=3Dkeep" } */
++
++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/g=
cc.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=3Dkeep" } */
++
++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/g=
cc.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=3Dkeep" } */
++
++__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/g=
cc.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=3Dkeep" } */
++
++__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/g=
cc.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=3Dthunk-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/g=
cc.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=3Dthunk -mindirect-branch=3Dthunk =
-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 { ! x3=
2 } } } } */
++/* { 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 } } } =
*/
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-Add-mfunction-return-keep-t=
o-indirect-branch-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-mfun=
ction-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-indir=
ect-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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From def2b5d75fd6234984ec969f4586fcb8c516a3b9 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Wed, 6 Dec 2017 09:58:42 -0800
+Subject: [PATCH 12/17] Add -mfunction-return=3Dkeep to indirect branch tes=
ts
+
+---
+ 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/testsu=
ite/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=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsu=
ite/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=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsu=
ite/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=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsu=
ite/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=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsu=
ite/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=3Dthunk" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk" } */
+=20
+ extern void bar (void);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsu=
ite/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=3Dthunk" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk" } */
+=20
+ extern void bar (void);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsu=
ite/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=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
+=20
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/t=
estsuite/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=3Dkeep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/t=
estsuite/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=3Dkeep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/t=
estsuite/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=3Dkeep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/t=
estsuite/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=3Dkeep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/t=
estsuite/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=3Dkeep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/t=
estsuite/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=3Dkeep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/t=
estsuite/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=3Dkeep -fno-pic" } */
+=20
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/t=
estsuite/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=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
+=20
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/te=
stsuite/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=3Dthunk -fcheck-pointer-bounds -mm=
px -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fno-pic" } */
+=20
+ void (*dispatch) (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/te=
stsuite/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=3Dthunk -fcheck-pointer-bounds -mm=
px -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fno-pic" } */
+=20
+ void (*dispatch) (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/te=
stsuite/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=3Dthunk -fcheck-pointer-bounds -mm=
px -fpic -fno-plt" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
+=20
+ void bar (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/te=
stsuite/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=3Dthunk -fcheck-pointer-bounds -mm=
px -fpic -fno-plt" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
+=20
+ 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=3Dthunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dthunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dthunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dthunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dthunk-extern" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-extern" } */
+=20
+ extern void bar (void);
+=20
+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=3Dthunk-extern" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-extern" } */
+=20
+ extern void bar (void);
+=20
+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=3Dthunk-extern -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
+=20
+ 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=3Dthunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dthunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dthunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dthunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dthunk-inline" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-inline" } */
+=20
+ extern void bar (void);
+=20
+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=3Dthunk-inline" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-inline" } */
+=20
+ extern void bar (void);
+=20
+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=3Dthunk-inline -fno-pic" } */
++/* { dg-options "-O2 -mfunction-return=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
+=20
+ void func0 (void);
+ void func1 (void);
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-loop.p=
atch 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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From d667049b53e3d45de057fba2f1ed0e3f268201c1 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Thu, 16 Nov 2017 14:46:20 -0800
+Subject: [PATCH 10/17] Add -mindirect-branch-loop=3D
+
+Add -mindirect-branch-loop=3D 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
+ };
+=20
++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)
+=20
+   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
+=20
+-  /* 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 ();
++    }
+=20
+   /* 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(indi=
rect_branch_thunk_inline)
+=20
+ EnumValue
+ Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_ex=
tern)
++
++mindirect-branch-loop=3D
++Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86_i=
ndirect_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=3D option):
++
++EnumValue
++Enum(indirect_branch_loop) String(lfence) Value(indirect_branch_loop_lfen=
ce)
++
++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/t=
estsuite/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=3Dthunk -mindirect-branch-loop=3Dp=
ause -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/t=
estsuite/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=3Dthunk -mindirect-branch-loop=3Dn=
op -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/t=
estsuite/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=3Dthunk -mindirect-branch-loop=3Dl=
fence -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/t=
estsuite/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=3Dthunk-inline -mindirect-branch-l=
oop=3Dpause -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/t=
estsuite/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=3Dthunk-extern -mindirect-branch-l=
oop=3Dpause -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" } } */
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-Add-mindirect-branch-regist=
er-and-tests.patch b/gnu/packages/patches/gcc-retpoline-Add-mindirect-branc=
h-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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From fb8875abab630962dbcb08c822b1b960fa5a51d4 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@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 @@
+=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 =3D=3D DImode")
++       (and (match_test "TARGET_X32 && Pmode =3D=3D DImode
++			 && !ix86_indirect_branch_thunk_register")
+ 	    (match_operand 0 "GOT_memory_operand"))))
+=20
+ (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 =3D=3D DImode")
++       (and (match_test "TARGET_X32 && Pmode =3D=3D DImode
++			 && !ix86_indirect_branch_thunk_register")
+ 	    (match_operand 0 "GOT_memory_operand"))))
+=20
+ (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] =3D convert_memory_address (word_mode, operands[0]);
+ })
+=20
+@@ -11657,7 +11657,7 @@
+ 					 OPTAB_DIRECT);
+     }
+=20
+-  if (TARGET_X32)
++  if (TARGET_X32 || ix86_indirect_branch_thunk_register)
+     operands[0] =3D convert_memory_address (word_mode, operands[0]);
+ })
+=20
+@@ -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")])
+=20
+@@ -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 @@
+ })
+=20
+ (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")])
+=20
+ (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))])
+=20
+ ;; 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")])
+=20
+@@ -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 @@
+=20
+ (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(indi=
rect_branch_thunk_inline)
+ EnumValue
+ Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_ex=
tern)
+=20
++mindirect-branch-register
++Target Report Var(ix86_indirect_branch_thunk_register) Init(0)
++Force indirect call and jump via register.
++
+ mindirect-branch-loop=3D
+ Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86_i=
ndirect_branch_loop) Undocumented Init(indirect_branch_loop_lfence)
+=20
+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"))))
+=20
+ ;; Return true if OP is a memory operands that can be used in sibcalls.
+@@ -664,7 +665,8 @@
+=20
+ ;; 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 =3D XEXP (op, 0);
+   return (GET_CODE (op) =3D=3D CONST
+@@ -678,9 +680,11 @@
+   (ior (match_test "constant_call_address_operand
+ 		     (op, mode =3D=3D 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 =3D=3D DImode")
++	    (and (match_test "TARGET_X32 && Pmode =3D=3D DImode
++			      && !ix86_indirect_branch_thunk_register")
+ 		 (match_operand 0 "GOT_memory_operand")))))
+=20
+ ;; Similarly, but for tail calls, in which we cannot allow memory referen=
ces.
+@@ -688,14 +692,17 @@
+   (ior (match_test "constant_call_address_operand
+ 		     (op, mode =3D=3D 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 =3D=3D DImode")
++	    (and (match_test "TARGET_X32 && Pmode =3D=3D DImode
++			      && !ix86_indirect_branch_thunk_register")
+ 		 (match_operand 0 "GOT_memory_operand")))))
+=20
+ ;; Return true if OP is a 32-bit GOT symbol operand.
+ (define_predicate "GOT32_symbol_operand"
+-  (match_test "GET_CODE (op) =3D=3D CONST
++  (match_test "!ix86_indirect_branch_thunk_register
++	       && GET_CODE (op) =3D=3D CONST
+                && GET_CODE (XEXP (op, 0)) =3D=3D UNSPEC
+                && XINT (XEXP (op, 0), 1) =3D=3D UNSPEC_GOT"))
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/g=
cc/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=3Dthunk -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/g=
cc/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=3Dthunk-inline -mindirect-branch-r=
egister -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/g=
cc/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=3Dthunk-extern -mindirect-branch-r=
egister -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" } } */
+--=20
+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-thun=
k-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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 4032162fb6d36e20091885d0558f91daaa0080d3 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Mon, 27 Nov 2017 08:38:41 -0800
+Subject: [PATCH 07/17] Add -mindirect-branch=3Dthunk-extern
+
+Add -mindirect-branch=3Dthunk-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
+ };
+=20
+ #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_bra=
nch_thunk)
+=20
+ EnumValue
+ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_in=
line)
++
++EnumValue
++Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_ex=
tern)
+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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-extern" } */
++
++extern void bar (void);
++
++void
++foo (void)
++{
++  bar ();
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { 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=3Dthunk-extern" } */
++
++extern void bar (void);
++
++int
++foo (void)
++{
++  bar ();
++  return 0;
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { 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=3Dthunk-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\]+\\(,%" { ta=
rget { ! 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" } } */
+--=20
+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-thun=
k-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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 7f4f2bf1688c81496107993080e68a29a24de702 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Wed, 15 Nov 2017 11:20:31 -0800
+Subject: [PATCH 06/17] Add -mindirect-branch=3Dthunk-inline
+
+Add -mindirect-branch=3Dthunk-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 {
+=20
+ enum indirect_branch {
+   indirect_branch_keep,
+-  indirect_branch_thunk
++  indirect_branch_thunk,
++  indirect_branch_thunk_inline
+ };
+=20
+ #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 =3D ix86_bnd_prefixed_insn_p (current_output_insn);
+=20
+-  bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thunk;
+-  if (need_bnd_p)
+-    indirect_thunk_bnd_needed |=3D need_thunk;
++  if (ix86_indirect_branch !=3D indirect_branch_thunk_inline)
++    {
++      bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thu=
nk;
++      if (need_bnd_p)
++	indirect_thunk_bnd_needed |=3D need_thunk;
++      else
++	indirect_thunk_needed |=3D need_thunk;
++      indirect_thunk_name (thunk_name_buf, need_bnd_p);
++      thunk_name =3D thunk_name_buf;
++    }
+   else
+-    indirect_thunk_needed |=3D need_thunk;
+-  indirect_thunk_name (thunk_name, need_bnd_p);
++    thunk_name =3D NULL;
+=20
+   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,
+=20
+       output_asm_insn (push_buf, &call_op);
+=20
+-      if (need_bnd_p)
+-	fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
++      if (thunk_name !=3D 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);
+=20
+       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
+=20
+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_bran=
ch_keep)
+=20
+ EnumValue
+ Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk)
++
++EnumValue
++Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_in=
line)
+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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-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=3Dthunk-inline" } */
++
++extern void bar (void);
++
++void
++foo (void)
++{
++  bar ();
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { 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=3Dthunk-inline" } */
++
++extern void bar (void);
++
++int
++foo (void)
++{
++  bar ();
++  return 0;
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { 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=3Dthunk-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\]+\\(,%" { ta=
rget { ! 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" } } */
+--=20
+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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 63024dad9c00f1613738fd766e2f0afd455b76d1 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Wed, 1 Nov 2017 16:05:50 -0700
+Subject: [PATCH 04/17] Add -mindirect-branch=3Dthunk
+
+Add tests for -mindirect-branch=3Dthunk
+---
+ 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 */
+ };
+=20
++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
+=20
+ 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);
+=20
+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
+=20
++static int indirectlabelno;
++static bool indirect_thunk_needed =3D false;
++static bool indirect_thunk_bnd_needed =3D 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 =3D 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] =3D stack_pointer_rtx;
++  xops[1] =3D 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 =3D build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
++		     get_identifier (name),
++		     build_function_type_list (void_type_node, NULL_TREE));
++  DECL_RESULT (decl) =3D build_decl (BUILTINS_LOCATION, RESULT_DECL,
++				   NULL_TREE, void_type_node);
++  TREE_PUBLIC (decl) =3D 1;
++  TREE_STATIC (decl) =3D 1;
++  DECL_IGNORED_P (decl) =3D 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) =3D 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) =3D make_node (BLOCK);
++  current_function_decl =3D 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 =3D true;
++  first_function_block_is_cold =3D 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 =3D NULL;
++}
++
+ static int pic_labels_used;
+=20
+ /* 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;
+=20
++  if (indirect_thunk_needed)
++    output_indirect_thunk_function (false);
++  if (indirect_thunk_bnd_needed)
++    output_indirect_thunk_function (true);
++
+   for (regno =3D AX_REG; regno <=3D SP_REG; regno++)
+     {
+       char name[32];
+@@ -28452,12 +28596,132 @@ ix86_nopic_noplt_attribute_p (rtx call_op)
+   return false;
+ }
+=20
++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 =3D ix86_bnd_prefixed_insn_p (current_output_insn);
++
++  bool need_thunk =3D ix86_indirect_branch =3D=3D indirect_branch_thunk;
++  if (need_bnd_p)
++    indirect_thunk_bnd_needed |=3D need_thunk;
++  else
++    indirect_thunk_needed |=3D 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 !=3D 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 =3D XEXP (call_op, 0);
++	  if (ix86_decompose_address (addr, &parts)
++	      && parts.base =3D=3D 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 =3D gen_rtx_MULT (Pmode, parts.index,
++				       GEN_INT (parts.scale));
++		  addr =3D gen_rtx_PLUS (Pmode, stack_pointer_rtx,
++				       addr);
++		}
++	      else
++		addr =3D stack_pointer_rtx;
++
++	      rtx disp;
++	      if (parts.disp !=3D NULL_RTX)
++		disp =3D plus_constant (Pmode, parts.disp,
++				      UNITS_PER_WORD);
++	      else
++		disp =3D GEN_INT (UNITS_PER_WORD);
++
++	      addr =3D gen_rtx_PLUS (Pmode, addr, disp);
++	      call_op =3D 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 =3D=3D 0
++      && ix86_indirect_branch !=3D indirect_branch_keep)
++    {
++      ix86_output_indirect_branch (call_op, "%0", true);
++      return "";
++    }
++  else
++    return "%!jmp\t%A0";
++}
++
+ /* Output the assembly for a call instruction.  */
+=20
+ const char *
+ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
+ {
+   bool direct_p =3D constant_call_address_operand (call_op, VOIDmode);
++  bool output_indirect_p
++    =3D (!TARGET_SEH
++       && ix86_indirect_branch !=3D indirect_branch_keep);
+   bool seh_nop_p =3D false;
+   const char *xasm;
+=20
+@@ -28467,10 +28731,21 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_=
op)
+ 	{
+ 	  if (ix86_nopic_noplt_attribute_p (call_op))
+ 	    {
++	      direct_p =3D false;
+ 	      if (TARGET_64BIT)
+-		xasm =3D "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
++		{
++		  if (output_indirect_p)
++		    xasm =3D "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
++		  else
++		    xasm =3D "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]=
]}";
++		}
+ 	      else
+-		xasm =3D "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
++		{
++		  if (output_indirect_p)
++		    xasm =3D "{%p0@GOT|[DWORD PTR %p0@GOT]}";
++		  else
++		    xasm =3D "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
++		}
+ 	    }
+ 	  else
+ 	    xasm =3D "%!jmp\t%P0";
+@@ -28480,9 +28755,17 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_o=
p)
+       else if (TARGET_SEH)
+ 	xasm =3D "%!rex.W jmp\t%A0";
+       else
+-	xasm =3D "%!jmp\t%A0";
++	{
++	  if (output_indirect_p)
++	    xasm =3D "%0";
++	  else
++	    xasm =3D "%!jmp\t%A0";
++	}
+=20
+-      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 "";
+     }
+=20
+@@ -28520,18 +28803,37 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_=
op)
+     {
+       if (ix86_nopic_noplt_attribute_p (call_op))
+ 	{
++	  direct_p =3D false;
+ 	  if (TARGET_64BIT)
+-	    xasm =3D "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]=
]}";
++	    {
++	      if (output_indirect_p)
++		xasm =3D "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
++	      else
++		xasm =3D "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
++	    }
+ 	  else
+-	    xasm =3D "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
++	    {
++	      if (output_indirect_p)
++		xasm =3D "{%p0@GOT|[DWORD PTR %p0@GOT]}";
++	      else
++		xasm =3D "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
++	    }
+ 	}
+       else
+ 	xasm =3D "%!call\t%P0";
+     }
+   else
+-    xasm =3D "%!call\t%A0";
++    {
++      if (output_indirect_p)
++	xasm =3D "%0";
++      else
++	xasm =3D "%!call\t%A0";
++    }
+=20
+-  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);
+=20
+   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 con=
taining ret bytes.
+ mgeneral-regs-only
+ Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flag=
s) Save
+ Generate code which uses only the general registers.
++
++mindirect-branch=3D
++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indire=
ct_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=3D opti=
on):
++
++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
+ -malign-data=3D@var{type}  -mstack-protector-guard=3D@var{guard} @gol
+--mmitigate-rop  -mgeneral-regs-only}
++-mmitigate-rop  -mgeneral-regs-only -mindirect-branch=3D@var{choice}}
+=20
+ @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.
+=20
++@item -mindirect-branch=3D@var{choice}
++@opindex -mindirect-branch
++Update indirect call and jump with @var{choice}.  The default is
++@samp{keep}, which keeps indirect call and jump unmodified.
++@samp{thunk} converts indirect call and jump to push and
++PC-relative call thunk.
++
+ @end table
+=20
+ 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/testsu=
ite/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=3Dthunk -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/testsu=
ite/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=3Dthunk -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/testsu=
ite/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=3Dthunk -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/testsu=
ite/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=3Dthunk -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/testsu=
ite/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=3Dthunk" } */
++
++extern void bar (void);
++
++void
++foo (void)
++{
++  bar ();
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { 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/testsu=
ite/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=3Dthunk" } */
++
++extern void bar (void);
++
++int
++foo (void)
++{
++  bar ();
++  return 0;
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { 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/testsu=
ite/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=3Dthunk -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\]+\\(,%" { ta=
rget { ! 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} } } */
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-Add-mno-indirect-branch-reg=
ister-to-indirect-branch-.patch b/gnu/packages/patches/gcc-retpoline-Add-mn=
o-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-t=
o-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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 2c14ecf03978ce6c60e021a2b0d72778a5fe0982 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@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/testsu=
ite/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=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsu=
ite/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=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsu=
ite/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=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mno-indirect-branch-register -mfunction-return=3Dkeep -mindirect-b=
ranch=3Dthunk -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsu=
ite/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=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mno-indirect-branch-register -mfunction-return=3Dkeep -mindirect-b=
ranch=3Dthunk -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsu=
ite/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=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fpic -fno-plt -mindirect-branch=3Dthunk" } */
+=20
+ extern void bar (void);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsu=
ite/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=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mno-indirect-branch-register -mfunction-return=3Dkeep -fpic -fno-p=
lt -mindirect-branch=3Dthunk" } */
+=20
+ extern void bar (void);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsu=
ite/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=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk -fno-pic" } */
+=20
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/t=
estsuite/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=3Dkeep -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/t=
estsuite/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=3Dkeep -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/t=
estsuite/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=3Dkeep -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/t=
estsuite/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=3Dkeep -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/t=
estsuite/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=3Dkeep -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/t=
estsuite/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=3Dkeep -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/t=
estsuite/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=3Dkeep -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fno-pic" } */
+=20
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/te=
stsuite/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=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fno-pic" } */
+=20
+ void (*dispatch) (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/te=
stsuite/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=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fno-pic" } */
+=20
+ void (*dispatch) (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/te=
stsuite/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=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" }=
 */
+=20
+ void bar (char *);
+ char buf[10];
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/te=
stsuite/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=3Dkeep -mindirect-branch=3Dthunk -=
fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mfunction-return=3Dkeep -mindirect-branch=3Dthunk -fcheck-pointer-=
bounds -mmpx -fpic -fno-plt" } */
+=20
+ 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=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-extern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-extern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-extern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-extern -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-extern" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fpic -fno-plt -mindirect-branch=3Dthunk-extern" } */
+=20
+ extern void bar (void);
+=20
+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=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-extern" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fpic -fno-plt -mindirect-branch=3Dthunk-extern" } */
+=20
+ extern void bar (void);
+=20
+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=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-extern -fno-pic" } */
+=20
+ 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=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-inline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-inline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-inline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-inline -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-inline" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */
+=20
+ extern void bar (void);
+=20
+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=3Dkeep -fpic -fno-plt -mindirect-b=
ranch=3Dthunk-inline" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -fpic -fno-plt -mindirect-branch=3Dthunk-inline" } */
+=20
+ extern void bar (void);
+=20
+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=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-inline -fno-pic" } */
+=20
+ void func0 (void);
+ void func1 (void);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c b/gcc/t=
estsuite/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=3Dthunk -mindirect-branch-loop=3Dp=
ause -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth=
unk -mindirect-branch-loop=3Dpause -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c b/gcc/t=
estsuite/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=3Dthunk -mindirect-branch-loop=3Dn=
op -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth=
unk -mindirect-branch-loop=3Dnop -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c b/gcc/t=
estsuite/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=3Dthunk -mindirect-branch-loop=3Dl=
fence -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth=
unk -mindirect-branch-loop=3Dlfence -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c b/gcc/t=
estsuite/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=3Dthunk-inline -mindirect-branch-l=
oop=3Dpause -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth=
unk-inline -mindirect-branch-loop=3Dpause -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c b/gcc/t=
estsuite/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=3Dthunk-extern -mindirect-branch-l=
oop=3Dpause -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mindirect-branch=3Dth=
unk-extern -mindirect-branch-loop=3Dpause -fno-pic" } */
+=20
+ typedef void (*dispatch_t)(long offset);
+=20
+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=3Dthunk-inline -mindirect-branch=
=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mfunction-return=3Dthunk-inline -mindirect-branch=3Dthunk -fno-pic=
" } */
+=20
+ extern void (*bar) (void);
+=20
+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=3Dthunk-extern -mindirect-branch=
=3Dthunk -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct=
ion-return=3Dthunk-extern -mindirect-branch=3Dthunk -fno-pic" } */
+=20
+ extern void (*bar) (void);
+=20
+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=3Dkeep -mindirect-branch=3Dthunk -=
fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct=
ion-return=3Dkeep -mindirect-branch=3Dthunk -fno-pic" } */
+=20
+ extern void (*bar) (void);
+=20
+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=3Dkeep -mindirect-branch=3Dthunk-i=
nline -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-inline -fno-pic" } */
+=20
+ 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=3Dkeep -mindirect-branch=3Dthunk-e=
xtern -fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=3Dke=
ep -mindirect-branch=3Dthunk-extern -fno-pic" } */
+=20
+ extern void (*bar) (void);
+=20
+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=3Dkeep -mindirect-branch=3Dkeep -f=
no-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mno-indirect-branch-register -mno-indirect-branch-register -mfunct=
ion-return=3Dkeep -mindirect-branch=3Dkeep -fno-pic" } */
+=20
+ extern void (*bar) (void);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/g=
cc.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=3Dthunk -mindirect-branch=3Dthunk =
-fno-pic" } */
++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-r=
egister -mfunction-return=3Dthunk -mindirect-branch=3Dthunk -fno-pic" } */
+=20
+ extern void (*bar) (void);
+=20
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-Add-tests-for-mindirect-bra=
nch-thunk-fcheck-pointer-.patch b/gnu/packages/patches/gcc-retpoline-Add-te=
sts-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-thu=
nk-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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From ece041bc3083aabd00fab9de5ba409fbd7dcad8c Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Mon, 4 Dec 2017 12:58:20 -0800
+Subject: [PATCH 05/17] Add tests for -mindirect-branch=3Dthunk
+ -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/te=
stsuite/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=3Dthunk -fcheck-pointer-bounds -mm=
px -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/te=
stsuite/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=3Dthunk -fcheck-pointer-bounds -mm=
px -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/te=
stsuite/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=3Dthunk -fcheck-pointer-bounds -mm=
px -fpic -fno-plt" } */
++
++void bar (char *);
++char buf[10];
++
++void
++foo (void)
++{
++  bar (buf);
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { 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/te=
stsuite/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=3Dthunk -fcheck-pointer-bounds -mm=
px -fpic -fno-plt" } */
++
++void bar (char *);
++char buf[10];
++
++int
++foo (void)
++{
++  bar (buf);
++  return 0;
++}
++
++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
++/* { 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} } } */
+--=20
+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-indire=
ct-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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From f96e28553b0f2253184441f22852d76976e19968 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@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
+=20
+ 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);
+ }
+=20
+-/* 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.  */
+=20
+ 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 =3D=3D 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,
+ }
+=20
+ const char *
+-ix86_output_indirect_jmp (rtx call_op)
++ix86_output_indirect_jmp (rtx call_op, bool ret_p)
+ {
+-  if (ix86_red_zone_size =3D=3D 0
+-      && cfun->machine->indirect_branch_type !=3D indirect_branch_keep)
++  if (cfun->machine->indirect_branch_type !=3D 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 !=3D 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;
+=20
++  /* 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;
+=20
+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] =3D convert_memory_address (word_mode, operands[0]);
++  cfun->machine->has_local_indirect_jump =3D true;
+ })
+=20
+ (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 @@
+=20
+   if (TARGET_X32 || ix86_indirect_branch_thunk_register)
+     operands[0] =3D convert_memory_address (word_mode, operands[0]);
++  cfun->machine->has_local_indirect_jump =3D true;
+ })
+=20
+ (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")])
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-Rename-thunks-to-__x86_indi=
rect_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_th=
unk_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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From a072725899c551d9f3f06f3595e2a49748ab0187 Mon Sep 17 00:00:00 2001
+From: David Woodhouse <dwmw2@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, b=
ool need_bnd_p,
+ 	    reg_prefix =3D TARGET_64BIT ? "r" : "e";
+ 	  else
+ 	    reg_prefix =3D "";
+-	  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 =3D 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, i=
nt regno)
+   char name[32];
+   tree decl;
+=20
+-  /* 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 =3D build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
+ 		     get_identifier (name),
+@@ -12165,7 +12165,7 @@ output_indirect_thunk_function (bool need_bnd_p, i=
nt regno)
+=20
+   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];
+=20
+       indirect_thunk_name (alias, regno, need_bnd_p, true);
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsu=
ite/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)
+ }
+=20
+ /* { 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/testsu=
ite/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)
+ }
+=20
+ /* { 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/testsu=
ite/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)
+ }
+=20
+ /* { 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/testsu=
ite/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)
+ }
+=20
+ /* { 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/testsu=
ite/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)
+ }
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
+-/* { 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/testsu=
ite/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)
+ }
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
+-/* { 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/testsu=
ite/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)
+ }
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta=
rget { ! 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/t=
estsuite/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)
+ }
+=20
+ /* { 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/t=
estsuite/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)
+ }
+=20
+ /* { 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/t=
estsuite/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/t=
estsuite/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/t=
estsuite/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 { ! x=
32 } } } } */
+ /* { 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/t=
estsuite/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 { ! x=
32 } } } } */
+ /* { 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/t=
estsuite/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)
+ }
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta=
rget { ! 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/t=
estsuite/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)
+     }
+ }
+=20
+-/* { 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/te=
stsuite/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)
+=20
+ /* { 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/te=
stsuite/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)
+=20
+ /* { 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/te=
stsuite/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)
+ }
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
+-/* { 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/te=
stsuite/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)
+ }
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
+-/* { 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)
+ }
+=20
+ /* { 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)
+ }
+=20
+ /* { 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)
+ }
+=20
+ /* { 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 { ! x=
32 } } } } */
+ /* { 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)
+ }
+=20
+ /* { 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 { ! x=
32 } } } } */
+ /* { 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)
+ }
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
+-/* { 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)\[ \t\]*bar@GOT" } } */
+ /* { 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)
+ }
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta=
rget { ! 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)\[ \t\]*bar@GOT" } } */
+ /* { 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)\[ \t\]*bar@GOT" } } */
+ /* { 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/t=
estsuite/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)
+ }
+=20
+ /* { 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/t=
estsuite/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)
+ }
+=20
+ /* { 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/t=
estsuite/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)
+ }
+=20
+ /* { 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/t=
estsuite/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/t=
estsuite/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)
+ }
+=20
+ /* { 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/g=
cc/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);
+ }
+=20
+-/* { 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/g=
cc/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/g=
cc/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);
+ }
+=20
+-/* { 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/g=
cc.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)
+ {
+ }
+=20
+-/* { 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)
+=20
+ /* { 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 { ! x3=
2 } } } } */
+-/* { 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;
+ }
+=20
+-/* { 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 { ! x3=
2 } } } } */
+-/* { 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;
+ }
+=20
+-/* { 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;
+ }
+=20
+-/* { 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 { ! x3=
2 } } } } */
+ /* { 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)
+ }
+=20
+ /* { 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 { ! x3=
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\]*__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;
+ }
+=20
+-/* { 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 { ! x3=
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\]*__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;
+ }
+=20
+-/* { 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/g=
cc.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/g=
cc.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)
+ {
+ }
+=20
+-/* { 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/g=
cc.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)
+ {
+ }
+=20
+-/* { 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/g=
cc.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)
+ {
+ }
+=20
+-/* { 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/g=
cc.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/g=
cc.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)
+ {
+ }
+=20
+-/* { 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/g=
cc.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)
+ {
+ }
+=20
+-/* { 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/g=
cc.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;
+ }
+=20
+-/* { 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 { ! x3=
2 } } } } */
+-/* { 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 } } } =
*/
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-Use-__x86.indirect_thunk.re=
g-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-i=
ndirect-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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From e4e33b44a49eaa102806589ce12f021ab6a1e5f1 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@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 =3D false;
+ static bool indirect_thunk_bnd_needed =3D false;
+=20
++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 =3D false;
+ /* Fills in the label name that should be used for the indirect thunk.  */
+=20
+ 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 =3D need_bnd_p ? "_bnd" : "";
+-      sprintf (name, "__x86.indirect_thunk%s", bnd);
++      if (regno >=3D 0)
++	{
++	  const char *reg_prefix;
++	  if (LEGACY_INT_REGNO_P (regno))
++	    reg_prefix =3D TARGET_64BIT ? "r" : "e";
++	  else
++	    reg_prefix =3D "";
++	  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 >=3D 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);
++	}
+     }
+ }
+=20
+ 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)
+=20
+   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
+=20
+-  /* LEA.  */
+-  rtx xops[2];
+-  xops[0] =3D stack_pointer_rtx;
+-  xops[1] =3D plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
+-  output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);
++  if (regno >=3D 0)
++    {
++      /* MOV.  */
++      rtx xops[2];
++      xops[0] =3D gen_rtx_MEM (word_mode, stack_pointer_rtx);
++      xops[1] =3D gen_rtx_REG (word_mode, regno);
++      output_asm_insn ("mov\t{%1, %0|%0, %1}", xops);
++    }
++  else
++    {
++      /* LEA.  */
++      rtx xops[2];
++      xops[0] =3D stack_pointer_rtx;
++      xops[1] =3D plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD=
);
++      output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);
++    }
+=20
+   if (need_bnd_p)
+     fputs ("\tbnd ret\n", asm_out_file);
+@@ -12015,12 +12050,13 @@ output_indirect_thunk (bool need_bnd_p)
+ }
+=20
+ 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;
+=20
+-  indirect_thunk_name (name, need_bnd_p);
++  /* Create __x86.indirect_thunk/__x86.indirect_thunk_bnd.  */
++  indirect_thunk_name (name, regno, need_bnd_p);
+   decl =3D 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);
+=20
+-  output_indirect_thunk (need_bnd_p);
++  output_indirect_thunk (need_bnd_p, regno);
+=20
+   final_end_function ();
+   init_insn_lengths ();
+@@ -12110,15 +12146,31 @@ ix86_code_end (void)
+   int regno;
+=20
+   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 =3D FIRST_REX_INT_REG; regno <=3D LAST_REX_INT_REG; regno++)
++    {
++      int i =3D 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);
++    }
+=20
+   for (regno =3D AX_REG; regno <=3D SP_REG; regno++)
+     {
+       char name[32];
+       tree decl;
+=20
++      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;
+=20
+@@ -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 =3D ix86_bnd_prefixed_insn_p (current_output_insn);
++  int regno;
++
++  if (REG_P (call_op))
++    regno =3D REGNO (call_op);
++  else
++    regno =3D -1;
+=20
+   if (cfun->machine->indirect_branch_type
+       !=3D indirect_branch_thunk_inline)
+     {
+-      bool need_thunk
+-	=3D cfun->machine->indirect_branch_type =3D=3D indirect_branch_thunk;
+-      if (need_bnd_p)
+-	indirect_thunk_bnd_needed |=3D need_thunk;
+-      else
+-	indirect_thunk_needed |=3D need_thunk;
+-      indirect_thunk_name (thunk_name_buf, need_bnd_p);
++      if (cfun->machine->indirect_branch_type =3D=3D indirect_branch_thun=
k)
++	{
++	  if (regno >=3D 0)
++	    {
++	      int i =3D regno;
++	      if (i >=3D FIRST_REX_INT_REG)
++		i -=3D (FIRST_REX_INT_REG - LAST_INT_REG - 1);
++	      if (need_bnd_p)
++		indirect_thunks_bnd_used |=3D 1 << i;
++	      else
++		indirect_thunks_used |=3D 1 << i;
++	    }
++	  else
++	    {
++	      if (need_bnd_p)
++		indirect_thunk_bnd_needed =3D true;
++	      else
++		indirect_thunk_needed =3D true;
++	    }
++	}
++      indirect_thunk_name (thunk_name_buf, regno, need_bnd_p);
+       thunk_name =3D thunk_name_buf;
+     }
+   else
+@@ -28660,7 +28732,8 @@ ix86_output_indirect_branch (rtx call_op, const ch=
ar *xasm,
+=20
+   if (sibcall_p)
+     {
+-      output_asm_insn (push_buf, &call_op);
++      if (regno < 0)
++	output_asm_insn (push_buf, &call_op);
+       if (thunk_name !=3D 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 >=3D 0 && thunk_name !=3D 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];
+=20
+@@ -28725,7 +28807,8 @@ ix86_output_indirect_branch (rtx call_op, const ch=
ar *xasm,
+ 	    }
+ 	}
+=20
+-      output_asm_insn (push_buf, &call_op);
++      if (regno < 0)
++	output_asm_insn (push_buf, &call_op);
+=20
+       if (thunk_name !=3D NULL)
+ 	{
+@@ -28735,7 +28818,7 @@ ix86_output_indirect_branch (rtx call_op, const ch=
ar *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);
+=20
+       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
+=20
+diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsu=
ite/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)
+ }
+=20
+ /* { 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/testsu=
ite/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)
+ }
+=20
+ /* { 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/testsu=
ite/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)
+ }
+=20
+ /* { 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/testsu=
ite/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)
+ }
+=20
+ /* { 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/testsu=
ite/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)
+ }
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta=
rget { ! 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/t=
estsuite/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)
+ }
+=20
+ /* { 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/t=
estsuite/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)
+ }
+=20
+ /* { 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/t=
estsuite/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)
+ }
+=20
+ /* { 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/t=
estsuite/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)
+ }
+=20
+ /* { 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/t=
estsuite/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)
+ }
+=20
+ /* { 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 { ! x=
32 } } } } */
++/* { 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/t=
estsuite/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)
+ }
+=20
+ /* { 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 { ! x=
32 } } } } */
++/* { 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/t=
estsuite/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)
+ }
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta=
rget { ! 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)
+ }
+=20
+ /* { 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)
+ }
+=20
+ /* { 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)
+ }
+=20
+ /* { 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 { ! x=
32 } } } } */
++/* { 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)
+ }
+=20
+ /* { 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 { ! x=
32 } } } } */
++/* { 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)
+ }
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta=
rget { ! 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)
+ }
+=20
+ /* { 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)
+ }
+=20
+ /* { 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)
+ }
+=20
+ /* { 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)
+ }
+=20
+ /* { 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)
+ }
+=20
+ /* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { ta=
rget { ! 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" } } */
+--=20
+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-op=
erand-modifier.patch
new file mode 100644
index 000000000..1996a1dfe
--- /dev/null
+++ b/gnu/packages/patches/gcc-retpoline-i386-Add-V-register-operand-modifi=
er.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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From f83391fb22471a2f1c330e2e78f64630d64f497d Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@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_mo=
de 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 %.
+  */
+=20
+ void
+@@ -17896,7 +17897,7 @@ print_reg (rtx x, int code, FILE *file)
+   unsigned int regno;
+   bool duplicated;
+=20
+-  if (ASSEMBLER_DIALECT =3D=3D ASM_ATT)
++  if (ASSEMBLER_DIALECT =3D=3D ASM_ATT && code !=3D 'V')
+     putc ('%', file);
+=20
+   if (x =3D=3D 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;
+=20
+ 	case 's':
+--=20
+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-M=
ore-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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From d96784e4a7355aaab68dec62f31a97bd10714064 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@HIDDEN>
+Date: Tue, 28 Nov 2017 10:26:35 -0800
+Subject: [PATCH 03/17] i386: More use reference of struct ix86_frame to av=
oid
+ 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 =3D 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 =3D true;
+=20
+   ix86_compute_frame_layout ();
+-  frame =3D m->frame;
++  struct ix86_frame &frame =3D cfun->machine->frame;
+=20
+   if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_d=
ecl))
+     {
+@@ -14343,13 +14342,12 @@ ix86_expand_epilogue (int style)
+ {
+   struct machine_function *m =3D cfun->machine;
+   struct machine_frame_state frame_state_save =3D m->fs;
+-  struct ix86_frame frame;
+   bool restore_regs_via_mov;
+   bool using_drap;
+=20
+   ix86_finalize_stack_realign_flags ();
+   ix86_compute_frame_layout ();
+-  frame =3D m->frame;
++  struct ix86_frame &frame =3D cfun->machine->frame;
+=20
+   m->fs.sp_valid =3D (!frame_pointer_needed
+ 		    || (crtl->sp_is_unchanging
+--=20
+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-s=
truct-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-mac=
hine_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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 85743811dfa4eb648edbbb637632ac53182b6e05 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@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;
+ };
+=20
+-/* 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]	       | =3D 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;
+=20
+@@ -2579,7 +2532,7 @@ static unsigned int ix86_function_arg_boundary (mach=
ine_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 >=3D 32768)
+     return 0;
+=20
+-  ix86_compute_frame_layout (&frame);
++  ix86_compute_frame_layout ();
++  frame =3D cfun->machine->frame;
+   return (frame.stack_pointer_offset =3D=3D UNITS_PER_WORD
+ 	  && (frame.nregs + frame.nsseregs) =3D=3D 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 =3D cfun->machine->frame;
+=20
+   if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME_POINTER_REGN=
UM)
+     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. =
 */
+=20
+ static void
+-ix86_compute_frame_layout (struct ix86_frame *frame)
++ix86_compute_frame_layout (void)
+ {
++  struct ix86_frame *frame =3D &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 =3D INCOMING_FRAME_SP_OFFSET;
+   m->fs.sp_valid =3D true;
+=20
+-  ix86_compute_frame_layout (&frame);
++  ix86_compute_frame_layout ();
++  frame =3D m->frame;
+=20
+   if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_d=
ecl))
+     {
+@@ -14394,7 +14350,8 @@ ix86_expand_epilogue (int style)
+   bool using_drap;
+=20
+   ix86_finalize_stack_realign_flags ();
+-  ix86_compute_frame_layout (&frame);
++  ix86_compute_frame_layout ();
++  frame =3D m->frame;
+=20
+   m->fs.sp_valid =3D (!frame_pointer_needed
+ 		    || (crtl->sp_is_unchanging
+@@ -14904,7 +14861,8 @@ ix86_expand_split_stack_prologue (void)
+   gcc_assert (flag_split_stack && reload_completed);
+=20
+   ix86_finalize_stack_realign_flags ();
+-  ix86_compute_frame_layout (&frame);
++  ix86_compute_frame_layout ();
++  frame =3D cfun->machine->frame;
+   allocate =3D frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
+=20
+   /* 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]	       | =3D 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.  =
*/
+=20
+-#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];
+=20
++  /* 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)
+=20
+ /* Control behavior of x86_file_start.  */
+ #define X86_FILE_START_VERSION_DIRECTIVE false
+--=20
+2.15.1
+
diff --git a/gnu/packages/patches/gcc-retpoline-i386-Use-reference-of-struc=
t-ix86_frame-to-avoid-cop.patch b/gnu/packages/patches/gcc-retpoline-i386-U=
se-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=3DCVE-2017-5715
+
+Patch copied from the 'retpoline-20180107' branch of upstream source repos=
itory
+(please add new / update existing patches when new 'retpoline-xxxxxxxx' br=
anch
+appears):
+
+http://git.infradead.org/users/dwmw2/gcc-retpoline.git
+
+From 0b1769bdce27304a6a91bec234f47f102a2603d5 Mon Sep 17 00:00:00 2001
+From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Mon, 6 Nov 2017 23:04:15 +0000
+Subject: [PATCH 02/17] i386: Use reference of struct ix86_frame to avoid c=
opy
+
+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/trunk@254480 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;
+=20
+   ix86_compute_frame_layout ();
+-  frame =3D cfun->machine->frame;
++  struct ix86_frame &frame =3D cfun->machine->frame;
+   return (frame.stack_pointer_offset =3D=3D UNITS_PER_WORD
+ 	  && (frame.nregs + frame.nsseregs) =3D=3D 0);
+ }
+@@ -12333,7 +12331,7 @@ HOST_WIDE_INT
+ ix86_initial_elimination_offset (int from, int to)
+ {
+   ix86_compute_frame_layout ();
+-  struct ix86_frame frame =3D cfun->machine->frame;
++  struct ix86_frame &frame =3D cfun->machine->frame;
+=20
+   if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME_POINTER_REGN=
UM)
+     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)
+=20
+   ix86_finalize_stack_realign_flags ();
+   ix86_compute_frame_layout ();
+-  frame =3D cfun->machine->frame;
++  struct ix86_frame &frame =3D cfun->machine->frame;
+   allocate =3D frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
+=20
+   /* This is the label we will branch to if we have enough stack
+--=20
+2.15.1
+
--=20
2.15.1


--=-=-=
Content-Type: text/plain


Cheers,
Alex

--=-=-=--




Acknowledgement sent to Alex Vong <alexvong1995@HIDDEN>:
New bug report received and forwarded. Copy sent to guix-patches@HIDDEN. Full text available.
Report forwarded to guix-patches@HIDDEN:
bug#30111; Package guix-patches. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Tue, 27 Feb 2018 09:45:02 UTC

GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997 nCipher Corporation Ltd, 1994-97 Ian Jackson.