aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2023-03-31 08:21:05 +0200
committerJan Beulich <jbeulich@suse.com>2023-03-31 08:21:05 +0200
commit0ff3b7d0c70274a916c21eb8fb5e040ee17af9f8 (patch)
treed95febde6ae5fe425f1080438b9525504722549d /gas
parent393fbe8d81ed4e26c66493bba5ac98b0bdae5f27 (diff)
downloadbinutils-0ff3b7d0c70274a916c21eb8fb5e040ee17af9f8.zip
binutils-0ff3b7d0c70274a916c21eb8fb5e040ee17af9f8.tar.gz
binutils-0ff3b7d0c70274a916c21eb8fb5e040ee17af9f8.tar.bz2
x86: process instruction operands for .insn
Deal with register and memory operands; immediate operands will follow later, as will the handling of EVEX embedded broadcast and EVEX Disp8 scaling. Note that because we can't really know how to encode their use, %cr8 and up cannot be used with .insn outside of 64-bit mode. Users would need to specify an explicit LOCK prefix in combination with %cr0 etc.
Diffstat (limited to 'gas')
-rw-r--r--gas/config/tc-i386-intel.c7
-rw-r--r--gas/config/tc-i386.c316
-rw-r--r--gas/testsuite/gas/i386/insn-32.d18
-rw-r--r--gas/testsuite/gas/i386/insn-32.s36
-rw-r--r--gas/testsuite/gas/i386/insn-64.d29
-rw-r--r--gas/testsuite/gas/i386/insn-64.s47
6 files changed, 432 insertions, 21 deletions
diff --git a/gas/config/tc-i386-intel.c b/gas/config/tc-i386-intel.c
index c139c58..98262bd 100644
--- a/gas/config/tc-i386-intel.c
+++ b/gas/config/tc-i386-intel.c
@@ -320,8 +320,10 @@ i386_intel_simplify_register (expressionS *e)
as_bad (_("invalid use of register"));
return 0;
}
- if (i386_regtab[reg_num].reg_type.bitfield.class == SReg
- && i386_regtab[reg_num].reg_num == RegFlat)
+ if ((i386_regtab[reg_num].reg_type.bitfield.class == SReg
+ && i386_regtab[reg_num].reg_num == RegFlat)
+ || (dot_insn ()
+ && i386_regtab[reg_num].reg_type.bitfield.class == ClassNone))
{
as_bad (_("invalid use of pseudo-register"));
return 0;
@@ -342,6 +344,7 @@ i386_intel_simplify_register (expressionS *e)
if (intel_state.in_scale
|| i386_regtab[reg_num].reg_type.bitfield.baseindex
+ || dot_insn ()
|| t->mnem_off == MN_bndmk
|| t->mnem_off == MN_bndldx
|| t->mnem_off == MN_bndstx)
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index d901ef9..748cf1c 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -2354,7 +2354,8 @@ fits_in_disp8 (offsetT num)
static INLINE int
fits_in_imm4 (offsetT num)
{
- return (num & 0xf) == num;
+ /* Despite the name, check for imm3 if we're dealing with EVEX. */
+ return (num & (i.vec_encoding != vex_encoding_evex ? 0xf : 7)) == num;
}
static i386_operand_type
@@ -8213,7 +8214,7 @@ process_operands (void)
}
}
}
- else if (i.types[0].bitfield.class == SReg)
+ else if (i.types[0].bitfield.class == SReg && !dot_insn ())
{
if (flag_code != CODE_64BIT
? i.tm.base_opcode == POP_SEG_SHORT
@@ -8246,15 +8247,32 @@ process_operands (void)
}
else if (i.short_form)
{
- /* The register operand is in operand 0 or 1. */
- const reg_entry *r = i.op[0].regs;
+ /* The register operand is in the 1st or 2nd non-immediate operand. */
+ const reg_entry *r = i.op[i.imm_operands].regs;
- if (i.imm_operands
- || (r->reg_type.bitfield.instance == Accum && i.op[1].regs))
- r = i.op[1].regs;
+ if (!dot_insn ()
+ && r->reg_type.bitfield.instance == Accum
+ && i.op[i.imm_operands + 1].regs)
+ r = i.op[i.imm_operands + 1].regs;
/* Register goes in low 3 bits of opcode. */
i.tm.base_opcode |= r->reg_num;
set_rex_vrex (r, REX_B, false);
+
+ if (dot_insn () && i.reg_operands == 2)
+ {
+ gas_assert (is_any_vex_encoding (&i.tm)
+ || i.vec_encoding != vex_encoding_default);
+ i.vex.register_specifier = i.op[i.operands - 1].regs;
+ }
+ }
+ else if (i.reg_operands == 1
+ && !i.flags[i.operands - 1]
+ && i.tm.operand_types[i.operands - 1].bitfield.instance
+ == InstanceNone)
+ {
+ gas_assert (is_any_vex_encoding (&i.tm)
+ || i.vec_encoding != vex_encoding_default);
+ i.vex.register_specifier = i.op[i.operands - 1].regs;
}
if ((i.seg[0] || i.prefix[SEG_PREFIX])
@@ -8315,10 +8333,12 @@ build_modrm_byte (void)
VexW0 or VexW1. The destination must be either XMM, YMM or
ZMM register.
2. 4 operands: 4 register operands or 3 register operands
- plus 1 memory operand, with VexXDS. */
+ plus 1 memory operand, with VexXDS.
+ 3. Other equivalent combinations when coming from s_insn(). */
gas_assert (i.tm.opcode_modifier.vexvvvv
- && i.tm.opcode_modifier.vexw
- && i.tm.operand_types[dest].bitfield.class == RegSIMD);
+ && i.tm.opcode_modifier.vexw);
+ gas_assert (dot_insn ()
+ || i.tm.operand_types[dest].bitfield.class == RegSIMD);
/* Of the first two non-immediate operands the one with the template
not allowing for a memory one is encoded in the immediate operand. */
@@ -8327,6 +8347,14 @@ build_modrm_byte (void)
else
reg_slot = source++;
+ if (!dot_insn ())
+ {
+ gas_assert (i.tm.operand_types[reg_slot].bitfield.class == RegSIMD);
+ gas_assert (!(i.op[reg_slot].regs->reg_flags & RegVRex));
+ }
+ else
+ gas_assert (i.tm.operand_types[reg_slot].bitfield.class != ClassNone);
+
if (i.imm_operands == 0)
{
/* When there is no immediate operand, generate an 8bit
@@ -8336,10 +8364,7 @@ build_modrm_byte (void)
i.types[i.operands].bitfield.imm8 = 1;
i.operands++;
- gas_assert (i.tm.operand_types[reg_slot].bitfield.class == RegSIMD);
exp->X_op = O_constant;
- exp->X_add_number = register_number (i.op[reg_slot].regs) << 4;
- gas_assert ((i.op[reg_slot].regs->reg_flags & RegVRex) == 0);
}
else
{
@@ -8350,11 +8375,11 @@ build_modrm_byte (void)
/* Turn on Imm8 again so that output_imm will generate it. */
i.types[0].bitfield.imm8 = 1;
- gas_assert (i.tm.operand_types[reg_slot].bitfield.class == RegSIMD);
- i.op[0].imms->X_add_number
- |= register_number (i.op[reg_slot].regs) << 4;
- gas_assert ((i.op[reg_slot].regs->reg_flags & RegVRex) == 0);
+ exp = i.op[0].imms;
}
+ exp->X_add_number |= register_number (i.op[reg_slot].regs)
+ << (3 + !(is_evex_encoding (&i.tm)
+ || i.vec_encoding == vex_encoding_evex));
}
for (v = source + 1; v < dest; ++v)
@@ -10619,6 +10644,9 @@ s_insn (int dummy ATTRIBUTE_UNUSED)
goto bad;
}
+ if (line > end && i.vec_encoding == vex_encoding_default)
+ i.vec_encoding = evex ? vex_encoding_evex : vex_encoding_vex;
+
if (line > end && *line == '.')
{
/* Length specifier (VEX.L, XOP.L, EVEX.L'L). */
@@ -10898,7 +10926,244 @@ s_insn (int dummy ATTRIBUTE_UNUSED)
goto bad;
}
i.opcode_length = j;
- i.tm.base_opcode = val;
+
+ /* Handle operands, if any. */
+ if (*line == ',')
+ {
+ i386_operand_type combined;
+ bool changed;
+
+ ptr = parse_operands (line + 1, &i386_mnemonics[MN__insn]);
+ this_operand = -1;
+ if (!ptr)
+ goto bad;
+ line = ptr;
+
+ if (!i.operands)
+ {
+ as_bad (_("expecting operand after ','; got nothing"));
+ goto done;
+ }
+
+ if (i.mem_operands > 1)
+ {
+ as_bad (_("too many memory references for `%s'"),
+ &i386_mnemonics[MN__insn]);
+ goto done;
+ }
+
+ /* Are we to emit ModR/M encoding? */
+ if (!i.short_form
+ && (i.mem_operands
+ || i.reg_operands > (i.vec_encoding != vex_encoding_default)
+ || i.tm.extension_opcode != None))
+ i.tm.opcode_modifier.modrm = 1;
+
+ if (!i.tm.opcode_modifier.modrm
+ && (i.reg_operands
+ > i.short_form + 0U + (i.vec_encoding != vex_encoding_default)
+ || i.mem_operands))
+ {
+ as_bad (_("too many register/memory operands"));
+ goto done;
+ }
+
+ /* Enforce certain constraints on operands. */
+ switch (i.reg_operands + i.mem_operands
+ + (i.tm.extension_opcode != None))
+ {
+ case 0:
+ if (i.short_form)
+ {
+ as_bad (_("too few register/memory operands"));
+ goto done;
+ }
+ /* Fall through. */
+ case 1:
+ if (i.tm.opcode_modifier.modrm)
+ {
+ as_bad (_("too few register/memory operands"));
+ goto done;
+ }
+ break;
+
+ case 2:
+ break;
+
+ case 4:
+ if (i.imm_operands
+ && (i.op[0].imms->X_op != O_constant
+ || !fits_in_imm4 (i.op[0].imms->X_add_number)))
+ {
+ as_bad (_("constant doesn't fit in %d bits"), evex ? 3 : 4);
+ goto done;
+ }
+ /* Fall through. */
+ case 3:
+ if (i.vec_encoding != vex_encoding_default)
+ {
+ i.tm.opcode_modifier.vexvvvv = 1;
+ break;
+ }
+ /* Fall through. */
+ default:
+ as_bad (_("too many register/memory operands"));
+ goto done;
+ }
+
+ /* Bring operands into canonical order (imm, mem, reg). */
+ do
+ {
+ changed = false;
+
+ for (j = 1; j < i.operands; ++j)
+ {
+ if ((!operand_type_check (i.types[j - 1], imm)
+ && operand_type_check (i.types[j], imm))
+ || (i.types[j - 1].bitfield.class != ClassNone
+ && i.types[j].bitfield.class == ClassNone))
+ {
+ swap_2_operands (j - 1, j);
+ changed = true;
+ }
+ }
+ }
+ while (changed);
+
+ /* For Intel syntax swap the order of register operands. */
+ if (intel_syntax)
+ switch (i.reg_operands)
+ {
+ case 0:
+ case 1:
+ break;
+
+ case 4:
+ swap_2_operands (i.imm_operands + i.mem_operands + 1, i.operands - 2);
+ /* Fall through. */
+ case 3:
+ case 2:
+ swap_2_operands (i.imm_operands + i.mem_operands, i.operands - 1);
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* Enforce constraints when using VSIB. */
+ if (i.index_reg
+ && (i.index_reg->reg_type.bitfield.xmmword
+ || i.index_reg->reg_type.bitfield.ymmword
+ || i.index_reg->reg_type.bitfield.zmmword))
+ {
+ if (i.vec_encoding == vex_encoding_default)
+ {
+ as_bad (_("VSIB unavailable with legacy encoding"));
+ goto done;
+ }
+
+ if (i.vec_encoding == vex_encoding_evex
+ && i.reg_operands > 1)
+ {
+ /* We could allow two register operands, encoding the 2nd one in
+ an 8-bit immediate like for 4-register-operand insns, but that
+ would require ugly fiddling with process_operands() and/or
+ build_modrm_byte(). */
+ as_bad (_("too many register operands with VSIB"));
+ goto done;
+ }
+
+ i.tm.opcode_modifier.sib = 1;
+ }
+
+ /* Establish operand size encoding. */
+ operand_type_set (&combined, 0);
+ for (j = i.imm_operands; j < i.operands; ++j)
+ {
+ i.types[j].bitfield.instance = InstanceNone;
+
+ if (operand_type_check (i.types[j], disp))
+ i.types[j].bitfield.baseindex = 1;
+
+ if ((i.broadcast.type || i.broadcast.bytes)
+ && j == i.broadcast.operand)
+ continue;
+
+ combined = operand_type_or (combined, i.types[j]);
+ combined.bitfield.class = ClassNone;
+ }
+
+ if (i.vec_encoding == vex_encoding_default)
+ {
+ if (flag_code == CODE_64BIT && combined.bitfield.qword)
+ i.rex |= REX_W;
+ else if ((flag_code == CODE_16BIT ? combined.bitfield.dword
+ : combined.bitfield.word)
+ && !add_prefix (DATA_PREFIX_OPCODE))
+ goto done;
+ }
+ else if (!i.tm.opcode_modifier.vexw)
+ {
+ if (flag_code == CODE_64BIT)
+ {
+ if (combined.bitfield.qword)
+ i.tm.opcode_modifier.vexw = VEXW1;
+ else if (combined.bitfield.dword)
+ i.tm.opcode_modifier.vexw = VEXW0;
+ }
+
+ if (!i.tm.opcode_modifier.vexw)
+ i.tm.opcode_modifier.vexw = VEXWIG;
+ }
+
+ if (vex || xop)
+ {
+ if (!i.tm.opcode_modifier.vex)
+ {
+ if (combined.bitfield.ymmword)
+ i.tm.opcode_modifier.vex = VEX256;
+ else if (combined.bitfield.xmmword)
+ i.tm.opcode_modifier.vex = VEX128;
+ }
+ }
+ else if (evex)
+ {
+ if (!i.tm.opcode_modifier.evex)
+ {
+ /* Do _not_ consider AVX512VL here. */
+ if (i.rounding.type != rc_none || combined.bitfield.zmmword)
+ i.tm.opcode_modifier.evex = EVEX512;
+ else if (combined.bitfield.ymmword)
+ i.tm.opcode_modifier.evex = EVEX256;
+ else if (combined.bitfield.xmmword)
+ i.tm.opcode_modifier.evex = EVEX128;
+ }
+ }
+
+ if (i.disp_operands && !optimize_disp (&i.tm))
+ goto done;
+
+ for (j = 0; j < i.operands; ++j)
+ i.tm.operand_types[j] = i.types[j];
+
+ process_operands ();
+ }
+
+ /* Don't set opcode until after processing operands, to avoid any
+ potential special casing there. */
+ i.tm.base_opcode |= val;
+
+ if (i.vec_encoding == vex_encoding_error
+ || (i.vec_encoding != vex_encoding_evex
+ ? i.broadcast.type || i.broadcast.bytes
+ || i.rounding.type != rc_none
+ || i.mask.reg
+ : (i.broadcast.type || i.broadcast.bytes)
+ && i.rounding.type != rc_none))
+ {
+ as_bad (_("conflicting .insn operands"));
+ goto done;
+ }
if (vex || xop)
{
@@ -10916,6 +11181,8 @@ s_insn (int dummy ATTRIBUTE_UNUSED)
build_evex_prefix ();
i.rex &= REX_OPCODE;
}
+ else if (i.rex != 0)
+ add_prefix (REX_OPCODE | i.rex);
output_insn ();
@@ -11884,6 +12151,15 @@ i386_att_operand (char *operand_string)
as_bad (_("junk `%s' after register"), op_string);
return 0;
}
+
+ /* Reject pseudo registers for .insn. */
+ if (dot_insn () && r->reg_type.bitfield.class == ClassNone)
+ {
+ as_bad (_("`%s%s' cannot be used here"),
+ register_prefix, r->reg_name);
+ return 0;
+ }
+
temp = r->reg_type;
temp.bitfield.baseindex = 0;
i.types[this_operand] = operand_type_or (i.types[this_operand],
@@ -13263,7 +13539,9 @@ static bool check_register (const reg_entry *r)
}
if (((r->reg_flags & (RegRex64 | RegRex)) || r->reg_type.bitfield.qword)
- && (!cpu_arch_flags.bitfield.cpulm || r->reg_type.bitfield.class != RegCR)
+ && (!cpu_arch_flags.bitfield.cpulm
+ || r->reg_type.bitfield.class != RegCR
+ || dot_insn ())
&& flag_code != CODE_64BIT)
return false;
diff --git a/gas/testsuite/gas/i386/insn-32.d b/gas/testsuite/gas/i386/insn-32.d
index 77c6fc0..fdd9ae7 100644
--- a/gas/testsuite/gas/i386/insn-32.d
+++ b/gas/testsuite/gas/i386/insn-32.d
@@ -11,6 +11,24 @@ Disassembly of section .text:
[ ]*[a-f0-9]+: f3 90[ ]+pause
[ ]*[a-f0-9]+: d9 ee[ ]+fldz
[ ]*[a-f0-9]+: f3 0f 01 e8[ ]+setssbsy
+[ ]*[a-f0-9]+: 8b c1[ ]+mov %ecx,%eax
+[ ]*[a-f0-9]+: 66 8b c8[ ]+mov %ax,%cx
+[ ]*[a-f0-9]+: 89 48 04[ ]+mov %ecx,0x4\(%eax\)
+[ ]*[a-f0-9]+: 8b 0c 05 44 44 00 00[ ]+mov 0x4444\(,%eax,1\),%ecx
+[ ]*[a-f0-9]+: 66 0f b6 cc[ ]+movzbw %ah,%cx
+[ ]*[a-f0-9]+: 0f b7 c8[ ]+movzwl %ax,%ecx
+[ ]*[a-f0-9]+: 0f ca[ ]+bswap %edx
[ ]*[a-f0-9]+: c5 fc 77[ ]+vzeroall
[ ]*[a-f0-9]+: c4 e1 7c 77[ ]+vzeroall
+[ ]*[a-f0-9]+: c5 f1 58 d0[ ]+vaddpd %xmm0,%xmm1,%xmm2
+[ ]*[a-f0-9]+: c5 f5 58 d0[ ]+vaddpd %ymm0,%ymm1,%ymm2
+[ ]*[a-f0-9]+: c5 f2 58 d0[ ]+vaddss %xmm0,%xmm1,%xmm2
+[ ]*[a-f0-9]+: c4 e3 69 68 19 00[ ]+vfmaddps %xmm0,\(%ecx\),%xmm2,%xmm3
+[ ]*[a-f0-9]+: c4 e3 e9 68 19 00[ ]+vfmaddps \(%ecx\),%xmm0,%xmm2,%xmm3
+[ ]*[a-f0-9]+: c4 e3 e9 68 18 10[ ]+vfmaddps \(%eax\),%xmm1,%xmm2,%xmm3
+[ ]*[a-f0-9]+: c5 f8 92 c8[ ]+kmovw %eax,%k1
+[ ]*[a-f0-9]+: c5 f8 93 c1[ ]+kmovw %k1,%eax
+[ ]*[a-f0-9]+: 62 f1 74 18 58 d0[ ]+vaddps \{rn-sae\},%zmm0,%zmm1,%zmm2
+[ ]*[a-f0-9]+: c4 e2 79 92 1c 48[ ]+vgatherdps %xmm0,\(%eax,%xmm1,2\),%xmm3
+[ ]*[a-f0-9]+: 62 f2 fd 0c 93 1c 48[ ]+vgatherqpd \(%eax,%xmm1,2\),%xmm3\{%k4\}
#pass
diff --git a/gas/testsuite/gas/i386/insn-32.s b/gas/testsuite/gas/i386/insn-32.s
index db0ddb7..73491e4 100644
--- a/gas/testsuite/gas/i386/insn-32.s
+++ b/gas/testsuite/gas/i386/insn-32.s
@@ -13,6 +13,42 @@ insn:
# setssbsy
.insn 0xf30f01e8
+ # mov
+ .insn 0x8b, %ecx, %eax
+ .insn 0x8b, %ax, %cx
+ .insn 0x89, %ecx, 4(%eax)
+ .insn 0x8b, 0x4444(,%eax), %ecx
+
+ # movzx
+ .insn 0x0fb6, %ah, %cx
+ .insn 0x0fb7, %eax, %ecx
+
+ # bswap
+ .insn 0x0fc8+r, %edx
+
# vzeroall
.insn VEX.256.0F.WIG 0x77
.insn {vex3} VEX.L1 0x0f77
+
+ # vaddpd
+ .insn VEX.66.0F 0x58, %xmm0, %xmm1, %xmm2
+ .insn VEX.66 0x0f58, %ymm0, %ymm1, %ymm2
+
+ # vaddss
+ .insn VEX.LIG.F3.0F 0x58, %xmm0, %xmm1, %xmm2
+
+ # vfmaddps
+ .insn VEX.66.0F3A.W0 0x68, %xmm0, (%ecx), %xmm2, %xmm3
+ .insn VEX.66.0F3A.W1 0x68, %xmm0, (%ecx), %xmm2, %xmm3
+ .insn VEX.66.0F3A.W1 0x68, (%eax), %xmm1, %xmm2, %xmm3
+
+ # kmovw
+ .insn VEX.L0.0F.W0 0x92, %eax, %k1
+ .insn VEX.L0.0F.W0 0x93, %k1, %eax
+
+ # vaddps
+ .insn EVEX.NP.0F.W0 0x58, {rn-sae}, %zmm0, %zmm1, %zmm2
+
+ # vgather...
+ .insn VEX.66.0f38.W0 0x92, %xmm0, (%eax, %xmm1, 2), %xmm3
+ .insn EVEX.66.0f38.W1 0x93, (%eax, %xmm1, 2), %xmm3{%k4}
diff --git a/gas/testsuite/gas/i386/insn-64.d b/gas/testsuite/gas/i386/insn-64.d
index 6c61989..229960f 100644
--- a/gas/testsuite/gas/i386/insn-64.d
+++ b/gas/testsuite/gas/i386/insn-64.d
@@ -11,6 +11,35 @@ Disassembly of section .text:
[ ]*[a-f0-9]+: f3 90[ ]+pause
[ ]*[a-f0-9]+: d9 ee[ ]+fldz
[ ]*[a-f0-9]+: f3 0f 01 e8[ ]+setssbsy
+[ ]*[a-f0-9]+: 44 8b c1[ ]+mov %ecx,%r8d
+[ ]*[a-f0-9]+: 48 8b c8[ ]+mov %rax,%rcx
+[ ]*[a-f0-9]+: 41 89 48 08[ ]+mov %ecx,0x8\(%r8\)
+[ ]*[a-f0-9]+: 42 8b 0c 05 80 80 00 00[ ]+mov 0x8080\(,%r8,1\),%ecx
+[ ]*[a-f0-9]+: 66 0f be cc[ ]+movsbw %ah,%cx
+[ ]*[a-f0-9]+: 0f bf c8[ ]+movswl %ax,%ecx
+[ ]*[a-f0-9]+: 48 63 c8[ ]+movslq %eax,%rcx
+[ ]*[a-f0-9]+: 48 0f ca[ ]+bswap %rdx
+[ ]*[a-f0-9]+: 41 0f c8[ ]+bswap %r8d
[ ]*[a-f0-9]+: c5 fc 77[ ]+vzeroall
[ ]*[a-f0-9]+: c4 e1 7c 77[ ]+vzeroall
+[ ]*[a-f0-9]+: c4 c1 71 58 d0[ ]+vaddpd %xmm8,%xmm1,%xmm2
+[ ]*[a-f0-9]+: c5 b5 58 d0[ ]+vaddpd %ymm0,%ymm9,%ymm2
+[ ]*[a-f0-9]+: c5 72 58 d0[ ]+vaddss %xmm0,%xmm1,%xmm10
+[ ]*[a-f0-9]+: c4 e3 69 68 19 80[ ]+vfmaddps %xmm8,\(%rcx\),%xmm2,%xmm3
+[ ]*[a-f0-9]+: 67 c4 e3 e9 68 19 00[ ]+vfmaddps \(%ecx\),%xmm0,%xmm2,%xmm3
+[ ]*[a-f0-9]+: c4 c3 e9 68 18 10[ ]+vfmaddps \(%r8\),%xmm1,%xmm2,%xmm3
+[ ]*[a-f0-9]+: c4 c1 78 92 c8[ ]+kmovw %r8d,%k1
+[ ]*[a-f0-9]+: c5 78 93 c1[ ]+kmovw %k1,%r8d
+[ ]*[a-f0-9]+: 62 b1 74 38 58 d0[ ]+vaddps \{rd-sae\},%zmm16,%zmm1,%zmm2
+[ ]*[a-f0-9]+: 62 f1 74 10 58 d0[ ]+vaddps \{rn-sae\},%zmm0,%zmm17,%zmm2
+[ ]*[a-f0-9]+: 62 e1 74 58 58 d0[ ]+vaddps \{ru-sae\},%zmm0,%zmm1,%zmm18
+[ ]*[a-f0-9]+: c4 e2 39 92 1c 48[ ]+vgatherdps %xmm8,\(%rax,%xmm1,2\),%xmm3
+[ ]*[a-f0-9]+: c4 c2 79 92 1c 48[ ]+vgatherdps %xmm0,\(%r8,%xmm1,2\),%xmm3
+[ ]*[a-f0-9]+: c4 a2 79 92 1c 48[ ]+vgatherdps %xmm0,\(%rax,%xmm9,2\),%xmm3
+[ ]*[a-f0-9]+: c4 62 79 92 1c 48[ ]+vgatherdps %xmm0,\(%rax,%xmm1,2\),%xmm11
+[ ]*[a-f0-9]+: 62 d2 fd 0c 93 1c 48[ ]+vgatherqpd \(%r8,%xmm1,2\),%xmm3\{%k4\}
+[ ]*[a-f0-9]+: 62 b2 fd 0c 93 1c 48[ ]+vgatherqpd \(%rax,%xmm9,2\),%xmm3\{%k4\}
+[ ]*[a-f0-9]+: 62 f2 fd 04 93 1c 48[ ]+vgatherqpd \(%rax,%xmm17,2\),%xmm3\{%k4\}
+[ ]*[a-f0-9]+: 62 72 fd 0c 93 1c 48[ ]+vgatherqpd \(%rax,%xmm1,2\),%xmm11\{%k4\}
+[ ]*[a-f0-9]+: 62 e2 fd 0c 93 1c 48[ ]+vgatherqpd \(%rax,%xmm1,2\),%xmm19\{%k4\}
#pass
diff --git a/gas/testsuite/gas/i386/insn-64.s b/gas/testsuite/gas/i386/insn-64.s
index db0ddb7..b8f5ede 100644
--- a/gas/testsuite/gas/i386/insn-64.s
+++ b/gas/testsuite/gas/i386/insn-64.s
@@ -13,6 +13,53 @@ insn:
# setssbsy
.insn 0xf30f01e8
+ # mov
+ .insn 0x8b, %ecx, %r8d
+ .insn 0x8b, %rax, %rcx
+ .insn 0x89, %ecx, 8(%r8)
+ .insn 0x8b, 0x8080(,%r8), %ecx
+
+ # movsx
+ .insn 0x0fbe, %ah, %cx
+ .insn 0x0fbf, %eax, %ecx
+ .insn 0x63, %rax, %rcx
+
+ # bswap
+ .insn 0x0fc8+r, %rdx
+ .insn 0x0fc8+r, %r8d
+
# vzeroall
.insn VEX.256.0F.WIG 0x77
.insn {vex3} VEX.L1 0x0f77
+
+ # vaddpd
+ .insn VEX.66.0F 0x58, %xmm8, %xmm1, %xmm2
+ .insn VEX.66 0x0f58, %ymm0, %ymm9, %ymm2
+
+ # vaddss
+ .insn VEX.LIG.F3.0F 0x58, %xmm0, %xmm1, %xmm10
+
+ # vfmaddps
+ .insn VEX.66.0F3A.W0 0x68, %xmm8, (%rcx), %xmm2, %xmm3
+ .insn VEX.66.0F3A.W1 0x68, %xmm0, (%ecx), %xmm2, %xmm3
+ .insn VEX.66.0F3A.W1 0x68, (%r8), %xmm1, %xmm2, %xmm3
+
+ # kmovw
+ .insn VEX.L0.0F.W0 0x92, %r8d, %k1
+ .insn VEX.L0.0F.W0 0x93, %k1, %r8d
+
+ # vaddps
+ .insn EVEX.NP.0F.W0 0x58, {rd-sae}, %zmm16, %zmm1, %zmm2
+ .insn EVEX.NP.0F.W0 0x58, {rn-sae}, %zmm0, %zmm17, %zmm2
+ .insn EVEX.NP.0F.W0 0x58, {ru-sae}, %zmm0, %zmm1, %zmm18
+
+ # vgather...
+ .insn VEX.66.0f38.W0 0x92, %xmm8, (%rax, %xmm1, 2), %xmm3
+ .insn VEX.66.0f38.W0 0x92, %xmm0, (%r8, %xmm1, 2), %xmm3
+ .insn VEX.66.0f38.W0 0x92, %xmm0, (%rax, %xmm9, 2), %xmm3
+ .insn VEX.66.0f38.W0 0x92, %xmm0, (%rax, %xmm1, 2), %xmm11
+ .insn EVEX.66.0f38.W1 0x93, (%r8, %xmm1, 2), %xmm3{%k4}
+ .insn EVEX.66.0f38.W1 0x93, (%rax, %xmm9, 2), %xmm3{%k4}
+ .insn EVEX.66.0f38.W1 0x93, (%rax, %xmm17, 2), %xmm3{%k4}
+ .insn EVEX.66.0f38.W1 0x93, (%rax, %xmm1, 2), %xmm11{%k4}
+ .insn EVEX.66.0f38.W1 0x93, (%rax, %xmm1, 2), %xmm19{%k4}