[PATCH 1/2] i386: Generate lfence with load/indirect branch/ret [CVE-2020-0551]

Hongtao Liu crazylht@gmail.com
Sun Apr 26 02:03:43 GMT 2020


On Fri, Apr 24, 2020 at 9:00 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Fri, Apr 24, 2020 at 12:24 AM Hongtao Liu <crazylht@gmail.com> wrote:
> >
> > On Fri, Apr 24, 2020 at 2:01 PM Jan Beulich <jbeulich@suse.com> wrote:
> > >
> > > On 24.04.2020 07:30, Hongtao Liu wrote:
> > > > Change to
> > > >
> > > > +      /* lret or iret.  */
> > > > +      bfd_boolean lret = (i.tm.base_opcode | 0x5) == 0xcf;
> > > > +      bfd_boolean has_rexw = i.prefix[REX_PREFIX] & REX_W;
> > > > +      char prefix = 0x0;
> > > > +      /* Default operand size for far return is 32 bits,
> > > > +         64 bits for near return.  */
> > > > +      /* Near ret ingore operand size override under CPU64.  */
> > > > +      if ((!lret && flag_code == CODE_64BIT) || has_rexw)
> > > > +        prefix = 0x48;
> > > >        else
> > > > +        prefix = i.prefix[DATA_PREFIX] ? 0x66 : 0x0;
> > >
> > > One minor remark on this one - I'd suggest to either omit the
> > > initializer for prefix, or make the last two lines
> > >
> > >       else if (i.prefix[DATA_PREFIX])
> > >         prefix = 0x66;
> > >
> > > as there's no point assigning 0 twice.
> > >
> >
> > I'll do this change.
> >
> > > > Update total patch:
> > >
> > > Looks okay to me now, thanks.
> > >
> > > Jan
> >
> > Thanks for you review and patience, I'll wait for H.J's approval and
> > submit my patch.
> >
>
> Please post your final patch.
>
> Thanks.
>
> --
> H.J.

>From 495f32049c894cfc24984dfceed3f45169bc0128 Mon Sep 17 00:00:00 2001
From: liuhongt <hongtao.liu@intel.com>
Date: Mon, 16 Mar 2020 11:03:12 +0800
Subject: [PATCH] Improve -mlfence-after-load

  1.Implict load for POP/POPF/POPA/XLATB, no load for Anysize insns
  2. Add -mlfence-before-ret=shl/yes, adjust operand size of
  or/not/shl according to ret's.
  3. Issue warning for REP CMPS/SCAS since they would affect control
  flow behavior.
  4. Adjust testcases and documents.

gas/Changelog:
        * config/tc-i386.c (lfence_before_ret_shl): New member.
        (load_insn_p): implict load for POP/POPA/POPF/XLATB, no load
        for Anysize insns.
        (insert_after_load): Issue warning for REP CMPS/SCAS.
        (insert_before_before): Handle iret, Handle
        -mlfence-before-ret=shl, Adjust operand size of or/not/shl to ret's,
        (md_parse_option): Change -mlfence-before-ret=[none|not|or] to
        -mlfence-before-ret=[none/not/or/shl/yes].
        Enable -mlfence-before-ret=shl when
        -mlfence-beofre-indirect-branch=all and no explict
-mlfence-before-ret option.
        (md_show_usage): Ditto.
        * doc/c-i386.texi: Ditto.
        * testsuite/gas/i386/i386.exp: Add new testcases.
        * testsuite/gas/i386/lfence-load-b.d: New.
        * testsuite/gas/i386/lfence-load-b.e: New.
        * testsuite/gas/i386/lfence-load.d: Modified.
        * testsuite/gas/i386/lfence-load.e: New.
        * testsuite/gas/i386/lfence-load.s: Modified.
        * testsuite/gas/i386/lfence-ret-a.d: Modified.
        * testsuite/gas/i386/lfence-ret-b.d: Modified.
        * testsuite/gas/i386/lfence-ret-c.d: New.
        * testsuite/gas/i386/lfence-ret-d.d: New.
        * testsuite/gas/i386/lfence-ret.s: Modified.
        * testsuite/gas/i386/x86-64-lfence-load-b.d: New.
        * testsuite/gas/i386/x86-64-lfence-load.d: Modified.
        * testsuite/gas/i386/x86-64-lfence-load.s: Modified.
        * testsuite/gas/i386/x86-64-lfence-ret-a.d: Modified.
        * testsuite/gas/i386/x86-64-lfence-ret-b.d: Modified.
        * testsuite/gas/i386/x86-64-lfence-ret-c.d: New.
        * testsuite/gas/i386/x86-64-lfence-ret-d.d: New
        * testsuite/gas/i386/x86-64-lfence-ret-e.d: New.
        * testsuite/gas/i386/x86-64-lfence-ret.e: New.
        * testsuite/gas/i386/x86-64-lfence-ret.s: New.
---
 gas/config/tc-i386.c                         | 120 ++++++++++++++-----
 gas/doc/c-i386.texi                          |  12 +-
 gas/testsuite/gas/i386/i386.exp              |   5 +
 gas/testsuite/gas/i386/lfence-load.d         |  26 ++++
 gas/testsuite/gas/i386/lfence-load.e         |   3 +
 gas/testsuite/gas/i386/lfence-load.s         |  20 ++++
 gas/testsuite/gas/i386/lfence-ret-a.d        |  18 +++
 gas/testsuite/gas/i386/lfence-ret-b.d        |  24 ++++
 gas/testsuite/gas/i386/lfence-ret-c.d        |  35 ++++++
 gas/testsuite/gas/i386/lfence-ret-d.d        |  36 ++++++
 gas/testsuite/gas/i386/lfence-ret.s          |   6 +
 gas/testsuite/gas/i386/x86-64-lfence-load.d  |  24 ++++
 gas/testsuite/gas/i386/x86-64-lfence-load.s  |  19 +++
 gas/testsuite/gas/i386/x86-64-lfence-ret-a.d |  35 +++++-
 gas/testsuite/gas/i386/x86-64-lfence-ret-b.d |  45 ++++++-
 gas/testsuite/gas/i386/x86-64-lfence-ret-c.d |  48 ++++++++
 gas/testsuite/gas/i386/x86-64-lfence-ret-d.d |  49 ++++++++
 gas/testsuite/gas/i386/x86-64-lfence-ret-e.d |  49 ++++++++
 gas/testsuite/gas/i386/x86-64-lfence-ret.e   |   3 +
 gas/testsuite/gas/i386/x86-64-lfence-ret.s   |  14 +++
 20 files changed, 551 insertions(+), 40 deletions(-)
 create mode 100644 gas/testsuite/gas/i386/lfence-load.e
 create mode 100644 gas/testsuite/gas/i386/lfence-ret-c.d
 create mode 100644 gas/testsuite/gas/i386/lfence-ret-d.d
 create mode 100644 gas/testsuite/gas/i386/x86-64-lfence-ret-c.d
 create mode 100644 gas/testsuite/gas/i386/x86-64-lfence-ret-d.d
 create mode 100644 gas/testsuite/gas/i386/x86-64-lfence-ret-e.d
 create mode 100644 gas/testsuite/gas/i386/x86-64-lfence-ret.e
 create mode 100644 gas/testsuite/gas/i386/x86-64-lfence-ret.s

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 093497becd..a692c457a5 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -647,7 +647,8 @@ static enum lfence_before_ret_kind
   {
     lfence_before_ret_none = 0,
     lfence_before_ret_not,
-    lfence_before_ret_or
+    lfence_before_ret_or,
+    lfence_before_ret_shl
   }
 lfence_before_ret;

@@ -4350,22 +4351,28 @@ load_insn_p (void)

   if (!any_vex_p)
     {
-      /* lea  */
-      if (i.tm.base_opcode == 0x8d)
+      /* Anysize insns: lea, invlpg, clflush, prefetchnta, prefetcht0,
+         prefetcht1, prefetcht2, prefetchtw, bndmk, bndcl, bndcu, bndcn,
+         bndstx, bndldx, prefetchwt1, clflushopt, clwb, cldemote.  */
+      if (i.tm.opcode_modifier.anysize)
         return 0;

-      /* pop  */
-      if ((i.tm.base_opcode & ~7) == 0x58
-          || (i.tm.base_opcode == 0x8f && i.tm.extension_opcode == 0))
+      /* pop, popf, popa.   */
+      if (strcmp (i.tm.name, "pop") == 0
+          || i.tm.base_opcode == 0x9d
+          || i.tm.base_opcode == 0x61)
         return 1;

       /* movs, cmps, lods, scas.  */
       if ((i.tm.base_opcode | 0xb) == 0xaf)
         return 1;

-      /* outs */
-      if (base_opcode == 0x6f)
+      /* outs, xlatb.  */
+      if (base_opcode == 0x6f
+          || i.tm.base_opcode == 0xd7)
         return 1;
+      /* NB: For AMD-specific insns with implicit memory operands,
+         they're intentionally not covered.  */
     }

   /* No memory operand.  */
@@ -4506,6 +4513,22 @@ insert_lfence_after (void)
 {
   if (lfence_after_load && load_insn_p ())
     {
+      /* There are also two REP string instructions that require
+         special treatment. Specifically, the compare string (CMPS)
+         and scan string (SCAS) instructions set EFLAGS in a manner
+         that depends on the data being compared/scanned. When used
+         with a REP prefix, the number of iterations may therefore
+         vary depending on this data. If the data is a program secret
+         chosen by the adversary using an LVI method,
+         then this data-dependent behavior may leak some aspect
+         of the secret.  */
+      if (((i.tm.base_opcode | 0x1) == 0xa7
+           || (i.tm.base_opcode | 0x1) == 0xaf)
+          && i.prefix[REP_PREFIX])
+        {
+            as_warn (_("`%s` changes flags which would affect control
flow behavior"),
+                     i.tm.name);
+        }
       char *p = frag_more (3);
       *p++ = 0xf;
       *p++ = 0xae;
@@ -4568,12 +4591,13 @@ insert_lfence_before (void)
       return;
     }

-  /* Output or/not and lfence before ret.  */
+  /* Output or/not/shl and lfence before ret/lret/iret.  */
   if (lfence_before_ret != lfence_before_ret_none
       && (i.tm.base_opcode == 0xc2
           || i.tm.base_opcode == 0xc3
           || i.tm.base_opcode == 0xca
-          || i.tm.base_opcode == 0xcb))
+          || i.tm.base_opcode == 0xcb
+          || i.tm.base_opcode == 0xcf))
     {
       if (last_insn.kind != last_insn_other
           && last_insn.seg == now_seg)
@@ -4583,33 +4607,59 @@ insert_lfence_before (void)
                          last_insn.name, i.tm.name);
           return;
         }
-      if (lfence_before_ret == lfence_before_ret_or)
-        {
-          /* orl: 0x830c2400.  */
-          p = frag_more ((flag_code == CODE_64BIT ? 1 : 0) + 4 + 3);
-          if (flag_code == CODE_64BIT)
-            *p++ = 0x48;
-          *p++ = 0x83;
-          *p++ = 0xc;
-          *p++ = 0x24;
-          *p++ = 0x0;
-        }
-      else
-        {
-          p = frag_more ((flag_code == CODE_64BIT ? 2 : 0) + 6 + 3);
-          /* notl: 0xf71424.  */
-          if (flag_code == CODE_64BIT)
-            *p++ = 0x48;
+
+      /* lret or iret.  */
+      bfd_boolean lret = (i.tm.base_opcode | 0x5) == 0xcf;
+      bfd_boolean has_rexw = i.prefix[REX_PREFIX] & REX_W;
+      char prefix = 0x0;
+      /* Default operand size for far return is 32 bits,
+         64 bits for near return.  */
+      /* Near ret ingore operand size override under CPU64.  */
+      if ((!lret && flag_code == CODE_64BIT) || has_rexw)
+        prefix = 0x48;
+      else if (i.prefix[DATA_PREFIX])
+        prefix = 0x66;
+
+      if (lfence_before_ret == lfence_before_ret_not)
+        {
+          /* not: 0xf71424, may add prefix
+             for operand size override or 64-bit code.  */
+          p = frag_more ((prefix ? 2 : 0) + 6 + 3);
+          if (prefix)
+            *p++ = prefix;
           *p++ = 0xf7;
           *p++ = 0x14;
           *p++ = 0x24;
-          /* notl: 0xf71424.  */
-          if (flag_code == CODE_64BIT)
-            *p++ = 0x48;
+          if (prefix)
+            *p++ = prefix;
           *p++ = 0xf7;
           *p++ = 0x14;
           *p++ = 0x24;
         }
+      else
+        {
+          p = frag_more ((prefix ? 1 : 0) + 4 + 3);
+          if (prefix)
+            *p++ = prefix;
+          if (lfence_before_ret == lfence_before_ret_or)
+            {
+              /* or: 0x830c2400, may add prefix
+                 for operand size override or 64-bit code.  */
+              *p++ = 0x83;
+              *p++ = 0x0c;
+            }
+          else
+            {
+              /* shl: 0xc1242400, may add prefix
+                 for operand size override or 64-bit code.  */
+              *p++ = 0xc1;
+              *p++ = 0x24;
+            }
+
+          *p++ = 0x24;
+          *p++ = 0x0;
+        }
+
       *p++ = 0xf;
       *p++ = 0xae;
       *p = 0xe8;
@@ -12995,7 +13045,11 @@ md_parse_option (int c, const char *arg)

     case OPTION_MLFENCE_BEFORE_INDIRECT_BRANCH:
       if (strcasecmp (arg, "all") == 0)
-        lfence_before_indirect_branch = lfence_branch_all;
+        {
+          lfence_before_indirect_branch = lfence_branch_all;
+          if (lfence_before_ret == lfence_before_ret_none)
+            lfence_before_ret = lfence_before_ret_shl;
+        }
       else if (strcasecmp (arg, "memory") == 0)
         lfence_before_indirect_branch = lfence_branch_memory;
       else if (strcasecmp (arg, "register") == 0)
@@ -13012,6 +13066,8 @@ md_parse_option (int c, const char *arg)
         lfence_before_ret = lfence_before_ret_or;
       else if (strcasecmp (arg, "not") == 0)
         lfence_before_ret = lfence_before_ret_not;
+      else if (strcasecmp (arg, "shl") == 0 || strcasecmp (arg, "yes") == 0)
+        lfence_before_ret = lfence_before_ret_shl;
       else if (strcasecmp (arg, "none") == 0)
         lfence_before_ret = lfence_before_ret_none;
       else
@@ -13382,7 +13438,7 @@ md_show_usage (FILE *stream)
   -mlfence-before-indirect-branch=[none|all|register|memory] (default: none)\n\
                           generate lfence before indirect near branch\n"));
   fprintf (stream, _("\
-  -mlfence-before-ret=[none|or|not] (default: none)\n\
+  -mlfence-before-ret=[none|or|not|shl|yes] (default: none)\n\
                           generate lfence before ret\n"));
   fprintf (stream, _("\
   -mamd64                 accept only AMD64 ISA [default]\n"));
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
index 628fb1ad5a..4acece4394 100644
--- a/gas/doc/c-i386.texi
+++ b/gas/doc/c-i386.texi
@@ -488,6 +488,8 @@ before indirect near branch instructions.
 @option{-mlfence-before-indirect-branch=@var{all}} will generate lfence
 before indirect near branch via register and issue a warning before
 indirect near branch via memory.
+It also implicitly sets @option{-mlfence-before-ret=@var{shl}} when
+there's no explict @option{-mlfence-before-ret=}.
 @option{-mlfence-before-indirect-branch=@var{register}} will generate
 lfence before indirect near branch via register.
 @option{-mlfence-before-indirect-branch=@var{memory}} will issue a
@@ -501,15 +503,17 @@ after loading branch target register.
 @cindex @samp{-mlfence-before-ret=} option, i386
 @cindex @samp{-mlfence-before-ret=} option, x86-64
 @item -mlfence-before-ret=@var{none}
+@item -mlfence-before-ret=@var{shl}
 @item -mlfence-before-ret=@var{or}
+@item -mlfence-before-ret=@var{yes}
 @itemx -mlfence-before-ret=@var{not}
 These options control whether the assembler should generate lfence
 before ret.  @option{-mlfence-before-ret=@var{or}} will generate
 generate or instruction with lfence.
-@option{-mlfence-before-ret=@var{not}} will generate not instruction
-with lfence.
-@option{-mlfence-before-ret=@var{none}} will not generate lfence,
-which is the default.
+@option{-mlfence-before-ret=@var{shl/yes}} will generate shl instruction
+with lfence. @option{-mlfence-before-ret=@var{not}} will generate not
+instruction with lfence. @option{-mlfence-before-ret=@var{none}} will not
+generate lfence, which is the default.

 @cindex @samp{-mx86-used-note=} option, i386
 @cindex @samp{-mx86-used-note=} option, x86-64
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index 9dacc11906..3bacb80178 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -535,6 +535,8 @@ if [expr ([istarget "i*86-*-*"] ||  [istarget
"x86_64-*-*"]) && [gas_32_check]]
     run_dump_test "lfence-indbr-c"
     run_dump_test "lfence-ret-a"
     run_dump_test "lfence-ret-b"
+    run_dump_test "lfence-ret-c"
+    run_dump_test "lfence-ret-d"
     run_dump_test "lfence-byte"

     # These tests require support for 8 and 16 bit relocs,
@@ -1122,6 +1124,9 @@ if [expr ([istarget "i*86-*-*"] || [istarget
"x86_64-*-*"]) && [gas_64_check]] t
     run_dump_test "x86-64-lfence-indbr-c"
     run_dump_test "x86-64-lfence-ret-a"
     run_dump_test "x86-64-lfence-ret-b"
+    run_dump_test "x86-64-lfence-ret-c"
+    run_dump_test "x86-64-lfence-ret-d"
+    run_dump_test "x86-64-lfence-ret-e"
     run_dump_test "x86-64-lfence-byte"

     if { ![istarget "*-*-aix*"]
diff --git a/gas/testsuite/gas/i386/lfence-load.d
b/gas/testsuite/gas/i386/lfence-load.d
index cd7e7f76df..0d355df556 100644
--- a/gas/testsuite/gas/i386/lfence-load.d
+++ b/gas/testsuite/gas/i386/lfence-load.d
@@ -1,5 +1,6 @@
 #as: -mlfence-after-load=yes
 #objdump: -dw
+#warning_output: lfence-load.e
 #name: -mlfence-after-load=yes

 .*: +file format .*
@@ -15,6 +16,31 @@ Disassembly of section .text:
  +[a-f0-9]+: 0f c7 75 00          vmptrld 0x0\(%ebp\)
  +[a-f0-9]+: 0f ae e8              lfence
  +[a-f0-9]+: 66 0f c7 75 00        vmclear 0x0\(%ebp\)
+ +[a-f0-9]+: 66 0f 38 82 55 00    invpcid 0x0\(%ebp\),%edx
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 0f 01 7d 00          invlpg 0x0\(%ebp\)
+ +[a-f0-9]+: 0f ae 7d 00          clflush 0x0\(%ebp\)
+ +[a-f0-9]+: 66 0f ae 7d 00        clflushopt 0x0\(%ebp\)
+ +[a-f0-9]+: 66 0f ae 75 00        clwb   0x0\(%ebp\)
+ +[a-f0-9]+: 0f 1c 45 00          cldemote 0x0\(%ebp\)
+ +[a-f0-9]+: f3 0f 1b 4d 00        bndmk  0x0\(%ebp\),%bnd1
+ +[a-f0-9]+: f3 0f 1a 4d 00        bndcl  0x0\(%ebp\),%bnd1
+ +[a-f0-9]+: f2 0f 1a 4d 00        bndcu  0x0\(%ebp\),%bnd1
+ +[a-f0-9]+: f2 0f 1b 4d 00        bndcn  0x0\(%ebp\),%bnd1
+ +[a-f0-9]+: 0f 1b 4d 00          bndstx %bnd1,0x0\(%ebp\)
+ +[a-f0-9]+: 0f 1a 4d 00          bndldx 0x0\(%ebp\),%bnd1
+ +[a-f0-9]+: 0f 18 4d 00          prefetcht0 0x0\(%ebp\)
+ +[a-f0-9]+: 0f 18 55 00          prefetcht1 0x0\(%ebp\)
+ +[a-f0-9]+: 0f 18 5d 00          prefetcht2 0x0\(%ebp\)
+ +[a-f0-9]+: 0f 0d 4d 00          prefetchw 0x0\(%ebp\)
+ +[a-f0-9]+: 1f                    pop    %ds
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 9d                    popf
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 61                    popa
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: d7                    xlat   %ds:\(%ebx\)
+ +[a-f0-9]+: 0f ae e8              lfence
  +[a-f0-9]+: d9 55 00              fsts   0x0\(%ebp\)
  +[a-f0-9]+: d9 45 00              flds   0x0\(%ebp\)
  +[a-f0-9]+: 0f ae e8              lfence
diff --git a/gas/testsuite/gas/i386/lfence-load.e
b/gas/testsuite/gas/i386/lfence-load.e
new file mode 100644
index 0000000000..1ee49da7fd
--- /dev/null
+++ b/gas/testsuite/gas/i386/lfence-load.e
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:??: Warning: `scas` changes flags which would affect control flow behavior
+.*:??: Warning: `cmps` changes flags which would affect control flow behavior
diff --git a/gas/testsuite/gas/i386/lfence-load.s
b/gas/testsuite/gas/i386/lfence-load.s
index b417ac644e..4b4aa1610b 100644
--- a/gas/testsuite/gas/i386/lfence-load.s
+++ b/gas/testsuite/gas/i386/lfence-load.s
@@ -4,6 +4,26 @@ _start:
  lgdt (%ebp)
  vmptrld (%ebp)
  vmclear (%ebp)
+ invpcid (%ebp), %edx
+ invlpg (%ebp)
+ clflush (%ebp)
+ clflushopt (%ebp)
+ clwb (%ebp)
+ cldemote (%ebp)
+ bndmk (%ebp), %bnd1
+ bndcl (%ebp), %bnd1
+ bndcu (%ebp), %bnd1
+ bndcn (%ebp), %bnd1
+ bndstx %bnd1, (%ebp)
+ bndldx (%ebp), %bnd1
+ prefetcht0 (%ebp)
+ prefetcht1 (%ebp)
+ prefetcht2 (%ebp)
+ prefetchw (%ebp)
+ pop %ds
+ popf
+ popa
+ xlatb (%ebx)
  fsts (%ebp)
  flds (%ebp)
  fistl (%ebp)
diff --git a/gas/testsuite/gas/i386/lfence-ret-a.d
b/gas/testsuite/gas/i386/lfence-ret-a.d
index 719cf1b472..aa35857664 100644
--- a/gas/testsuite/gas/i386/lfence-ret-a.d
+++ b/gas/testsuite/gas/i386/lfence-ret-a.d
@@ -9,10 +9,28 @@
 Disassembly of section .text:

 0+ <_start>:
+ +[a-f0-9]+: 66 83 0c 24 00        orw    \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c3                retw
+ +[a-f0-9]+: 66 83 0c 24 00        orw    \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c2 14 00          retw   \$0x14
  +[a-f0-9]+: 83 0c 24 00          orl    \$0x0,\(%esp\)
  +[a-f0-9]+: 0f ae e8              lfence
  +[a-f0-9]+: c3                    ret
  +[a-f0-9]+: 83 0c 24 00          orl    \$0x0,\(%esp\)
  +[a-f0-9]+: 0f ae e8              lfence
  +[a-f0-9]+: c2 1e 00              ret    \$0x1e
+ +[a-f0-9]+: 66 83 0c 24 00        orw    \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 cb                lretw
+ +[a-f0-9]+: 66 83 0c 24 00        orw    \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 ca 28 00          lretw  \$0x28
+ +[a-f0-9]+: 83 0c 24 00          orl    \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: cb                    lret
+ +[a-f0-9]+: 83 0c 24 00          orl    \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: ca 28 00              lret   \$0x28
 #pass
diff --git a/gas/testsuite/gas/i386/lfence-ret-b.d
b/gas/testsuite/gas/i386/lfence-ret-b.d
index e3914b9c28..77001c425e 100644
--- a/gas/testsuite/gas/i386/lfence-ret-b.d
+++ b/gas/testsuite/gas/i386/lfence-ret-b.d
@@ -9,6 +9,14 @@
 Disassembly of section .text:

 0+ <_start>:
+ +[a-f0-9]+: 66 f7 14 24          notw   \(%esp\)
+ +[a-f0-9]+: 66 f7 14 24          notw   \(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c3                retw
+ +[a-f0-9]+: 66 f7 14 24          notw   \(%esp\)
+ +[a-f0-9]+: 66 f7 14 24          notw   \(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c2 14 00          retw   \$0x14
  +[a-f0-9]+: f7 14 24              notl   \(%esp\)
  +[a-f0-9]+: f7 14 24              notl   \(%esp\)
  +[a-f0-9]+: 0f ae e8              lfence
@@ -17,4 +25,20 @@ Disassembly of section .text:
  +[a-f0-9]+: f7 14 24              notl   \(%esp\)
  +[a-f0-9]+: 0f ae e8              lfence
  +[a-f0-9]+: c2 1e 00              ret    \$0x1e
+ +[a-f0-9]+: 66 f7 14 24          notw   \(%esp\)
+ +[a-f0-9]+: 66 f7 14 24          notw   \(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 cb                lretw
+ +[a-f0-9]+: 66 f7 14 24          notw   \(%esp\)
+ +[a-f0-9]+: 66 f7 14 24          notw   \(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 ca 28 00          lretw  \$0x28
+ +[a-f0-9]+: f7 14 24              notl   \(%esp\)
+ +[a-f0-9]+: f7 14 24              notl   \(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: cb                    lret
+ +[a-f0-9]+: f7 14 24              notl   \(%esp\)
+ +[a-f0-9]+: f7 14 24              notl   \(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: ca 28 00              lret   \$0x28
 #pass
diff --git a/gas/testsuite/gas/i386/lfence-ret-c.d
b/gas/testsuite/gas/i386/lfence-ret-c.d
new file mode 100644
index 0000000000..fceb0eb182
--- /dev/null
+++ b/gas/testsuite/gas/i386/lfence-ret-c.d
@@ -0,0 +1,35 @@
+#source: lfence-ret.s
+#as: -mlfence-before-ret=or -mlfence-before-indirect-branch=all
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <_start>:
+ +[a-f0-9]+: 66 83 0c 24 00        orw    \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c3                retw
+ +[a-f0-9]+: 66 83 0c 24 00        orw    \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c2 14 00          retw   \$0x14
+ +[a-f0-9]+: 83 0c 24 00          orl    \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: c3                    ret
+ +[a-f0-9]+: 83 0c 24 00          orl    \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: c2 1e 00              ret    \$0x1e
+ +[a-f0-9]+: 66 83 0c 24 00        orw    \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 cb                lretw
+ +[a-f0-9]+: 66 83 0c 24 00        orw    \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 ca 28 00          lretw  \$0x28
+ +[a-f0-9]+: 83 0c 24 00          orl    \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: cb                    lret
+ +[a-f0-9]+: 83 0c 24 00          orl    \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: ca 28 00              lret   \$0x28
+#pass
diff --git a/gas/testsuite/gas/i386/lfence-ret-d.d
b/gas/testsuite/gas/i386/lfence-ret-d.d
new file mode 100644
index 0000000000..03f8f88fd7
--- /dev/null
+++ b/gas/testsuite/gas/i386/lfence-ret-d.d
@@ -0,0 +1,36 @@
+#source: lfence-ret.s
+#as: -mlfence-before-ret=shl
+#objdump: -dw
+#name: -mlfence-before-ret=shl
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <_start>:
+ +[a-f0-9]+: 66 c1 24 24 00        shlw   \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c3                retw
+ +[a-f0-9]+: 66 c1 24 24 00        shlw   \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c2 14 00          retw   \$0x14
+ +[a-f0-9]+: c1 24 24 00          shll   \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: c3                    ret
+ +[a-f0-9]+: c1 24 24 00          shll   \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: c2 1e 00              ret    \$0x1e
+ +[a-f0-9]+: 66 c1 24 24 00        shlw   \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 cb                lretw
+ +[a-f0-9]+: 66 c1 24 24 00        shlw   \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 ca 28 00          lretw  \$0x28
+ +[a-f0-9]+: c1 24 24 00          shll   \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: cb                    lret
+ +[a-f0-9]+: c1 24 24 00          shll   \$0x0,\(%esp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: ca 28 00              lret   \$0x28
+#pass
diff --git a/gas/testsuite/gas/i386/lfence-ret.s
b/gas/testsuite/gas/i386/lfence-ret.s
index 35c4e6eeaa..f27fa5839e 100644
--- a/gas/testsuite/gas/i386/lfence-ret.s
+++ b/gas/testsuite/gas/i386/lfence-ret.s
@@ -1,4 +1,10 @@
  .text
 _start:
+ retw
+ retw $20
  ret
  ret $30
+ lretw
+ lretw $40
+ lret
+ lret $40
diff --git a/gas/testsuite/gas/i386/x86-64-lfence-load.d
b/gas/testsuite/gas/i386/x86-64-lfence-load.d
index 4f6cd00edf..5cd764391d 100644
--- a/gas/testsuite/gas/i386/x86-64-lfence-load.d
+++ b/gas/testsuite/gas/i386/x86-64-lfence-load.d
@@ -1,5 +1,6 @@
 #as: -mlfence-after-load=yes
 #objdump: -dw
+#warning_output: lfence-load.e
 #name: x86-64 -mlfence-after-load=yes

 .*: +file format .*
@@ -15,6 +16,29 @@ Disassembly of section .text:
  +[a-f0-9]+: 0f c7 75 00          vmptrld 0x0\(%rbp\)
  +[a-f0-9]+: 0f ae e8              lfence
  +[a-f0-9]+: 66 0f c7 75 00        vmclear 0x0\(%rbp\)
+ +[a-f0-9]+: 66 0f 38 82 55 00    invpcid 0x0\(%rbp\),%rdx
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 67 0f 01 38          invlpg \(%eax\)
+ +[a-f0-9]+: 0f ae 7d 00          clflush 0x0\(%rbp\)
+ +[a-f0-9]+: 66 0f ae 7d 00        clflushopt 0x0\(%rbp\)
+ +[a-f0-9]+: 66 0f ae 75 00        clwb   0x0\(%rbp\)
+ +[a-f0-9]+: 0f 1c 45 00          cldemote 0x0\(%rbp\)
+ +[a-f0-9]+: f3 0f 1b 4d 00        bndmk  0x0\(%rbp\),%bnd1
+ +[a-f0-9]+: f3 0f 1a 4d 00        bndcl  0x0\(%rbp\),%bnd1
+ +[a-f0-9]+: f2 0f 1a 4d 00        bndcu  0x0\(%rbp\),%bnd1
+ +[a-f0-9]+: f2 0f 1b 4d 00        bndcn  0x0\(%rbp\),%bnd1
+ +[a-f0-9]+: 0f 1b 4d 00          bndstx %bnd1,0x0\(%rbp\)
+ +[a-f0-9]+: 0f 1a 4d 00          bndldx 0x0\(%rbp\),%bnd1
+ +[a-f0-9]+: 0f 18 4d 00          prefetcht0 0x0\(%rbp\)
+ +[a-f0-9]+: 0f 18 55 00          prefetcht1 0x0\(%rbp\)
+ +[a-f0-9]+: 0f 18 5d 00          prefetcht2 0x0\(%rbp\)
+ +[a-f0-9]+: 0f 0d 4d 00          prefetchw 0x0\(%rbp\)
+ +[a-f0-9]+: 0f a1                popq   %fs
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 9d                    popfq
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: d7                    xlat   %ds:\(%rbx\)
+ +[a-f0-9]+: 0f ae e8              lfence
  +[a-f0-9]+: d9 55 00              fsts   0x0\(%rbp\)
  +[a-f0-9]+: d9 45 00              flds   0x0\(%rbp\)
  +[a-f0-9]+: 0f ae e8              lfence
diff --git a/gas/testsuite/gas/i386/x86-64-lfence-load.s
b/gas/testsuite/gas/i386/x86-64-lfence-load.s
index 76d0886617..2a3ac6b7d2 100644
--- a/gas/testsuite/gas/i386/x86-64-lfence-load.s
+++ b/gas/testsuite/gas/i386/x86-64-lfence-load.s
@@ -4,6 +4,25 @@ _start:
  lgdt (%rbp)
  vmptrld (%rbp)
  vmclear (%rbp)
+ invpcid (%rbp), %rdx
+ invlpg (%eax)
+ clflush (%rbp)
+ clflushopt (%rbp)
+ clwb (%rbp)
+ cldemote (%rbp)
+ bndmk (%rbp), %bnd1
+ bndcl (%rbp), %bnd1
+ bndcu (%rbp), %bnd1
+ bndcn (%rbp), %bnd1
+ bndstx %bnd1, (%rbp)
+ bndldx (%rbp), %bnd1
+ prefetcht0 (%rbp)
+ prefetcht1 (%rbp)
+ prefetcht2 (%rbp)
+ prefetchw (%rbp)
+ pop %fs
+ popf
+ xlatb (%rbx)
  fsts (%rbp)
  flds (%rbp)
  fistl (%rbp)
diff --git a/gas/testsuite/gas/i386/x86-64-lfence-ret-a.d
b/gas/testsuite/gas/i386/x86-64-lfence-ret-a.d
index 26e5b48bec..345217b17c 100644
--- a/gas/testsuite/gas/i386/x86-64-lfence-ret-a.d
+++ b/gas/testsuite/gas/i386/x86-64-lfence-ret-a.d
@@ -1,6 +1,7 @@
-#source: lfence-ret.s
+#source: x86-64-lfence-ret.s
 #as: -mlfence-before-ret=or
-#objdump: -dw
+#warning_output: x86-64-lfence-ret.e
+#objdump: -dw -Mintel64
 #name: x86-64 -mlfence-before-ret=or

 .*: +file format .*
@@ -9,10 +10,40 @@
 Disassembly of section .text:

 0+ <_start>:
+ +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c3                data16 retq
+ +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c2 14 00          data16 retq \$0x14
  +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
  +[a-f0-9]+: 0f ae e8              lfence
  +[a-f0-9]+: c3                    retq
  +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
  +[a-f0-9]+: 0f ae e8              lfence
  +[a-f0-9]+: c2 1e 00              retq   \$0x1e
+ +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 48 c3              data16 rex.W retq
+ +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 48 c2 28 00        data16 rex.W retq \$0x28
+ +[a-f0-9]+: 66 83 0c 24 00        orw    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 cb                lretw
+ +[a-f0-9]+: 66 83 0c 24 00        orw    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 ca 28 00          lretw  \$0x28
+ +[a-f0-9]+: 83 0c 24 00          orl    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: cb                    lret
+ +[a-f0-9]+: 83 0c 24 00          orl    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: ca 28 00              lret   \$0x28
+ +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 48 cb                lretq
+ +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 48 ca 28 00          lretq  \$0x28
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-lfence-ret-b.d
b/gas/testsuite/gas/i386/x86-64-lfence-ret-b.d
index 340488831d..3947660fea 100644
--- a/gas/testsuite/gas/i386/x86-64-lfence-ret-b.d
+++ b/gas/testsuite/gas/i386/x86-64-lfence-ret-b.d
@@ -1,6 +1,7 @@
-#source: lfence-ret.s
+#source: x86-64-lfence-ret.s
 #as: -mlfence-before-ret=not
-#objdump: -dw
+#warning_output: x86-64-lfence-ret.e
+#objdump: -dw -Mintel64
 #name: x86-64 -mlfence-before-ret=not

 .*: +file format .*
@@ -9,6 +10,14 @@
 Disassembly of section .text:

 0+ <_start>:
+ +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
+ +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c3                data16 retq
+ +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
+ +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c2 14 00          data16 retq \$0x14
  +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
  +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
  +[a-f0-9]+: 0f ae e8              lfence
@@ -17,4 +26,36 @@ Disassembly of section .text:
  +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
  +[a-f0-9]+: 0f ae e8              lfence
  +[a-f0-9]+: c2 1e 00              retq   \$0x1e
+ +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
+ +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 48 c3              data16 rex.W retq
+ +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
+ +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 48 c2 28 00        data16 rex.W retq \$0x28
+ +[a-f0-9]+: 66 f7 14 24          notw   \(%rsp\)
+ +[a-f0-9]+: 66 f7 14 24          notw   \(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 cb                lretw
+ +[a-f0-9]+: 66 f7 14 24          notw   \(%rsp\)
+ +[a-f0-9]+: 66 f7 14 24          notw   \(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 ca 28 00          lretw  \$0x28
+ +[a-f0-9]+: f7 14 24              notl   \(%rsp\)
+ +[a-f0-9]+: f7 14 24              notl   \(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: cb                    lret
+ +[a-f0-9]+: f7 14 24              notl   \(%rsp\)
+ +[a-f0-9]+: f7 14 24              notl   \(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: ca 28 00              lret   \$0x28
+ +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
+ +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 48 cb                lretq
+ +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
+ +[a-f0-9]+: 48 f7 14 24          notq   \(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 48 ca 28 00          lretq  \$0x28
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-lfence-ret-c.d
b/gas/testsuite/gas/i386/x86-64-lfence-ret-c.d
new file mode 100644
index 0000000000..cd89a95bc4
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-lfence-ret-c.d
@@ -0,0 +1,48 @@
+#source: x86-64-lfence-ret.s
+#as: -mlfence-before-ret=or -mlfence-before-indirect-branch=all
+#warning_output: x86-64-lfence-ret.e
+#objdump: -dw -Mintel64
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <_start>:
+ +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c3                data16 retq
+ +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c2 14 00          data16 retq \$0x14
+ +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: c3                    retq
+ +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: c2 1e 00              retq   \$0x1e
+ +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 48 c3              data16 rex.W retq
+ +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 48 c2 28 00        data16 rex.W retq \$0x28
+ +[a-f0-9]+: 66 83 0c 24 00        orw    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 cb                lretw
+ +[a-f0-9]+: 66 83 0c 24 00        orw    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 ca 28 00          lretw  \$0x28
+ +[a-f0-9]+: 83 0c 24 00          orl    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: cb                    lret
+ +[a-f0-9]+: 83 0c 24 00          orl    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: ca 28 00              lret   \$0x28
+ +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 48 cb                lretq
+ +[a-f0-9]+: 48 83 0c 24 00        orq    \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 48 ca 28 00          lretq  \$0x28
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-lfence-ret-d.d
b/gas/testsuite/gas/i386/x86-64-lfence-ret-d.d
new file mode 100644
index 0000000000..593b889435
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-lfence-ret-d.d
@@ -0,0 +1,49 @@
+#source: x86-64-lfence-ret.s
+#as: -mlfence-before-ret=shl
+#warning_output: x86-64-lfence-ret.e
+#objdump: -dw -Mintel64
+#name: x86-64 -mlfence-before-ret=shl
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <_start>:
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c3                data16 retq
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c2 14 00          data16 retq \$0x14
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: c3                    retq
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: c2 1e 00              retq   \$0x1e
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 48 c3              data16 rex.W retq
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 48 c2 28 00        data16 rex.W retq \$0x28
+ +[a-f0-9]+: 66 c1 24 24 00        shlw   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 cb                lretw
+ +[a-f0-9]+: 66 c1 24 24 00        shlw   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 ca 28 00          lretw  \$0x28
+ +[a-f0-9]+: c1 24 24 00          shll   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: cb                    lret
+ +[a-f0-9]+: c1 24 24 00          shll   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: ca 28 00              lret   \$0x28
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 48 cb                lretq
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 48 ca 28 00          lretq  \$0x28
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-lfence-ret-e.d
b/gas/testsuite/gas/i386/x86-64-lfence-ret-e.d
new file mode 100644
index 0000000000..b4d229654c
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-lfence-ret-e.d
@@ -0,0 +1,49 @@
+#source: x86-64-lfence-ret.s
+#as: -mlfence-before-ret=shl
+#warning_output: x86-64-lfence-ret.e
+#objdump: -dw -Mintel64
+#name: x86-64 -mlfence-before-ret=yes
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <_start>:
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c3                data16 retq
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 c2 14 00          data16 retq \$0x14
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: c3                    retq
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: c2 1e 00              retq   \$0x1e
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 48 c3              data16 rex.W retq
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 48 c2 28 00        data16 rex.W retq \$0x28
+ +[a-f0-9]+: 66 c1 24 24 00        shlw   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 cb                lretw
+ +[a-f0-9]+: 66 c1 24 24 00        shlw   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 66 ca 28 00          lretw  \$0x28
+ +[a-f0-9]+: c1 24 24 00          shll   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: cb                    lret
+ +[a-f0-9]+: c1 24 24 00          shll   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: ca 28 00              lret   \$0x28
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 48 cb                lretq
+ +[a-f0-9]+: 48 c1 24 24 00        shlq   \$0x0,\(%rsp\)
+ +[a-f0-9]+: 0f ae e8              lfence
+ +[a-f0-9]+: 48 ca 28 00          lretq  \$0x28
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-lfence-ret.e
b/gas/testsuite/gas/i386/x86-64-lfence-ret.e
new file mode 100644
index 0000000000..13730e50e6
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-lfence-ret.e
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:??: Warning: no instruction mnemonic suffix given and no register
operands; using default for `lret'
+.*:??: Warning: no instruction mnemonic suffix given and no register
operands; using default for `lret'
diff --git a/gas/testsuite/gas/i386/x86-64-lfence-ret.s
b/gas/testsuite/gas/i386/x86-64-lfence-ret.s
new file mode 100644
index 0000000000..986239c222
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-lfence-ret.s
@@ -0,0 +1,14 @@
+ .text
+_start:
+ retw
+ retw $20
+ ret
+ ret $30
+ data16 rex.w ret
+ data16 rex.w ret $40
+ lretw
+ lretw $40
+ lret
+ lret $40
+ lretq
+ lretq $40
-- 
2.18.1


-- 
BR,
Hongtao


More information about the Binutils mailing list