Add option -mfence-as-lock-add=[no|yes].
authorAndrew Senkevich <andrew.senkevich@intel.com>
Fri, 29 Jan 2016 12:46:50 +0000 (15:46 +0300)
committerAndrew Senkevich <andrew.senkevich@intel.com>
Fri, 29 Jan 2016 12:46:50 +0000 (15:46 +0300)
With -mfence-as-lock-add=yes lfence, mfence and sfence will be encoded
as lock addl $0x0, (%{r,e}sp).

gas/:

    * config/tc-i386.c (avoid_fence): New.
    (output_insn): Encode as lock addl $0x0, (%{r,e}sp) if avoid_fence
    is true.
    (OPTION_FENCE_AS_LOCK_ADD): New.
    (md_longopts): Add -mfence-as-lock-add.
    (md_parse_option): Handle -mfence-as-lock-add.
    (md_show_usage): Add -mfence-as-lock-add=[no|yes].
    * doc/c-i386.texi (-mfence-as-lock-add): Document.

gas/testsuite/:

    * gas/i386/i386.exp: Run new tests.
    * gas/i386/fence-as-lock-add.s: New.
    * gas/i386/fence-as-lock-add-yes.d: Likewise.
    * gas/i386/fence-as-lock-add-no.d: Likewise.
    * gas/i386/x86-64-fence-as-lock-add-yes.d: Likewise.
    * gas/i386/x86-64-fence-as-lock-add-no.d: Likewise.

gas/ChangeLog
gas/config/tc-i386.c
gas/doc/c-i386.texi
gas/testsuite/gas/i386/fence-as-lock-add-no.d [new file with mode: 0644]
gas/testsuite/gas/i386/fence-as-lock-add-yes.d [new file with mode: 0644]
gas/testsuite/gas/i386/fence-as-lock-add.s [new file with mode: 0644]
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/x86-64-fence-as-lock-add-no.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-fence-as-lock-add-yes.d [new file with mode: 0644]

index b210227fc030e9442a1e82251a3397d58201219a..a4bfa720c1e857679fc70c343136e8aea1ab894d 100644 (file)
@@ -1,3 +1,21 @@
+2016-01-29  Andrew Senkevich  <andrew.senkevich@intel.com>
+           H.J. Lu  <hongjiu.lu@intel.com>
+
+       * config/tc-i386.c (avoid_fence): New.
+       (output_insn): Encode as lock addl $0x0, (%{r,e}sp) if avoid_fence
+       is true.
+       (OPTION_FENCE_AS_LOCK_ADD): New.
+       (md_longopts): Add -mfence-as-lock-add.
+       (md_parse_option): Handle -mfence-as-lock-add.
+       (md_show_usage): Add -mfence-as-lock-add=[no|yes].
+       * doc/c-i386.texi (-mfence-as-lock-add): Document.
+       * gas/i386/i386.exp: Run new tests.
+       * gas/i386/fence-as-lock-add.s: New.
+       * gas/i386/fence-as-lock-add-yes.d: Likewise.
+       * gas/i386/fence-as-lock-add-no.d: Likewise.
+       * gas/i386/x86-64-fence-as-lock-add-yes.d: Likewise.
+       * gas/i386/x86-64-fence-as-lock-add-no.d: Likewise.
+
 2016-01-27  H.J. Lu  <hongjiu.lu@intel.com>
 
        * configure.ac (compressed_debug_sections): Remove trailing `]'.
index 62f247c7af48d34908477fea6a46a144e28f8e26..3a98b21d955acf7d5f49a49c2bcb03e084a64204 100644 (file)
@@ -552,6 +552,10 @@ static int allow_index_reg = 0;
    specified explicitly.  */
 static int omit_lock_prefix = 0;
 
+/* 1 if the assembler should encode lfence, mfence, and sfence as
+   "lock addl $0, (%{re}sp)".  */
+static int avoid_fence = 0;
+
 static enum check_kind
   {
     check_none = 0,
@@ -6956,6 +6960,22 @@ output_insn (void)
       unsigned int j;
       unsigned int prefix;
 
+      if (avoid_fence
+         && i.tm.base_opcode == 0xfae
+         && i.operands == 1
+         && i.imm_operands == 1
+         && (i.op[0].imms->X_add_number == 0xe8
+             || i.op[0].imms->X_add_number == 0xf0
+             || i.op[0].imms->X_add_number == 0xf8))
+        {
+          /* Encode lfence, mfence, and sfence as
+             f0 83 04 24 00   lock addl $0x0, (%{re}sp).  */
+          offsetT val = 0x240483f0ULL;
+          p = frag_more (5);
+          md_number_to_chars (p, val, 5);
+          return;
+        }
+
       /* Some processors fail on LOCK prefix. This options makes
         assembler ignore LOCK prefix and serves as a workaround.  */
       if (omit_lock_prefix)
@@ -9622,6 +9642,7 @@ const char *md_shortopts = "qn";
 #define OPTION_MSHARED (OPTION_MD_BASE + 21)
 #define OPTION_MAMD64 (OPTION_MD_BASE + 22)
 #define OPTION_MINTEL64 (OPTION_MD_BASE + 23)
+#define OPTION_MFENCE_AS_LOCK_ADD (OPTION_MD_BASE + 24)
 
 struct option md_longopts[] =
 {
@@ -9653,6 +9674,7 @@ struct option md_longopts[] =
   {"mbig-obj", no_argument, NULL, OPTION_MBIG_OBJ},
 #endif
   {"momit-lock-prefix", required_argument, NULL, OPTION_MOMIT_LOCK_PREFIX},
+  {"mfence-as-lock-add", required_argument, NULL, OPTION_MFENCE_AS_LOCK_ADD},
   {"mevexrcig", required_argument, NULL, OPTION_MEVEXRCIG},
   {"mamd64", no_argument, NULL, OPTION_MAMD64},
   {"mintel64", no_argument, NULL, OPTION_MINTEL64},
@@ -9972,6 +9994,15 @@ md_parse_option (int c, char *arg)
         as_fatal (_("invalid -momit-lock-prefix= option: `%s'"), arg);
       break;
 
+    case OPTION_MFENCE_AS_LOCK_ADD:
+      if (strcasecmp (arg, "yes") == 0)
+        avoid_fence = 1;
+      else if (strcasecmp (arg, "no") == 0)
+        avoid_fence = 0;
+      else
+        as_fatal (_("invalid -mfence-as-lock-add= option: `%s'"), arg);
+      break;
+
     case OPTION_MAMD64:
       cpu_arch_flags.bitfield.cpuamd64 = 1;
       cpu_arch_flags.bitfield.cpuintel64 = 0;
@@ -10152,6 +10183,10 @@ md_show_usage (FILE *stream)
   -momit-lock-prefix=[no|yes]\n\
                           strip all lock prefixes\n"));
   fprintf (stream, _("\
+  -mfence-as-lock-add=[no|yes]\n\
+                          encode lfence, mfence and sfence as\n\
+                           lock addl $0x0, (%%{re}sp)\n"));
+  fprintf (stream, _("\
   -mamd64                 accept only AMD64 ISA\n"));
   fprintf (stream, _("\
   -mintel64               accept only Intel64 ISA\n"));
index 2f6485df4786ae63823c5f698d4f087b0cdfa3d1..357851a3126141aa805eba864d48437ea2a6a2dd 100644 (file)
@@ -327,6 +327,18 @@ single-thread computers
 @option{-momit-lock-prefix=@var{no}} will encode lock prefix as usual,
 which is the default.
 
+@cindex @samp{-mfence-as-lock-add=} option, i386
+@cindex @samp{-mfence-as-lock-add=} option, x86-64
+@item -mfence-as-lock-add=@var{no}
+@itemx -mfence-as-lock-add=@var{yes}
+These options control how the assembler should encode lfence, mfence and
+sfence.
+@option{-mfence-as-lock-add=@var{yes}} will encode lfence, mfence and
+sfence as @samp{lock addl $0x0, (%rsp)} in 64-bit mode and
+@samp{lock addl $0x0, (%esp)} in 32-bit mode.
+@option{-mfence-as-lock-add=@var{no}} will encode lfence, mfence and
+sfence as usual, which is the default.
+
 @cindex @samp{-mevexrcig=} option, i386
 @cindex @samp{-mevexrcig=} option, x86-64
 @item -mevexrcig=@var{rne}
diff --git a/gas/testsuite/gas/i386/fence-as-lock-add-no.d b/gas/testsuite/gas/i386/fence-as-lock-add-no.d
new file mode 100644 (file)
index 0000000..2083066
--- /dev/null
@@ -0,0 +1,14 @@
+#source: fence-as-lock-add.s
+#as: -mfence-as-lock-add=no
+#objdump: -dw
+#name: i386  fence as lock add = no
+
+.*: +file format .*i386.*
+
+Disassembly of section .text:
+
+0+ <main>:
+[   ]*[a-f0-9]+:       0f ae e8[ ]*    lfence 
+[   ]*[a-f0-9]+:       0f ae f0[ ]*    mfence 
+[   ]*[a-f0-9]+:       0f ae f8[ ]*    sfence 
+#pass
diff --git a/gas/testsuite/gas/i386/fence-as-lock-add-yes.d b/gas/testsuite/gas/i386/fence-as-lock-add-yes.d
new file mode 100644 (file)
index 0000000..4ee6300
--- /dev/null
@@ -0,0 +1,14 @@
+#source: fence-as-lock-add.s
+#as: -mfence-as-lock-add=yes
+#objdump: -dw
+#name: i386  fence as lock add = yes
+
+.*: +file format .*i386.*
+
+Disassembly of section .text:
+
+0+ <main>:
+[   ]*[a-f0-9]+:       f0 83 04 24 00[ ]*      lock addl \$0x0,\(%esp\)
+[   ]*[a-f0-9]+:       f0 83 04 24 00[ ]*      lock addl \$0x0,\(%esp\)
+[   ]*[a-f0-9]+:       f0 83 04 24 00[ ]*      lock addl \$0x0,\(%esp\)
+#pass
diff --git a/gas/testsuite/gas/i386/fence-as-lock-add.s b/gas/testsuite/gas/i386/fence-as-lock-add.s
new file mode 100644 (file)
index 0000000..5ecb1d9
--- /dev/null
@@ -0,0 +1,6 @@
+       .text
+.globl main
+main:
+       lfence
+       mfence
+       sfence
index e23a4e59685ea5ec7b3596b5a78f226c918724f8..b9144c4a9d48942a0fd3fb31ef01798b0af646a9 100644 (file)
@@ -303,6 +303,8 @@ if [expr ([istarget "i*86-*-*"] ||  [istarget "x86_64-*-*"]) && [gas_32_check]]
     run_dump_test "avx512dq_vl"
     run_dump_test "omit-lock-yes"
     run_dump_test "omit-lock-no"
+    run_dump_test "fence-as-lock-add-yes"
+    run_dump_test "fence-as-lock-add-no"
     run_dump_test "avx512dq-rcigrd-intel"
     run_dump_test "avx512dq-rcigrd"
     run_dump_test "avx512dq-rcigrne-intel"
@@ -731,6 +733,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
     run_dump_test "x86-64-mwaitx-bdver4"
     run_list_test "x86-64-mwaitx-reg"
     run_dump_test "x86-64-ospke"
+    run_dump_test "x86-64-fence-as-lock-add-yes"
+    run_dump_test "x86-64-fence-as-lock-add-no"
 
     if { ![istarget "*-*-aix*"]
       && ![istarget "*-*-beos*"]
diff --git a/gas/testsuite/gas/i386/x86-64-fence-as-lock-add-no.d b/gas/testsuite/gas/i386/x86-64-fence-as-lock-add-no.d
new file mode 100644 (file)
index 0000000..9277448
--- /dev/null
@@ -0,0 +1,14 @@
+#source: fence-as-lock-add.s
+#as: -mfence-as-lock-add=no
+#objdump: -dw
+#name: x86-64 fence as lock add = no
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <main>:
+[   ]*[a-f0-9]+:       0f ae e8[ ]*    lfence 
+[   ]*[a-f0-9]+:       0f ae f0[ ]*    mfence 
+[   ]*[a-f0-9]+:       0f ae f8[ ]*    sfence 
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-fence-as-lock-add-yes.d b/gas/testsuite/gas/i386/x86-64-fence-as-lock-add-yes.d
new file mode 100644 (file)
index 0000000..9451cd8
--- /dev/null
@@ -0,0 +1,14 @@
+#source: fence-as-lock-add.s
+#as: -mfence-as-lock-add=yes
+#objdump: -dw
+#name: x86-64 fence as lock add = yes
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <main>:
+[   ]*[a-f0-9]+:       f0 83 04 24 00[ ]*      lock addl \$0x0,\(%rsp\)
+[   ]*[a-f0-9]+:       f0 83 04 24 00[ ]*      lock addl \$0x0,\(%rsp\)
+[   ]*[a-f0-9]+:       f0 83 04 24 00[ ]*      lock addl \$0x0,\(%rsp\)
+#pass