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]

RFC: [PATCH] X86: Add pseudo prefixes to control encoding


Many x86 instructions have more than one encodings.  Assembler picks
the default one, usually the shortest one.  Although the ".s", ".d8"
and ".d32" suffixes can be used to swap register operands or specify
displacement size, they aren't very flexible.  This patch adds pseudo
prefixes, {xxx}, to control instruction encoding.  The available
pseudo prefixes are {disp8}, {disp32}, {swap}, {vex2}, {vex3} and
{evex}.  Pseudo prefixes are preferred over the ".s", ".d8" and ".d32"
suffixes, which are deprecated.

Any comments?

H.J.
---
gas/

	* config/tc-i386.c (_i386_insn): Add vec_encoding.  Remove
	need_vrex.
	(extra_symbol_chars): Add '}'.
	(md_begin): Mark '}' with LEX_BEGIN_NAME.  Allow '}' in
	mnemonic.
	(build_vex_prefix): Don't use 2-byte VEX encoding with
	{vex3}.
	(parse_insn): Check pseudo prefixes.
	(VEX_check_operands): Likewise.
	(parse_real_register): Set vec_encoding instead of need_vrex.
	(parse_register): Likewise.
	* doc/c-i386.texi: Document {disp8}, {disp32}, {swap}, {vex2},
	{vex3} and {evex}.  Remove ".s", ".d8" and ".d32"
	* testsuite/gas/i386/i386.exp: Run pseudos and x86-64-pseudos.
	* testsuite/gas/i386/pseudos.d: New file.
	* testsuite/gas/i386/pseudos.s: Likewise.
	* testsuite/gas/i386/x86-64-pseudos.d: Likewise.
	* testsuite/gas/i386/x86-64-pseudos.s: Likewise.

opcodes/

	* i386-opc.tbl: Add {disp8}, {disp32}, {swap}, {vex2}, {vex3}
	and {evex}.
	* i386-tbl.h: Regenerated.
---
 gas/config/tc-i386.c                    | 122 ++++++++++++++++++++++++--------
 gas/doc/c-i386.texi                     |  25 +++++--
 gas/testsuite/gas/i386/i386.exp         |   2 +
 gas/testsuite/gas/i386/pseudos.d        |  56 +++++++++++++++
 gas/testsuite/gas/i386/pseudos.s        |  52 ++++++++++++++
 gas/testsuite/gas/i386/x86-64-pseudos.d |  56 +++++++++++++++
 gas/testsuite/gas/i386/x86-64-pseudos.s |  52 ++++++++++++++
 opcodes/i386-opc.tbl                    |   9 +++
 opcodes/i386-tbl.h                      |  78 ++++++++++++++++++++
 9 files changed, 419 insertions(+), 33 deletions(-)
 create mode 100644 gas/testsuite/gas/i386/pseudos.d
 create mode 100644 gas/testsuite/gas/i386/pseudos.s
 create mode 100644 gas/testsuite/gas/i386/x86-64-pseudos.d
 create mode 100644 gas/testsuite/gas/i386/x86-64-pseudos.s

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index ca26127..23af711 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -365,6 +365,15 @@ struct _i386_insn
 	disp_encoding_32bit
       } disp_encoding;
 
+    /* How to encode vector instructions.  */
+    enum
+      {
+	vex_encoding_default = 0,
+	vex_encoding_vex2,
+	vex_encoding_vex3,
+	vex_encoding_evex
+      } vec_encoding;
+
     /* REP prefix.  */
     const char *rep_prefix;
 
@@ -374,9 +383,6 @@ struct _i386_insn
     /* Have BND prefix.  */
     const char *bnd_prefix;
 
-    /* Need VREX to support upper 16 registers.  */
-    int need_vrex;
-
     /* Error message.  */
     enum i386_error error;
   };
@@ -403,7 +409,7 @@ static const struct RC_name RC_NamesTable[] =
 
 /* List of chars besides those in app.c:symbol_chars that can start an
    operand.  Used to prevent the scrubber eating vital white-space.  */
-const char extra_symbol_chars[] = "*%-([{"
+const char extra_symbol_chars[] = "*%-([{}"
 #ifdef LEX_AT
 	"@"
 #endif
@@ -2592,6 +2598,9 @@ md_begin (void)
 {
   const char *hash_err;
 
+  /* Support pseudo prefixes like {disp32}.  */
+  lex_type ['{'] = LEX_BEGIN_NAME;
+
   /* Initialize op_hash hash table.  */
   op_hash = hash_new ();
 
@@ -2673,7 +2682,10 @@ md_begin (void)
 	    operand_chars[c] = c;
 	  }
 	else if (c == '{' || c == '}')
-	  operand_chars[c] = c;
+	  {
+	    mnemonic_chars[c] = c;
+	    operand_chars[c] = c;
+	  }
 
 	if (ISALPHA (c) || ISDIGIT (c))
 	  identifier_chars[c] = c;
@@ -3139,7 +3151,8 @@ build_vex_prefix (const insn_template *t)
 
   /* Use 2-byte VEX prefix by swappping destination and source
      operand.  */
-  if (!i.swap_operand
+  if (i.vec_encoding != vex_encoding_vex3
+      && !i.swap_operand
       && i.operands == i.reg_operands
       && i.tm.opcode_modifier.vexopcode == VEX0F
       && i.tm.opcode_modifier.s
@@ -3191,7 +3204,8 @@ build_vex_prefix (const insn_template *t)
     }
 
   /* Use 2-byte VEX prefix if possible.  */
-  if (i.tm.opcode_modifier.vexopcode == VEX0F
+  if (i.vec_encoding != vex_encoding_vex3
+      && i.tm.opcode_modifier.vexopcode == VEX0F
       && i.tm.opcode_modifier.vexw != VEXW1
       && (i.rex & (REX_W | REX_X | REX_B)) == 0)
     {
@@ -3900,21 +3914,57 @@ parse_insn (char *line, char *mnemonic)
 		      current_templates->start->name);
 	      return NULL;
 	    }
-	  /* Add prefix, checking for repeated prefixes.  */
-	  switch (add_prefix (current_templates->start->base_opcode))
+	  if (current_templates->start->opcode_length == 0)
 	    {
-	    case PREFIX_EXIST:
-	      return NULL;
-	    case PREFIX_REP:
-	      if (current_templates->start->cpu_flags.bitfield.cpuhle)
-		i.hle_prefix = current_templates->start->name;
-	      else if (current_templates->start->cpu_flags.bitfield.cpumpx)
-		i.bnd_prefix = current_templates->start->name;
-	      else
-		i.rep_prefix = current_templates->start->name;
-	      break;
-	    default:
-	      break;
+	      /* Handle pseudo prefixes.  */
+	      switch (current_templates->start->base_opcode)
+		{
+		case 0x0:
+		  /* {disp8} */
+		  i.disp_encoding = disp_encoding_8bit;
+		  break;
+		case 0x1:
+		  /* {disp32} */
+		  i.disp_encoding = disp_encoding_32bit;
+		  break;
+		case 0x2:
+		  /* {swap} */
+		  i.swap_operand = 1;
+		  break;
+		case 0x3:
+		  /* {vex2} */
+		  i.vec_encoding = vex_encoding_vex2;
+		  break;
+		case 0x4:
+		  /* {vex3} */
+		  i.vec_encoding = vex_encoding_vex3;
+		  break;
+		case 0x5:
+		  /* {evex} */
+		  i.vec_encoding = vex_encoding_evex;
+		  break;
+		default:
+		  abort ();
+		}
+	    }
+	  else
+	    {
+	      /* Add prefix, checking for repeated prefixes.  */
+	      switch (add_prefix (current_templates->start->base_opcode))
+		{
+		case PREFIX_EXIST:
+		  return NULL;
+		case PREFIX_REP:
+		  if (current_templates->start->cpu_flags.bitfield.cpuhle)
+		    i.hle_prefix = current_templates->start->name;
+		  else if (current_templates->start->cpu_flags.bitfield.cpumpx)
+		    i.bnd_prefix = current_templates->start->name;
+		  else
+		    i.rep_prefix = current_templates->start->name;
+		  break;
+		default:
+		  break;
+		}
 	    }
 	  /* Skip past PREFIX_SEPARATOR and reset token_start.  */
 	  token_start = ++l;
@@ -4716,15 +4766,27 @@ check_VecOperands (const insn_template *t)
 static int
 VEX_check_operands (const insn_template *t)
 {
-  /* VREX is only valid with EVEX prefix.  */
-  if (i.need_vrex && !t->opcode_modifier.evex)
+  if (i.vec_encoding == vex_encoding_evex)
     {
-      i.error = invalid_register_operand;
-      return 1;
+      /* This instruction must be encoded with EVEX prefix.  */
+      if (!t->opcode_modifier.evex)
+	{
+	  i.error = unsupported;
+	  return 1;
+	}
+      return 0;
     }
 
   if (!t->opcode_modifier.vex)
-    return 0;
+    {
+      /* This instruction template doesn't have VEX prefix.  */
+      if (i.vec_encoding != vex_encoding_default)
+	{
+	  i.error = unsupported;
+	  return 1;
+	}
+      return 0;
+    }
 
   /* Only check VEX_Imm4, which must be the first operand.  */
   if (t->operand_types[0].bitfield.vec_imm4)
@@ -9720,11 +9782,13 @@ parse_real_register (char *reg_string, char **end_op)
      mode.  */
   if ((r->reg_flags & RegVRex))
     {
+      if (i.vec_encoding == vex_encoding_default)
+	i.vec_encoding = vex_encoding_evex;
+
       if (!cpu_arch_flags.bitfield.cpuvrex
+	  || i.vec_encoding != vex_encoding_evex
 	  || flag_code != CODE_64BIT)
 	return (const reg_entry *) NULL;
-
-      i.need_vrex = 1;
     }
 
   if (((r->reg_flags & (RegRex64 | RegRex))
@@ -9769,7 +9833,7 @@ parse_register (char *reg_string, char **end_op)
 		&& (valueT) e->X_add_number < i386_regtab_size);
 	  r = i386_regtab + e->X_add_number;
 	  if ((r->reg_flags & RegVRex))
-	    i.need_vrex = 1;
+	    i.vec_encoding = vex_encoding_evex;
 	  *end_op = input_line_pointer;
 	}
       *input_line_pointer = c;
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
index c3c632d..6bbe340 100644
--- a/gas/doc/c-i386.texi
+++ b/gas/doc/c-i386.texi
@@ -595,10 +595,27 @@ quadruple word).
 @cindex encoding options, i386
 @cindex encoding options, x86-64
 
-Different encoding options can be specified via optional mnemonic
-suffix.  @samp{.s} suffix swaps 2 register operands in encoding when
-moving from one register to another.  @samp{.d8} or @samp{.d32} suffix
-prefers 8bit or 32bit displacement in encoding.
+Different encoding options can be specified via pseudo prefixes:
+
+@itemize @bullet
+@item
+@samp{@{disp8@}} --  prefer 8-bit displacement.
+
+@item
+@samp{@{disp32@}} --  prefer 32-bit displacement.
+
+@item
+@samp{@{swap@}} --  swap 2 register operands.
+
+@item
+@samp{@{vex2@}} --  prefer 2-byte VEX prefix for VEX instruction.
+
+@item
+@samp{@{vex3@}} --  prefer 3-byte VEX prefix for VEX instruction.
+
+@item
+@samp{@{evex@}} --  encode with EVEX prefix.
+@end itemize
 
 @cindex conversion instructions, i386
 @cindex i386 conversion instructions
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index 11c342a..0225340 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -378,6 +378,7 @@ if [expr ([istarget "i*86-*-*"] ||  [istarget "x86_64-*-*"]) && [gas_32_check]]
     run_dump_test "ptwrite-intel"
     run_list_test "avx512vl-1" "-al"
     run_list_test "avx512vl-2" "-al"
+    run_dump_test "pseudos"
 
     # These tests require support for 8 and 16 bit relocs,
     # so we only run them for ELF and COFF targets.
@@ -793,6 +794,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
     run_list_test "x86-64-avx512vl-1" "-al"
     run_list_test "x86-64-avx512vl-2" "-al"
     run_dump_test "x86-64-opcode-bad"
+    run_dump_test "x86-64-pseudos"
 
     if { ![istarget "*-*-aix*"]
       && ![istarget "*-*-beos*"]
diff --git a/gas/testsuite/gas/i386/pseudos.d b/gas/testsuite/gas/i386/pseudos.d
new file mode 100644
index 0000000..44b1b0f
--- /dev/null
+++ b/gas/testsuite/gas/i386/pseudos.d
@@ -0,0 +1,56 @@
+#objdump: -drw
+#name: pseudo prefxes
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <_start>:
+ +[a-f0-9]+:	c4 e1 78 28 d7       	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c4 e1 78 29 fa       	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c5 f8 28 d7          	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c5 f8 28 d7          	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c5 f8 29 fa          	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c4 e1 78 28 10       	vmovaps \(%eax\),%xmm2
+ +[a-f0-9]+:	c5 f8 28 10          	vmovaps \(%eax\),%xmm2
+ +[a-f0-9]+:	c5 f8 28 10          	vmovaps \(%eax\),%xmm2
+ +[a-f0-9]+:	62 f1 7c 08 28 10    	vmovaps \(%eax\),%xmm2
+ +[a-f0-9]+:	c5 f8 28 90 00 00 00 00 	vmovaps 0x0\(%eax\),%xmm2
+ +[a-f0-9]+:	62 f1 7c 08 28 50 00 	vmovaps 0x0\(%eax\),%xmm2
+ +[a-f0-9]+:	62 f1 7c 08 28 90 00 00 00 00 	vmovaps 0x0\(%eax\),%xmm2
+ +[a-f0-9]+:	89 c8                	mov    %ecx,%eax
+ +[a-f0-9]+:	8b c1                	mov    %ecx,%eax
+ +[a-f0-9]+:	0f 28 10             	movaps \(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 50 00          	movaps 0x0\(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 00 00 00 00 	movaps 0x0\(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 50 ff          	movaps -0x1\(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 50 ff          	movaps -0x1\(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 ff ff ff ff 	movaps -0x1\(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 80 00 00 00 	movaps 0x80\(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 80 00 00 00 	movaps 0x80\(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 80 00 00 00 	movaps 0x80\(%eax\),%xmm2
+ +[a-f0-9]+:	c4 e1 78 28 d7       	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c4 e1 78 29 fa       	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c5 f8 28 d7          	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c5 f8 28 d7          	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c5 f8 29 fa          	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c4 e1 78 28 10       	vmovaps \(%eax\),%xmm2
+ +[a-f0-9]+:	c5 f8 28 10          	vmovaps \(%eax\),%xmm2
+ +[a-f0-9]+:	c5 f8 28 10          	vmovaps \(%eax\),%xmm2
+ +[a-f0-9]+:	62 f1 7c 08 28 10    	vmovaps \(%eax\),%xmm2
+ +[a-f0-9]+:	c5 f8 28 90 00 00 00 00 	vmovaps 0x0\(%eax\),%xmm2
+ +[a-f0-9]+:	62 f1 7c 08 28 50 00 	vmovaps 0x0\(%eax\),%xmm2
+ +[a-f0-9]+:	62 f1 7c 08 28 90 00 00 00 00 	vmovaps 0x0\(%eax\),%xmm2
+ +[a-f0-9]+:	89 c8                	mov    %ecx,%eax
+ +[a-f0-9]+:	8b c1                	mov    %ecx,%eax
+ +[a-f0-9]+:	0f 28 10             	movaps \(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 50 00          	movaps 0x0\(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 00 00 00 00 	movaps 0x0\(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 50 ff          	movaps -0x1\(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 50 ff          	movaps -0x1\(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 ff ff ff ff 	movaps -0x1\(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 80 00 00 00 	movaps 0x80\(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 80 00 00 00 	movaps 0x80\(%eax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 80 00 00 00 	movaps 0x80\(%eax\),%xmm2
+#pass
diff --git a/gas/testsuite/gas/i386/pseudos.s b/gas/testsuite/gas/i386/pseudos.s
new file mode 100644
index 0000000..8468fc9
--- /dev/null
+++ b/gas/testsuite/gas/i386/pseudos.s
@@ -0,0 +1,52 @@
+# Check instructions with pseudo prefixes for encoding
+
+	.text
+_start:
+	{vex3} vmovaps %xmm7,%xmm2
+	{vex3} {swap} vmovaps %xmm7,%xmm2
+	vmovaps %xmm7,%xmm2
+	{vex2} vmovaps %xmm7,%xmm2
+	{vex2} {swap} vmovaps %xmm7,%xmm2
+	{vex3} vmovaps (%eax),%xmm2
+	vmovaps (%eax),%xmm2
+	{vex2} vmovaps (%eax),%xmm2
+	{evex} vmovaps (%eax),%xmm2
+	{disp32} vmovaps (%eax),%xmm2
+	{evex} {disp8} vmovaps (%eax),%xmm2
+	{evex} {disp32} vmovaps (%eax),%xmm2
+	mov %ecx, %eax
+	{swap} mov %ecx, %eax
+	movaps (%eax),%xmm2
+	{disp8} movaps (%eax),%xmm2
+	{disp32} movaps (%eax),%xmm2
+	movaps -1(%eax),%xmm2
+	{disp8} movaps -1(%eax),%xmm2
+	{disp32} movaps -1(%eax),%xmm2
+	movaps 128(%eax),%xmm2
+	{disp8} movaps 128(%eax),%xmm2
+	{disp32} movaps 128(%eax),%xmm2
+
+	.intel_syntax noprefix
+	{vex3} vmovaps xmm2,xmm7
+	{vex3} {swap} vmovaps xmm2,xmm7
+	vmovaps xmm2,xmm7
+	{vex2} vmovaps xmm2,xmm7
+	{vex2} {swap} vmovaps xmm2,xmm7
+	{vex3} vmovaps xmm2,XMMWORD PTR [eax]
+	vmovaps xmm2,XMMWORD PTR [eax]
+	{vex2} vmovaps xmm2,XMMWORD PTR [eax]
+	{evex} vmovaps xmm2,XMMWORD PTR [eax]
+	{disp32} vmovaps xmm2,XMMWORD PTR [eax]
+	{evex} {disp8} vmovaps xmm2,XMMWORD PTR [eax]
+	{evex} {disp32} vmovaps xmm2,XMMWORD PTR [eax]
+	mov eax,ecx
+	{swap} mov eax,ecx
+	movaps xmm2,XMMWORD PTR [eax]
+	{disp8} movaps xmm2,XMMWORD PTR [eax]
+	{disp32} movaps xmm2,XMMWORD PTR [eax]
+	movaps xmm2,XMMWORD PTR [eax-1]
+	{disp8} movaps xmm2,XMMWORD PTR [eax-1]
+	{disp32} movaps xmm2,XMMWORD PTR [eax-1]
+	movaps xmm2,XMMWORD PTR [eax+128]
+	{disp8} movaps xmm2,XMMWORD PTR [eax+128]
+	{disp32} movaps xmm2,XMMWORD PTR [eax+128]
diff --git a/gas/testsuite/gas/i386/x86-64-pseudos.d b/gas/testsuite/gas/i386/x86-64-pseudos.d
new file mode 100644
index 0000000..9a0ab51
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-pseudos.d
@@ -0,0 +1,56 @@
+#objdump: -drw
+#name: x86-64 pseudo prefxes
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <_start>:
+ +[a-f0-9]+:	c4 e1 78 28 d7       	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c4 e1 78 29 fa       	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c5 f8 28 d7          	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c5 f8 28 d7          	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c5 f8 29 fa          	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c4 e1 78 28 10       	vmovaps \(%rax\),%xmm2
+ +[a-f0-9]+:	c5 f8 28 10          	vmovaps \(%rax\),%xmm2
+ +[a-f0-9]+:	c5 f8 28 10          	vmovaps \(%rax\),%xmm2
+ +[a-f0-9]+:	62 f1 7c 08 28 10    	vmovaps \(%rax\),%xmm2
+ +[a-f0-9]+:	c5 f8 28 90 00 00 00 00 	vmovaps 0x0\(%rax\),%xmm2
+ +[a-f0-9]+:	62 f1 7c 08 28 50 00 	vmovaps 0x0\(%rax\),%xmm2
+ +[a-f0-9]+:	62 f1 7c 08 28 90 00 00 00 00 	vmovaps 0x0\(%rax\),%xmm2
+ +[a-f0-9]+:	48 89 c8             	mov    %rcx,%rax
+ +[a-f0-9]+:	48 8b c1             	mov    %rcx,%rax
+ +[a-f0-9]+:	0f 28 10             	movaps \(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 50 00          	movaps 0x0\(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 00 00 00 00 	movaps 0x0\(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 50 ff          	movaps -0x1\(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 50 ff          	movaps -0x1\(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 ff ff ff ff 	movaps -0x1\(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 80 00 00 00 	movaps 0x80\(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 80 00 00 00 	movaps 0x80\(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 80 00 00 00 	movaps 0x80\(%rax\),%xmm2
+ +[a-f0-9]+:	c4 e1 78 28 d7       	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c4 e1 78 29 fa       	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c5 f8 28 d7          	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c5 f8 28 d7          	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c5 f8 29 fa          	vmovaps %xmm7,%xmm2
+ +[a-f0-9]+:	c4 e1 78 28 10       	vmovaps \(%rax\),%xmm2
+ +[a-f0-9]+:	c5 f8 28 10          	vmovaps \(%rax\),%xmm2
+ +[a-f0-9]+:	c5 f8 28 10          	vmovaps \(%rax\),%xmm2
+ +[a-f0-9]+:	62 f1 7c 08 28 10    	vmovaps \(%rax\),%xmm2
+ +[a-f0-9]+:	c5 f8 28 90 00 00 00 00 	vmovaps 0x0\(%rax\),%xmm2
+ +[a-f0-9]+:	62 f1 7c 08 28 50 00 	vmovaps 0x0\(%rax\),%xmm2
+ +[a-f0-9]+:	62 f1 7c 08 28 90 00 00 00 00 	vmovaps 0x0\(%rax\),%xmm2
+ +[a-f0-9]+:	48 89 c8             	mov    %rcx,%rax
+ +[a-f0-9]+:	48 8b c1             	mov    %rcx,%rax
+ +[a-f0-9]+:	0f 28 10             	movaps \(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 50 00          	movaps 0x0\(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 00 00 00 00 	movaps 0x0\(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 50 ff          	movaps -0x1\(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 50 ff          	movaps -0x1\(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 ff ff ff ff 	movaps -0x1\(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 80 00 00 00 	movaps 0x80\(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 80 00 00 00 	movaps 0x80\(%rax\),%xmm2
+ +[a-f0-9]+:	0f 28 90 80 00 00 00 	movaps 0x80\(%rax\),%xmm2
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-pseudos.s b/gas/testsuite/gas/i386/x86-64-pseudos.s
new file mode 100644
index 0000000..050526b
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-pseudos.s
@@ -0,0 +1,52 @@
+# Check 64bit instructions with pseudo prefixes for encoding
+
+	.text
+_start:
+	{vex3} vmovaps %xmm7,%xmm2
+	{vex3} {swap} vmovaps %xmm7,%xmm2
+	vmovaps %xmm7,%xmm2
+	{vex2} vmovaps %xmm7,%xmm2
+	{vex2} {swap} vmovaps %xmm7,%xmm2
+	{vex3} vmovaps (%rax),%xmm2
+	vmovaps (%rax),%xmm2
+	{vex2} vmovaps (%rax),%xmm2
+	{evex} vmovaps (%rax),%xmm2
+	{disp32} vmovaps (%rax),%xmm2
+	{evex} {disp8} vmovaps (%rax),%xmm2
+	{evex} {disp32} vmovaps (%rax),%xmm2
+	mov %rcx, %rax
+	{swap} mov %rcx, %rax
+	movaps (%rax),%xmm2
+	{disp8} movaps (%rax),%xmm2
+	{disp32} movaps (%rax),%xmm2
+	movaps -1(%rax),%xmm2
+	{disp8} movaps -1(%rax),%xmm2
+	{disp32} movaps -1(%rax),%xmm2
+	movaps 128(%rax),%xmm2
+	{disp8} movaps 128(%rax),%xmm2
+	{disp32} movaps 128(%rax),%xmm2
+
+	.intel_syntax noprefix
+	{vex3} vmovaps xmm2,xmm7
+	{vex3} {swap} vmovaps xmm2,xmm7
+	vmovaps xmm2,xmm7
+	{vex2} vmovaps xmm2,xmm7
+	{vex2} {swap} vmovaps xmm2,xmm7
+	{vex3} vmovaps xmm2,XMMWORD PTR [rax]
+	vmovaps xmm2,XMMWORD PTR [rax]
+	{vex2} vmovaps xmm2,XMMWORD PTR [rax]
+	{evex} vmovaps xmm2,XMMWORD PTR [rax]
+	{disp32} vmovaps xmm2,XMMWORD PTR [rax]
+	{evex} {disp8} vmovaps xmm2,XMMWORD PTR [rax]
+	{evex} {disp32} vmovaps xmm2,XMMWORD PTR [rax]
+	mov rax,rcx
+	{swap} mov rax,rcx
+	movaps xmm2,XMMWORD PTR [rax]
+	{disp8} movaps xmm2,XMMWORD PTR [rax]
+	{disp32} movaps xmm2,XMMWORD PTR [rax]
+	movaps xmm2,XMMWORD PTR [rax-1]
+	{disp8} movaps xmm2,XMMWORD PTR [rax-1]
+	{disp32} movaps xmm2,XMMWORD PTR [rax-1]
+	movaps xmm2,XMMWORD PTR [rax+128]
+	{disp8} movaps xmm2,XMMWORD PTR [rax+128]
+	{disp32} movaps xmm2,XMMWORD PTR [rax+128]
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
index 9ec09dc..59c0f1a 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -820,6 +820,15 @@ rex.wrb, 0, 0x4d, None, 1, Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldS
 rex.wrx, 0, 0x4e, None, 1, Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsPrefix, { 0 }
 rex.wrxb, 0, 0x4f, None, 1, Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsPrefix, { 0 }
 
+// Pseudo prefixes (opcode_length == 0)
+
+{disp8}, 0, 0x0, None, 0, 0, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsPrefix, { 0 }
+{disp32}, 0, 0x1, None, 0, 0, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsPrefix, { 0 }
+{swap}, 0, 0x2, None, 0, 0, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsPrefix, { 0 }
+{vex2}, 0, 0x3, None, 0, 0, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsPrefix, { 0 }
+{vex3}, 0, 0x4, None, 0, 0, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsPrefix, { 0 }
+{evex}, 0, 0x5, None, 0, 0, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsPrefix, { 0 }
+
 // 486 extensions.
 
 bswap, 1, 0xfc8, None, 2, Cpu486, ShortForm|No_bSuf|No_wSuf|No_sSuf|No_ldSuf, { Reg32|Reg64 }
diff --git a/opcodes/i386-tbl.h b/opcodes/i386-tbl.h
index 46f2e6b..88d8188 100644
--- a/opcodes/i386-tbl.h
+++ b/opcodes/i386-tbl.h
@@ -8582,6 +8582,84 @@ const insn_template i386_optab[] =
     { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } },
+  { "{disp8}", 0, 0x0, None, 0,
+    { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+      1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } },
+  { "{disp32}", 0, 0x1, None, 0,
+    { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+      1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } },
+  { "{swap}", 0, 0x2, None, 0,
+    { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+      1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } },
+  { "{vex2}", 0, 0x3, None, 0,
+    { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+      1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } },
+  { "{vex3}", 0, 0x4, None, 0,
+    { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+      1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } },
+  { "{evex}", 0, 0x5, None, 0,
+    { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+      1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } },
   { "bswap", 1, 0xfc8, None, 2,
     { { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-- 
2.7.4


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