This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] x86: Apply standalone prefixes to the following instruction


On Fri, Jul 19, 2019 at 2:31 AM Florian Weimer <fweimer@redhat.com> wrote:
>
> * H. J. Lu:
>
> > Standalone prefixes should be applied to the following instruction,
> > instead of being treated as regular instructions.  An error should be
> > issued when a standalone prefix is at the end of source or isn't
> > followed by an instruction in the same section.
>
> glibc used to do this:
>
> | #define __arch_c_compare_and_exchange_val_8_acq(mem, newval, oldval) \
> |   ({ __typeof (*mem) ret;                                                    \
> |     __asm __volatile ("cmpl $0, %%fs:%P5\n\t"                                \
> |                      "je 0f\n\t"                                             \
> |                      "lock\n"                                                \
> |                       "0:\tcmpxchgb %b2, %1"                                 \
> |                       : "=a" (ret), "=m" (*mem)                              \
> |                       : "q" (newval), "m" (*mem), "0" (oldval),              \
> |                         "i" (offsetof (tcbhead_t, multiple_threads)));       \
> |      ret; })
>
> Will this still work?
>

":" between prefixes and instruction is a special case.   Here is the updated
patch to add i386_frob_colon so that i386 can output all pending stand-alone
prefixes when seeing a colon in the same frag.

-- 
H.J.
From e72df470f74cd3f716eb7a0fb78979faccc27c69 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 18 Jul 2019 14:57:37 -0700
Subject: [PATCH] x86: Apply standalone prefixes to the following instruction

Standalone prefixes should be applied to the following instruction,
instead of being treated as regular instructions.  An error should be
issued when a standalone prefix is at the end of source or isn't
followed by an instruction in the same section.  tc_frob_colon is
added to colon so that i386 can output all pending stand-alone prefixes
when seeing a colon in the same frag.

	PR gas/24821
	* symbols.c (colon): Call tc_frob_colon if defined.
	* config/tc-i386.c (_i386_insn): Add prev.
	(check_hle): Also check i.prev.name for prefix name.
	(i386_frob_colon): New function.
	(i386_md_end): Likewise.
	(md_assemble): Apply the standalone prefix to the current
	instruction.  Issue an error if a standalone prefix isn't
	followed by an instruction in the same section.
	(output_insn): Remember the standalone prefix and add it to the
	following instruction.
	* config/tc-i386.h (i386_md_end): New.
	(md_end): Likewise.
	(i386_frob_colon): Likewise.
	(tc_frob_colon): Likewise.
	* testsuite/gas/i386/i386.exp: Run prefix-2, prefix-3, prefix-4,
	x86-64-prefix-3 and x86-64-prefix-4.
	* testsuite/gas/i386/ilp32/rex.d: Updated.
	* testsuite/gas/i386/omit-lock-no.d: Likewise.
	* testsuite/gas/i386/omit-lock-yes.d: Likewise.
	* testsuite/gas/i386/rex.d: Likewise.
	* testsuite/gas/i386/white.l: Likewise.
	* testsuite/gas/i386/omit-lock.s: Replace standalone lock
	with ds.
	* testsuite/gas/i386/prefix-2.l: New file.
	* testsuite/gas/i386/prefix-2.s: Likewise.
	* testsuite/gas/i386/prefix-3.d: Likewise.
	* testsuite/gas/i386/prefix-4.s: Likewise.
	* testsuite/gas/i386/prefix-4.d: Likewise.
	* testsuite/gas/i386/prefix-3.s: Likewise.
	* testsuite/gas/i386/x86-64-prefix-3.d: Likewise.
	* testsuite/gas/i386/x86-64-prefix-4.d: Likewise.
	* testsuite/gas/i386/rex.s: Add nop after REX prefixes.
---
 gas/config/tc-i386.c                     | 140 +++++++++++++++++++++--
 gas/config/tc-i386.h                     |   6 +
 gas/symbols.c                            |   4 +
 gas/testsuite/gas/i386/i386.exp          |   8 ++
 gas/testsuite/gas/i386/ilp32/rex.d       |  32 +++---
 gas/testsuite/gas/i386/omit-lock-no.d    |   2 +-
 gas/testsuite/gas/i386/omit-lock-yes.d   |   2 +-
 gas/testsuite/gas/i386/omit-lock.s       |   2 +-
 gas/testsuite/gas/i386/prefix-2.l        |   7 ++
 gas/testsuite/gas/i386/prefix-2.s        |  16 +++
 gas/testsuite/gas/i386/prefix-3.d        |  13 +++
 gas/testsuite/gas/i386/prefix-3.s        |  20 ++++
 gas/testsuite/gas/i386/prefix-4.d        |  12 ++
 gas/testsuite/gas/i386/prefix-4.s        |  13 +++
 gas/testsuite/gas/i386/rex.d             |  32 +++---
 gas/testsuite/gas/i386/rex.s             |  19 ++-
 gas/testsuite/gas/i386/white.l           |   4 +-
 gas/testsuite/gas/i386/x86-64-prefix-3.d |  17 +++
 gas/testsuite/gas/i386/x86-64-prefix-4.d |  15 +++
 19 files changed, 318 insertions(+), 46 deletions(-)
 create mode 100644 gas/testsuite/gas/i386/prefix-2.l
 create mode 100644 gas/testsuite/gas/i386/prefix-2.s
 create mode 100644 gas/testsuite/gas/i386/prefix-3.d
 create mode 100644 gas/testsuite/gas/i386/prefix-3.s
 create mode 100644 gas/testsuite/gas/i386/prefix-4.d
 create mode 100644 gas/testsuite/gas/i386/prefix-4.s
 create mode 100644 gas/testsuite/gas/i386/x86-64-prefix-3.d
 create mode 100644 gas/testsuite/gas/i386/x86-64-prefix-4.d

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 2710dcec72..31200b11cb 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -431,6 +431,25 @@ struct _i386_insn
 
     /* Error message.  */
     enum i386_error error;
+
+    /* Information of previous instruction.  */
+    struct
+      {
+	fragS *frag;
+	const char *name;
+	const char *file;
+	unsigned int line;
+	int error_count;
+	enum
+	  {
+	    insn_unknown,
+	    prefix_notrack,
+	    prefix_hle,
+	    prefix_bnd,
+	    prefix_rep,
+	    prefix_other
+	  } type;
+      } prev;
   };
 
 typedef struct _i386_insn i386_insn;
@@ -3902,7 +3921,8 @@ check_hle (void)
       abort ();
     case HLEPrefixNone:
       as_bad (_("invalid instruction `%s' after `%s'"),
-	      i.tm.name, i.hle_prefix);
+	      i.tm.name,
+	      i.hle_prefix ? i.hle_prefix : i.prev.name);
       return 0;
     case HLEPrefixLock:
       if (i.prefix[LOCK_PREFIX])
@@ -4230,6 +4250,39 @@ optimize_encoding (void)
     }
 }
 
+/* Additioanl processing for colon.  */
+
+void
+i386_frob_colon (const char *name ATTRIBUTE_UNUSED)
+{
+  if (i.prev.name
+      && i.prev.type != insn_unknown
+      && i.prev.frag == frag_now)
+    {
+      /* Output all pending stand-alone prefixes when seeing a colon in
+	 the same frag.  */
+      unsigned char *q;
+      unsigned int j;
+      for (j = ARRAY_SIZE (i.prefix), q = i.prefix; j > 0; j--, q++)
+	if (*q)
+	  FRAG_APPEND_1_CHAR (*q);
+      i.prev.name = NULL;
+    }
+}
+
+/* Issue an error if there is a stand-alone prefix at the end of
+   source.  */
+
+void
+i386_md_end (void)
+{
+  if (i.prev.name
+      && i.prev.type != insn_unknown
+      && i.prev.error_count == had_errors ())
+    as_bad_where (i.prev.file, i.prev.line,
+		  _("stand-alone `%s' prefix"), i.prev.name);
+}
+
 /* This is the guts of the machine-dependent assembler.  LINE points to a
    machine dependent instruction.  This function is supposed to emit
    the frags/bytes it assembles to.  */
@@ -4242,7 +4295,30 @@ md_assemble (char *line)
   const insn_template *t;
 
   /* Initialize globals.  */
-  memset (&i, '\0', sizeof (i));
+  if (i.prev.name
+      && i.prev.type != insn_unknown
+      && i.prev.error_count == had_errors ())
+    {
+      /* If there are no new errors since the previous stand-alone
+	 prefix, add prefix to the current instruction.  */
+      const fragS *fr;
+
+      for (fr = i.prev.frag; fr && fr != frag_now; fr = fr->fr_next)
+	;
+
+      if (fr != frag_now)
+	{
+	  /* Issue an error if the current instruction isn't in the
+	     same section.  */
+	  as_bad_where (i.prev.file, i.prev.line,
+			_("stand-alone `%s' prefix"),
+			i.prev.name);
+	  /* Discard the previous stand-alone prefix.  */
+	  memset (&i, '\0', sizeof (i));
+	}
+    }
+  else
+    memset (&i, '\0', sizeof (i));
   for (j = 0; j < MAX_OPERANDS; j++)
     i.reloc[j] = NO_RELOC;
   memset (disp_expressions, '\0', sizeof (disp_expressions));
@@ -4344,16 +4420,22 @@ md_assemble (char *line)
       return;
 
   /* Check if REP prefix is OK.  */
-  if (i.rep_prefix && !i.tm.opcode_modifier.repprefixok)
+  if ((i.rep_prefix
+       || (i.prev.name
+	   && i.prev.type == prefix_rep
+	   && !i.tm.opcode_modifier.isprefix))
+      && !i.tm.opcode_modifier.repprefixok)
     {
       as_bad (_("invalid instruction `%s' after `%s'"),
-		i.tm.name, i.rep_prefix);
+		i.tm.name,
+		i.rep_prefix ? i.rep_prefix : i.prev.name);
       return;
     }
 
   /* Check for lock without a lockable instruction.  Destination operand
      must be memory unless it is xchg (0x86).  */
   if (i.prefix[LOCK_PREFIX]
+      && !i.tm.opcode_modifier.isprefix
       && (!i.tm.opcode_modifier.islockable
 	  || i.mem_operands == 0
 	  || (i.tm.base_opcode != 0x86
@@ -4371,15 +4453,25 @@ md_assemble (char *line)
     }
 
   /* Check if HLE prefix is OK.  */
-  if (i.hle_prefix && !check_hle ())
+  if ((i.hle_prefix
+       || (i.prev.name
+	   && i.prev.type == prefix_hle
+	   && !i.tm.opcode_modifier.isprefix))
+      && !check_hle ())
     return;
 
   /* Check BND prefix.  */
-  if (i.bnd_prefix && !i.tm.opcode_modifier.bndprefixok)
+  if ((i.bnd_prefix
+       || (i.prev.name
+	   && i.prev.type == prefix_bnd
+	   && !i.tm.opcode_modifier.isprefix))
+      && !i.tm.opcode_modifier.bndprefixok)
     as_bad (_("expecting valid branch instruction after `bnd'"));
 
   /* Check NOTRACK prefix.  */
-  if (i.notrack_prefix && !i.tm.opcode_modifier.notrackprefixok)
+  if ((i.notrack_prefix
+       || (i.prev.name && i.prev.type == prefix_notrack))
+      && !i.tm.opcode_modifier.notrackprefixok)
     as_bad (_("expecting indirect branch instruction after `notrack'"));
 
   if (i.tm.cpu_flags.bitfield.cpumpx)
@@ -8314,6 +8406,40 @@ output_insn (void)
   insn_start_frag = frag_now;
   insn_start_off = frag_now_fix ();
 
+  if (i.tm.opcode_modifier.isprefix && i.tm.opcode_length == 1)
+    {
+      /* Remember the stand-alone prefix.  */
+      i.prev.name = i.tm.name;
+      i.prev.frag = insn_start_frag;
+      i.prev.file = as_where (&i.prev.line);
+
+      /* Save the current error count.  */
+      i.prev.error_count = had_errors ();
+
+      /* Add the prefix to the following instruction.  */
+      i.prev.type = prefix_other;
+      switch (add_prefix (i.tm.base_opcode))
+	{
+	case PREFIX_DS:
+	  if (i.tm.cpu_flags.bitfield.cpuibt)
+	    i.prev.type = prefix_notrack;
+	  break;
+	case PREFIX_REP:
+	  if (i.tm.cpu_flags.bitfield.cpuhle)
+	    i.prev.type = prefix_hle;
+	  else if (i.tm.cpu_flags.bitfield.cpumpx)
+	    i.prev.type = prefix_bnd;
+	  else
+	    i.prev.type = prefix_rep;
+	  break;
+	default:
+	  break;
+	}
+      return;
+    }
+  else
+    i.prev.name = NULL;
+
   /* Output jumps.  */
   if (i.tm.opcode_modifier.jump)
     output_branch ();
diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h
index b02a25671f..8d1a4d09cf 100644
--- a/gas/config/tc-i386.h
+++ b/gas/config/tc-i386.h
@@ -194,6 +194,12 @@ extern int i386_need_index_operator (void);
 extern const struct relax_type md_relax_table[];
 #define TC_GENERIC_RELAX_TABLE md_relax_table
 
+extern void i386_md_end (void);
+#define md_end() i386_md_end ()
+
+extern void i386_frob_colon (const char *);
+#define tc_frob_colon(name) i386_frob_colon (name)
+
 extern int optimize_align_code;
 
 #define md_do_align(n, fill, len, max, around)				\
diff --git a/gas/symbols.c b/gas/symbols.c
index 918028f875..2a3efd7ee0 100644
--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -458,6 +458,10 @@ colon (/* Just seen "x:" - rattle symbols & frags.  */
   obj_frob_colon (sym_name);
 #endif
 
+#ifdef tc_frob_colon
+  tc_frob_colon (sym_name);
+#endif
+
   if ((symbolP = symbol_find (sym_name)) != 0)
     {
       S_CLEAR_WEAKREFR (symbolP);
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index 988f3fffb2..2d5c147471 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -567,6 +567,10 @@ if [expr ([istarget "i*86-*-*"] ||  [istarget "x86_64-*-*"]) && [gas_32_check]]
 	run_dump_test "property-1"
 	run_dump_test "property-2"
 
+	run_list_test "prefix-2"
+	run_dump_test "prefix-3"
+	run_dump_test "prefix-4"
+
 	if { [gas_64_check] } then {
 	    run_dump_test "att-regs"
 	    run_dump_test "intel-regs"
@@ -1088,6 +1092,10 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
 	run_dump_test "evex-no-scale-64"
 	run_dump_test "x86-64-property-1"
 	run_dump_test "x86-64-property-2"
+
+	run_list_test "prefix-2"
+	run_dump_test "x86-64-prefix-3"
+	run_dump_test "x86-64-prefix-4"
     }
 
     set ASFLAGS "$old_ASFLAGS"
diff --git a/gas/testsuite/gas/i386/ilp32/rex.d b/gas/testsuite/gas/i386/ilp32/rex.d
index d8bc1b528c..189461961a 100644
--- a/gas/testsuite/gas/i386/ilp32/rex.d
+++ b/gas/testsuite/gas/i386/ilp32/rex.d
@@ -28,20 +28,20 @@ Disassembly of section .text:
 [	 ]*[0-9a-f]+:[	 ]+9b dd 30\s+fsave\s+\(%rax\)
 [	 ]*[0-9a-f]+:[	 ]+9b 41 dd 30\s+fsave\s+\(%r8\)
 [	 ]*[0-9a-f]+:[	 ]+40 c5 f9 28 00[	 ]+rex vmovapd \(%rax\),%xmm0
-[	 ]*[0-9a-f]+:[	 ]+40[	 ]+rex
-[	 ]*[0-9a-f]+:[	 ]+41[	 ]+rex.B
-[	 ]*[0-9a-f]+:[	 ]+42[	 ]+rex.X
-[	 ]*[0-9a-f]+:[	 ]+43[	 ]+rex.XB
-[	 ]*[0-9a-f]+:[	 ]+44[	 ]+rex.R
-[	 ]*[0-9a-f]+:[	 ]+45[	 ]+rex.RB
-[	 ]*[0-9a-f]+:[	 ]+46[	 ]+rex.RX
-[	 ]*[0-9a-f]+:[	 ]+47[	 ]+rex.RXB
-[	 ]*[0-9a-f]+:[	 ]+48[	 ]+rex.W
-[	 ]*[0-9a-f]+:[	 ]+49[	 ]+rex.WB
-[	 ]*[0-9a-f]+:[	 ]+4a[	 ]+rex.WX
-[	 ]*[0-9a-f]+:[	 ]+4b[	 ]+rex.WXB
-[	 ]*[0-9a-f]+:[	 ]+4c[	 ]+rex.WR
-[	 ]*[0-9a-f]+:[	 ]+4d[	 ]+rex.WRB
-[	 ]*[0-9a-f]+:[	 ]+4e[	 ]+rex.WRX
-[	 ]*[0-9a-f]+:[	 ]+4f[	 ]+rex.WRXB
+[	 ]*[0-9a-f]+:[	 ]+40 90[	 ]+rex xchg %eax,%eax
+[	 ]*[0-9a-f]+:[	 ]+41 90[	 ]+xchg[ ]+%eax,%r8d
+[	 ]*[0-9a-f]+:[	 ]+42 90[	 ]+rex.X xchg %eax,%eax
+[	 ]*[0-9a-f]+:[	 ]+43 90[	 ]+rex.XB xchg %eax,%r8d
+[	 ]*[0-9a-f]+:[	 ]+44 90[	 ]+rex.R xchg %eax,%eax
+[	 ]*[0-9a-f]+:[	 ]+45 90[	 ]+rex.RB xchg %eax,%r8d
+[	 ]*[0-9a-f]+:[	 ]+46 90[	 ]+rex.RX xchg %eax,%eax
+[	 ]*[0-9a-f]+:[	 ]+47 90[	 ]+rex.RXB xchg %eax,%r8d
+[	 ]*[0-9a-f]+:[	 ]+48 90[	 ]+rex.W nop
+[	 ]*[0-9a-f]+:[	 ]+49 90[	 ]+xchg[ ]+%rax,%r8
+[	 ]*[0-9a-f]+:[	 ]+4a 90[	 ]+rex.WX xchg %rax,%rax
+[	 ]*[0-9a-f]+:[	 ]+4b 90[	 ]+rex.WXB xchg %rax,%r8
+[	 ]*[0-9a-f]+:[	 ]+4c 90[	 ]+rex.WR xchg %rax,%rax
+[	 ]*[0-9a-f]+:[	 ]+4d 90[	 ]+rex.WRB xchg %rax,%r8
+[	 ]*[0-9a-f]+:[	 ]+4e 90[	 ]+rex.WRX xchg %rax,%rax
+[	 ]*[0-9a-f]+:[	 ]+4f 90[	 ]+rex.WRXB xchg %rax,%r8
 #pass
diff --git a/gas/testsuite/gas/i386/omit-lock-no.d b/gas/testsuite/gas/i386/omit-lock-no.d
index 87f796f3a8..a35dfe7cd2 100644
--- a/gas/testsuite/gas/i386/omit-lock-no.d
+++ b/gas/testsuite/gas/i386/omit-lock-no.d
@@ -8,5 +8,5 @@
 Disassembly of section .text:
 
 0+ <main>:
-   0:	f0 f0 83 00 01       	lock lock addl \$0x1,\(%eax\)
+   0:	3e f0 83 00 01       	lock addl \$0x1,%ds:\(%eax\)
 #pass
diff --git a/gas/testsuite/gas/i386/omit-lock-yes.d b/gas/testsuite/gas/i386/omit-lock-yes.d
index 67f0ef196e..1e17e52a24 100644
--- a/gas/testsuite/gas/i386/omit-lock-yes.d
+++ b/gas/testsuite/gas/i386/omit-lock-yes.d
@@ -8,5 +8,5 @@
 Disassembly of section .text:
 
 0+ <main>:
-   0:	83 00 01             	addl   \$0x1,\(%eax\)
+   0:	3e 83 00 01          	addl   \$0x1,%ds:\(%eax\)
 #pass
diff --git a/gas/testsuite/gas/i386/omit-lock.s b/gas/testsuite/gas/i386/omit-lock.s
index 248a9be1fe..1e52498399 100644
--- a/gas/testsuite/gas/i386/omit-lock.s
+++ b/gas/testsuite/gas/i386/omit-lock.s
@@ -1,5 +1,5 @@
 	.text
 .globl main
 main:
-	lock
+	ds
         lock addl $0x1,(%eax)
diff --git a/gas/testsuite/gas/i386/prefix-2.l b/gas/testsuite/gas/i386/prefix-2.l
new file mode 100644
index 0000000000..5dd3a6cd38
--- /dev/null
+++ b/gas/testsuite/gas/i386/prefix-2.l
@@ -0,0 +1,7 @@
+.*.s: Assembler messages:
+.*.s:3: Error: same type of prefix used twice
+.*.s:6: Error: invalid instruction `movups' after `rep'
+.*.s:8: Error: expecting valid branch instruction after `bnd'
+.*.s:9: Error: stand-alone `rep' prefix
+.*.s:12: Error: invalid instruction `movups' after `repz'
+.*.s:16: Error: stand-alone `lock' prefix
diff --git a/gas/testsuite/gas/i386/prefix-2.s b/gas/testsuite/gas/i386/prefix-2.s
new file mode 100644
index 0000000000..74977772b1
--- /dev/null
+++ b/gas/testsuite/gas/i386/prefix-2.s
@@ -0,0 +1,16 @@
+	.text
+	rep
+	rep
+	repz stosb
+	rep
+	movups foo, %xmm0
+	bnd
+	movups foo, %xmm0
+	rep
+	.pushsection .foo,"ax",@progbits
+	repz
+	movups foo, %xmm0
+	.popsection
+	movups foo, %xmm1
+	bnd
+	lock
diff --git a/gas/testsuite/gas/i386/prefix-3.d b/gas/testsuite/gas/i386/prefix-3.d
new file mode 100644
index 0000000000..4647730307
--- /dev/null
+++ b/gas/testsuite/gas/i386/prefix-3.d
@@ -0,0 +1,13 @@
+#objdump: -dw
+#name: i386 prefix 3
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <test>:
+ +[a-f0-9]+:	65 f3 f0 0f c1 05 00 00 00 00 	xrelease lock xadd %eax,%gs:0x0
+ +[a-f0-9]+:	f3 aa                	rep stos %al,%es:\(%edi\)
+ +[a-f0-9]+:	f2 e9 fc ff ff ff    	bnd jmp [a-f0-9]+ <test\+0x[a-f0-9]+>
+ +[a-f0-9]+:	f3 c3                	repz ret 
+#pass
diff --git a/gas/testsuite/gas/i386/prefix-3.s b/gas/testsuite/gas/i386/prefix-3.s
new file mode 100644
index 0000000000..7bf48746cf
--- /dev/null
+++ b/gas/testsuite/gas/i386/prefix-3.s
@@ -0,0 +1,20 @@
+	.text
+test:
+	gs
+	lock
+	xrelease
+	.p2align 4
+	xaddl %eax, foo
+	rep
+
+
+	stosb
+	bnd
+
+	jmp foo
+	rep
+	ret
+.ifdef __64_bit__
+	rex64
+	call foo
+.endif
diff --git a/gas/testsuite/gas/i386/prefix-4.d b/gas/testsuite/gas/i386/prefix-4.d
new file mode 100644
index 0000000000..f297ebce64
--- /dev/null
+++ b/gas/testsuite/gas/i386/prefix-4.d
@@ -0,0 +1,12 @@
+#objdump: -dw
+#name: i386 prefix 4
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <test>:
+ +[a-f0-9]+:	74 03                	je     5 <test\+0x5>
+ +[a-f0-9]+:	77 02                	ja     6 <test\+0x6>
+ +[a-f0-9]+:	f0 f3 0f b0 0d 00 00 00 00 	lock xrelease cmpxchg %cl,0x0
+#pass
diff --git a/gas/testsuite/gas/i386/prefix-4.s b/gas/testsuite/gas/i386/prefix-4.s
new file mode 100644
index 0000000000..943d28cc11
--- /dev/null
+++ b/gas/testsuite/gas/i386/prefix-4.s
@@ -0,0 +1,13 @@
+	.text
+test:
+	je 0f
+	ja 1f
+	lock
+0:
+	xrelease
+	.data
+foo:
+	.byte 0
+	.text
+1:
+	cmpxchgb %cl, foo
diff --git a/gas/testsuite/gas/i386/rex.d b/gas/testsuite/gas/i386/rex.d
index 22c0c7f30a..79111c8158 100644
--- a/gas/testsuite/gas/i386/rex.d
+++ b/gas/testsuite/gas/i386/rex.d
@@ -27,20 +27,20 @@ Disassembly of section .text:
 [	 ]*[0-9a-f]+:[	 ]+9b dd 30\s+fsave\s+\(%rax\)
 [	 ]*[0-9a-f]+:[	 ]+9b 41 dd 30\s+fsave\s+\(%r8\)
 [	 ]*[0-9a-f]+:[	 ]+40 c5 f9 28 00[	 ]+rex vmovapd \(%rax\),%xmm0
-[	 ]*[0-9a-f]+:[	 ]+40[	 ]+rex
-[	 ]*[0-9a-f]+:[	 ]+41[	 ]+rex.B
-[	 ]*[0-9a-f]+:[	 ]+42[	 ]+rex.X
-[	 ]*[0-9a-f]+:[	 ]+43[	 ]+rex.XB
-[	 ]*[0-9a-f]+:[	 ]+44[	 ]+rex.R
-[	 ]*[0-9a-f]+:[	 ]+45[	 ]+rex.RB
-[	 ]*[0-9a-f]+:[	 ]+46[	 ]+rex.RX
-[	 ]*[0-9a-f]+:[	 ]+47[	 ]+rex.RXB
-[	 ]*[0-9a-f]+:[	 ]+48[	 ]+rex.W
-[	 ]*[0-9a-f]+:[	 ]+49[	 ]+rex.WB
-[	 ]*[0-9a-f]+:[	 ]+4a[	 ]+rex.WX
-[	 ]*[0-9a-f]+:[	 ]+4b[	 ]+rex.WXB
-[	 ]*[0-9a-f]+:[	 ]+4c[	 ]+rex.WR
-[	 ]*[0-9a-f]+:[	 ]+4d[	 ]+rex.WRB
-[	 ]*[0-9a-f]+:[	 ]+4e[	 ]+rex.WRX
-[	 ]*[0-9a-f]+:[	 ]+4f[	 ]+rex.WRXB
+[	 ]*[0-9a-f]+:[	 ]+40 90[	 ]+rex xchg %eax,%eax
+[	 ]*[0-9a-f]+:[	 ]+41 90[	 ]+xchg[ ]+%eax,%r8d
+[	 ]*[0-9a-f]+:[	 ]+42 90[	 ]+rex.X xchg %eax,%eax
+[	 ]*[0-9a-f]+:[	 ]+43 90[	 ]+rex.XB xchg %eax,%r8d
+[	 ]*[0-9a-f]+:[	 ]+44 90[	 ]+rex.R xchg %eax,%eax
+[	 ]*[0-9a-f]+:[	 ]+45 90[	 ]+rex.RB xchg %eax,%r8d
+[	 ]*[0-9a-f]+:[	 ]+46 90[	 ]+rex.RX xchg %eax,%eax
+[	 ]*[0-9a-f]+:[	 ]+47 90[	 ]+rex.RXB xchg %eax,%r8d
+[	 ]*[0-9a-f]+:[	 ]+48 90[	 ]+rex.W nop
+[	 ]*[0-9a-f]+:[	 ]+49 90[	 ]+xchg[ ]+%rax,%r8
+[	 ]*[0-9a-f]+:[	 ]+4a 90[	 ]+rex.WX xchg %rax,%rax
+[	 ]*[0-9a-f]+:[	 ]+4b 90[	 ]+rex.WXB xchg %rax,%r8
+[	 ]*[0-9a-f]+:[	 ]+4c 90[	 ]+rex.WR xchg %rax,%rax
+[	 ]*[0-9a-f]+:[	 ]+4d 90[	 ]+rex.WRB xchg %rax,%r8
+[	 ]*[0-9a-f]+:[	 ]+4e 90[	 ]+rex.WRX xchg %rax,%rax
+[	 ]*[0-9a-f]+:[	 ]+4f 90[	 ]+rex.WRXB xchg %rax,%r8
 #pass
diff --git a/gas/testsuite/gas/i386/rex.s b/gas/testsuite/gas/i386/rex.s
index c1490ccdee..c33e538686 100644
--- a/gas/testsuite/gas/i386/rex.s
+++ b/gas/testsuite/gas/i386/rex.s
@@ -28,21 +28,36 @@ _start:
 
 # Test prefixes family.
 	rex
+	nop
 	rex.B
+	nop
 	rex.X
+	nop
 	rex.XB
+	nop
 	rex.R
+	nop
 	rex.RB
+	nop
 	rex.RX
+	nop
 	rex.RXB
+	nop
 	rex.W
+	nop
 	rex.WB
+	nop
 	rex.WX
+	nop
 	rex.WXB
+	nop
 	rex.WR
+	nop
 	rex.WRB
+	nop
 	rex.WRX
+	nop
 	rex.WRXB
-# Make sure that the above rex prefix won't become the rex prefix for
-# the padding.
+	nop
 	rex
+	nop
diff --git a/gas/testsuite/gas/i386/white.l b/gas/testsuite/gas/i386/white.l
index 876c9d525f..c0ab623a09 100644
--- a/gas/testsuite/gas/i386/white.l
+++ b/gas/testsuite/gas/i386/white.l
@@ -3,8 +3,8 @@ GAS LISTING .*
 
    1                                	# test handling of whitespace, and upper-case
    2                                	.TeXt 
-   3 0000 36                         		ss 
-   4 0001 8803                       		mov % al , \( % ebx \) 
+   3                                		ss 
+   4 0000 368803                     		mov % al , \( % ebx \) 
    5 0003 C705D711 00007B00 0000     	        mOvl \$ 123 , 4567 
    6 000d 678A787B                   	 ADDr16	mov 123 \( % bx , % si , 1 \) , % bh 
    7 0011 FFE0                       		jmp \* % eax 
diff --git a/gas/testsuite/gas/i386/x86-64-prefix-3.d b/gas/testsuite/gas/i386/x86-64-prefix-3.d
new file mode 100644
index 0000000000..2c29e3651a
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-prefix-3.d
@@ -0,0 +1,17 @@
+#name: x86-64 prefix 3
+#source: prefix-3.s
+#as: -defsym __64_bit__=1
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <test>:
+ +[a-f0-9]+:	65 f3 f0 0f c1 04 25 00 00 00 00 	xrelease lock xadd %eax,%gs:0x0
+ +[a-f0-9]+:	f3 aa                	rep stos %al,%es:\(%rdi\)
+ +[a-f0-9]+:	f2 e9 00 00 00 00    	bnd jmpq [a-f0-9]+ <test\+0x[a-f0-9]+>
+ +[a-f0-9]+:	f3 c3                	repz retq 
+ +[a-f0-9]+:	48 e8 00 00 00 00    	callq  [a-f0-9]+ <test\+0x[a-f0-9]+>
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-prefix-4.d b/gas/testsuite/gas/i386/x86-64-prefix-4.d
new file mode 100644
index 0000000000..555a6d740b
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-prefix-4.d
@@ -0,0 +1,15 @@
+#name: x86-64 prefix 4
+#source: prefix-4.s
+#as: -defsym __64_bit__=1
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <test>:
+ +[a-f0-9]+:	74 03                	je     5 <test\+0x5>
+ +[a-f0-9]+:	77 02                	ja     6 <test\+0x6>
+ +[a-f0-9]+:	f0 f3 0f b0 0c 25 00 00 00 00 	lock xrelease cmpxchg %cl,0x0
+#pass
-- 
2.20.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]