aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-03-09 09:58:46 -0800
committerH.J. Lu <hjl.tools@gmail.com>2017-03-09 09:59:00 -0800
commit86fa6981e7487e2c2df4337aa75ed2d93c32eaf2 (patch)
tree3a2c124ce66bd4de896bcd0fca29dcb3f4f8f094 /gas
parentf03265d9cda1f5f8df238efa9b7a20330e5711f1 (diff)
downloadbinutils-86fa6981e7487e2c2df4337aa75ed2d93c32eaf2.zip
binutils-86fa6981e7487e2c2df4337aa75ed2d93c32eaf2.tar.gz
binutils-86fa6981e7487e2c2df4337aa75ed2d93c32eaf2.tar.bz2
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}, {load}, {store}, {vex2}, {vex3} and {evex}. Pseudo prefixes are preferred over the ".s", ".d8" and ".d32" suffixes, which are deprecated. gas/ * config/tc-i386.c (_i386_insn): Add dir_encoding and vec_encoding. Remove swap_operand and 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}. Check dir_encoding and load. (parse_insn): Check pseudo prefixes. Set dir_encoding. (VEX_check_operands): Likewise. (match_template): Check dir_encoding and load. (parse_real_register): Set vec_encoding instead of need_vrex. (parse_register): Likewise. * doc/c-i386.texi: Document {disp8}, {disp32}, {load}, {store}, {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-gen.c (opcode_modifiers): Replace S with Load. * i386-opc.h (S): Removed. (Load): New. (i386_opcode_modifier): Replace s with load. * i386-opc.tbl: Add {disp8}, {disp32}, {swap}, {vex2}, {vex3} and {evex}. Replace S with Load. * i386-tbl.h: Regenerated.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog22
-rw-r--r--gas/config/tc-i386.c158
-rw-r--r--gas/doc/c-i386.texi28
-rw-r--r--gas/testsuite/gas/i386/i386.exp2
-rw-r--r--gas/testsuite/gas/i386/pseudos.d66
-rw-r--r--gas/testsuite/gas/i386/pseudos.s62
-rw-r--r--gas/testsuite/gas/i386/x86-64-pseudos.d66
-rw-r--r--gas/testsuite/gas/i386/x86-64-pseudos.s62
8 files changed, 418 insertions, 48 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 4504fdb..4a6a9f5 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,25 @@
+2017-03-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/tc-i386.c (_i386_insn): Add dir_encoding and
+ vec_encoding. Remove swap_operand and 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}. Check dir_encoding and load.
+ (parse_insn): Check pseudo prefixes. Set dir_encoding.
+ (VEX_check_operands): Likewise.
+ (match_template): Check dir_encoding and load.
+ (parse_real_register): Set vec_encoding instead of need_vrex.
+ (parse_register): Likewise.
+ * doc/c-i386.texi: Document {disp8}, {disp32}, {load}, {store},
+ {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.
+
2017-03-08 Peter Bergner <bergner@vnet.ibm.com>
* testsuite/gas/ppc/altivec2.d (as): Use the -mpower8 option.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 7deacad..6250793 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -354,8 +354,13 @@ struct _i386_insn
/* Compressed disp8*N attribute. */
unsigned int memshift;
- /* Swap operand in encoding. */
- unsigned int swap_operand;
+ /* Prefer load or store in encoding. */
+ enum
+ {
+ dir_encoding_default = 0,
+ dir_encoding_load,
+ dir_encoding_store
+ } dir_encoding;
/* Prefer 8bit or 32bit displacement in encoding. */
enum
@@ -365,6 +370,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 +388,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 +414,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
@@ -2597,6 +2608,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 ();
@@ -2678,7 +2692,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;
@@ -3144,10 +3161,11 @@ build_vex_prefix (const insn_template *t)
/* Use 2-byte VEX prefix by swapping destination and source
operand. */
- if (!i.swap_operand
+ if (i.vec_encoding != vex_encoding_vex3
+ && i.dir_encoding == dir_encoding_default
&& i.operands == i.reg_operands
&& i.tm.opcode_modifier.vexopcode == VEX0F
- && i.tm.opcode_modifier.s
+ && i.tm.opcode_modifier.load
&& i.rex == REX_B)
{
unsigned int xchg = i.operands - 1;
@@ -3196,7 +3214,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)
{
@@ -3905,21 +3924,61 @@ 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:
+ /* {load} */
+ i.dir_encoding = dir_encoding_load;
+ break;
+ case 0x3:
+ /* {store} */
+ i.dir_encoding = dir_encoding_store;
+ break;
+ case 0x4:
+ /* {vex2} */
+ i.vec_encoding = vex_encoding_vex2;
+ break;
+ case 0x5:
+ /* {vex3} */
+ i.vec_encoding = vex_encoding_vex3;
+ break;
+ case 0x6:
+ /* {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;
@@ -3933,7 +3992,7 @@ parse_insn (char *line, char *mnemonic)
/* Check if we should swap operand or force 32bit displacement in
encoding. */
if (mnem_p - 2 == dot_p && dot_p[1] == 's')
- i.swap_operand = 1;
+ i.dir_encoding = dir_encoding_store;
else if (mnem_p - 3 == dot_p
&& dot_p[1] == 'd'
&& dot_p[2] == '8')
@@ -4721,15 +4780,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)
@@ -4967,20 +5038,17 @@ match_template (char mnem_suffix)
&& operand_type_equal (&i.types [0], &acc32)
&& operand_type_equal (&i.types [1], &acc32))
continue;
- if (i.swap_operand)
- {
- /* If we swap operand in encoding, we either match
- the next one or reverse direction of operands. */
- if (t->opcode_modifier.s)
- continue;
- else if (t->opcode_modifier.d)
- goto check_reverse;
- }
+ /* If we want store form, we reverse direction of operands. */
+ if (i.dir_encoding == dir_encoding_store
+ && t->opcode_modifier.d)
+ goto check_reverse;
/* Fall through. */
case 3:
- /* If we swap operand in encoding, we match the next one. */
- if (i.swap_operand && t->opcode_modifier.s)
+ /* If we want store form, we skip the current load. */
+ if (i.dir_encoding == dir_encoding_store
+ && i.mem_operands == 0
+ && t->opcode_modifier.load)
continue;
/* Fall through. */
case 4:
@@ -9725,11 +9793,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))
@@ -9774,7 +9844,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 0733587..32f4289 100644
--- a/gas/doc/c-i386.texi
+++ b/gas/doc/c-i386.texi
@@ -598,10 +598,30 @@ 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{@{load@}} -- prefer load-form instruction.
+
+@item
+@samp{@{store@}} -- prefer store-form instruction.
+
+@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 cc5917a..c1d6af7 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -384,6 +384,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]]
run_dump_test "fpu-bad"
run_dump_test "cet"
run_dump_test "cet-intel"
+ run_dump_test "pseudos"
# These tests require support for 8 and 16 bit relocs,
# so we only run them for ELF and COFF targets.
@@ -803,6 +804,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
run_dump_test "x86-64-opcode-bad"
run_dump_test "x86-64-cet"
run_dump_test "x86-64-cet-intel"
+ 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..fb2dc5b
--- /dev/null
+++ b/gas/testsuite/gas/i386/pseudos.d
@@ -0,0 +1,66 @@
+#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 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 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]+: 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 10 movaps \(%eax\),%xmm2
+ +[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 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 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]+: 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 10 movaps \(%eax\),%xmm2
+ +[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..1309335
--- /dev/null
+++ b/gas/testsuite/gas/i386/pseudos.s
@@ -0,0 +1,62 @@
+# Check instructions with pseudo prefixes for encoding
+
+ .text
+_start:
+ {vex3} vmovaps %xmm7,%xmm2
+ {vex3} {load} vmovaps %xmm7,%xmm2
+ {vex3} {store} vmovaps %xmm7,%xmm2
+ vmovaps %xmm7,%xmm2
+ {vex2} vmovaps %xmm7,%xmm2
+ {vex2} {load} vmovaps %xmm7,%xmm2
+ {vex2} {store} 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
+ {load} mov %ecx, %eax
+ {store} mov %ecx, %eax
+ movaps (%eax),%xmm2
+ {load} movaps (%eax),%xmm2
+ {store} 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} {load} vmovaps xmm2,xmm7
+ {vex3} {store} vmovaps xmm2,xmm7
+ vmovaps xmm2,xmm7
+ {vex2} vmovaps xmm2,xmm7
+ {vex2} {load} vmovaps xmm2,xmm7
+ {vex2} {store} 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
+ {load} mov eax,ecx
+ {store} mov eax,ecx
+ movaps xmm2,XMMWORD PTR [eax]
+ {load} movaps xmm2,XMMWORD PTR [eax]
+ {store} 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..c63a0a1
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-pseudos.d
@@ -0,0 +1,66 @@
+#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 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 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 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 10 movaps \(%rax\),%xmm2
+ +[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 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 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 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 10 movaps \(%rax\),%xmm2
+ +[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..c0ee8dc
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-pseudos.s
@@ -0,0 +1,62 @@
+# Check 64bit instructions with pseudo prefixes for encoding
+
+ .text
+_start:
+ {vex3} vmovaps %xmm7,%xmm2
+ {vex3} {load} vmovaps %xmm7,%xmm2
+ {vex3} {store} vmovaps %xmm7,%xmm2
+ vmovaps %xmm7,%xmm2
+ {vex2} vmovaps %xmm7,%xmm2
+ {vex2} {load} vmovaps %xmm7,%xmm2
+ {vex2} {store} 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
+ {load} mov %rcx, %rax
+ {store} mov %rcx, %rax
+ movaps (%rax),%xmm2
+ {load} movaps (%rax),%xmm2
+ {store} 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} {load} vmovaps xmm2,xmm7
+ {vex3} {store} vmovaps xmm2,xmm7
+ vmovaps xmm2,xmm7
+ {vex2} vmovaps xmm2,xmm7
+ {vex2} {load} vmovaps xmm2,xmm7
+ {vex2} {store} 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
+ {load} mov rax,rcx
+ {store} mov rax,rcx
+ movaps xmm2,XMMWORD PTR [rax]
+ {load} movaps xmm2,XMMWORD PTR [rax]
+ {store} 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]