Support APX NF

For the case when NDD and NF are both 0 in evex-promoted format,
we will fully support and test it in another patch.

gas/ChangeLog:

       * NEWS: Support Intel APX NF.
       * config/tc-i386.c (enum i386_error): Add unsupported_nf.
       (struct _i386_insn): Add has_nf.
       (is_apx_evex_encoding): Ditto.
       (build_apx_evex_prefix): Encode the NF bit.
       (md_assemble): Handle unsupported_nf.
       (parse_insn): Handle Prefix_NF and report bad for illegal combination.
       (can_convert_NDD_to_legacy): Replace i.tm.opcode_modifier.nf with i.has_nf.
       (match_template): Support D for APX_F insns and check NF support.
       * testsuite/gas/i386/x86-64-apx-evex-promoted-bad.d: Add bad test for NF bit.
       * testsuite/gas/i386/x86-64-apx-evex-promoted-bad.s: Ditto.
       * testsuite/gas/i386/x86-64-apx-inval.l: Ditto.
       * testsuite/gas/i386/x86-64-apx-inval.s: Ditto.
       * testsuite/gas/i386/x86-64.exp: Add apx nf tests.
       * testsuite/gas/i386/x86-64-apx-nf-intel.d: New test.
       * testsuite/gas/i386/x86-64-apx-nf.d: Ditto.
       * testsuite/gas/i386/x86-64-apx-nf.s: Ditto.

opcodes/ChangeLog:

       * i386-dis-evex.h: Add %NF to the instructions that support APX NF and
       add new instruction imul, popcnt, tzcnt and lzcnt to EVEX table.
       * i386-dis-evex-reg.h: Ditto.
       * i386-dis.c (struct instr_info): Add nf.
       (struct dis386): Add "NF" for EVEX.NF.
       (get_valid_dis386): Set ins->vex.nf and report bad-nf for illegal case.
       (print_insn): Handle ins.vex.nf.
       (putop): Handle "%NF".
       * i386-opc.h (Prefix_NF): New.
       * i386-opc.tbl: Added new entries to support full APX NF instructions.
       * i386-mnem.h: Regenerated.
       * i386-tbl.h: Regenerated.
This commit is contained in:
Cui, Lili 2024-04-07 17:28:25 +08:00
parent bc0d0a5596
commit dd74a60337
17 changed files with 5037 additions and 407 deletions

View File

@ -1,5 +1,7 @@
-*- text -*-
* Support the NF feature in Intel APX.
* Remove KEYLOCKER and SHA promotions from EVEX MAP4.
* References to FB and dollar labels, when supported, are no longer permitted

View File

@ -242,6 +242,7 @@ enum i386_error
unsupported_with_intel_mnemonic,
unsupported_syntax,
unsupported_EGPR_for_addressing,
unsupported_nf,
unsupported,
unsupported_on_arch,
unsupported_64bit,
@ -439,6 +440,9 @@ struct _i386_insn
/* Prefer the REX2 prefix in encoding. */
bool rex2_encoding;
/* No CSPAZO flags update. */
bool has_nf;
/* Disable instruction size optimization. */
bool no_optimize;
@ -3944,7 +3948,7 @@ is_any_vex_encoding (const insn_template *t)
static INLINE bool
is_apx_evex_encoding (void)
{
return i.rex2 || i.tm.opcode_space == SPACE_EVEXMAP4
return i.rex2 || i.tm.opcode_space == SPACE_EVEXMAP4 || i.has_nf
|| (i.vex.register_specifier
&& (i.vex.register_specifier->reg_flags & RegRex2));
}
@ -4251,6 +4255,10 @@ build_apx_evex_prefix (void)
space. */
if (i.vex.register_specifier && i.tm.opcode_space == SPACE_EVEXMAP4)
i.vex.bytes[3] |= 0x10;
/* Encode the NF bit. */
if (i.has_nf)
i.vex.bytes[3] |= 0x04;
}
static void establish_rex (void)
@ -6645,6 +6653,9 @@ md_assemble (char *line)
case unsupported_EGPR_for_addressing:
err_msg = _("extended GPR cannot be used as base/index");
break;
case unsupported_nf:
err_msg = _("{nf} unsupported");
break;
case unsupported:
as_bad (_("unsupported instruction `%s'"),
pass1_mnem ? pass1_mnem : insn_name (current_templates.start));
@ -7209,6 +7220,12 @@ parse_insn (const char *line, char *mnemonic, bool prefix_only)
/* {rex2} */
i.rex2_encoding = true;
break;
case Prefix_NF:
/* {nf} */
i.has_nf = true;
if (i.encoding == encoding_default)
i.encoding = encoding_evex;
break;
case Prefix_NoOptimize:
/* {nooptimize} */
i.no_optimize = true;
@ -7216,6 +7233,11 @@ parse_insn (const char *line, char *mnemonic, bool prefix_only)
default:
abort ();
}
if (i.has_nf && i.encoding != encoding_evex)
{
as_bad (_("{nf} cannot be combined with {vex}/{vex3}"));
return NULL;
}
}
else
{
@ -8468,8 +8490,7 @@ can_convert_NDD_to_legacy (const insn_template *t)
{
unsigned int match_dest_op = ~0;
if (!i.tm.opcode_modifier.nf
&& i.reg_operands >= 2)
if (!i.has_nf && i.reg_operands >= 2)
{
unsigned int dest = i.operands - 1;
unsigned int src1 = i.operands - 2;
@ -8559,6 +8580,11 @@ match_template (char mnem_suffix)
: t->opcode_modifier.dialect == INTEL_SYNTAX)
continue;
/* Check NF support. */
specific_error = progress (unsupported_nf);
if (i.has_nf && !t->opcode_modifier.nf)
continue;
/* Check Intel64/AMD64 ISA. */
switch (isa64)
{
@ -8902,7 +8928,8 @@ match_template (char mnem_suffix)
found_reverse_match = Opcode_VexW;
goto check_operands_345;
}
else if (is_cpu (t, CpuAPX_F) && i.operands == 3)
else if (t->opcode_space == SPACE_EVEXMAP4
&& t->opcode_modifier.w)
{
found_reverse_match = Opcode_D;
goto check_operands_345;

View File

@ -21,14 +21,12 @@ Disassembly of section .text:
[ ]*[a-f0-9]+:[ ]+62 fc 7d[ ]+\(bad\).*
[ ]*[a-f0-9]+:[ ]+28 60 c7[ ]+.*
[ ]*[a-f0-9]+:[ ]+62 fc 7d[ ]+\(bad\).*
[ ]*[a-f0-9]+:[ ]+8f[ ]+\(bad\)
[ ]*[a-f0-9]+:[ ]+60[ ]+\(bad\)
[ ]*[a-f0-9]+:[ ]+c7[ ]+\(bad\)
[ ]*[a-f0-9]+:[ ]+8b 60 c7[ ]+.*
[ ]*[a-f0-9]+:[ ]+62 f2 fc 09 f5[ ]+\(bad\).*
[ ]*[a-f0-9]+:[ ]+0c 18[ ]+or.*
[ ]*[a-f0-9]+:[ ]+62 f2 fc 28 f5[ ]+\(bad\)
[ ]*[a-f0-9]+:[ ]+0c 18[ ]+or.*
[ ]*[a-f0-9]+:[ ]+62 f2 fc 8f f5[ ]+\(bad\).*
[ ]*[a-f0-9]+:[ ]+62 f2 fc 8b f5[ ]+\(bad\).*
[ ]*[a-f0-9]+:[ ]+0c 18[ ]+or.*
[ ]*[a-f0-9]+:[ ]+62 f2 fc 18 f5[ ]+\(bad\)
[ ]*[a-f0-9]+:[ ]+0c 18[ ]+or.*
@ -40,4 +38,5 @@ Disassembly of section .text:
[ ]*[a-f0-9]+:[ ]+62 74 7c 18 8f c0[ ]+pop2 %rax,\(bad\)
[ ]*[a-f0-9]+:[ ]+62 d4 24 18 8f[ ]+\(bad\)
[ ]*[a-f0-9]+:[ ]+c3[ ]+.*
[ ]*[a-f0-9]+:[ ]+62 fc 7d 0c 60 c7[ ]+movbe \{bad-nf\},%r23w,%ax
#pass

View File

@ -23,7 +23,7 @@ _start:
.insn EVEX.L1.66.M12.W0 0x60, %di, %ax
#EVEX_MAP4 movbe %r18w,%ax set EVEX.z == 0b1.
.insn EVEX.L0.66.M12.W0 0x60, %di, %ax {%k7}{z}
.insn EVEX.L0.66.M12.W0 0x60, %di, %ax {%k3}{z}
#EVEX from VEX bzhi %rax,(%rax,%rbx),%rcx EVEX.aaa[1:0] (P[17:16])
#== 0b01
@ -33,18 +33,23 @@ _start:
.insn EVEX.L1.NP.0f38.W1 0xf5, %rax, (%rax,%rbx), %rcx
#EVEX from VEX bzhi %rax,(%rax,%rbx),%rcx EVEX.P[23](EVEX.z) == 0b1
.insn EVEX.L0.NP.0f38.W1 0xf5, %rax, (%rax,%rbx), %rcx {%k7}{z}
.insn EVEX.L0.NP.0f38.W1 0xf5, %rax, (%rax,%rbx), %rcx {%k3}{z}
#EVEX from VEX bzhi %rax,(%rax,%rbx),%rcx EVEX.P[20](EVEX.b) == 0b1
.insn EVEX.L0.NP.0f38.W1 0xf5, %rax, (%rax,%rbx){1to8}, %rcx
#{evex} inc %rax %rbx EVEX.vvvv != 1111 && EVEX.ND = 0.
.byte 0x62, 0xf4, 0xe4, 0x08, 0xff, 0x04, 0x08
# pop2 %rax, %r8 set EVEX.ND=0.
.byte 0x62, 0xf4, 0x3c, 0x08, 0x8f, 0xc0
.byte 0xff, 0xff, 0xff
# pop2 %rax, %r8 set EVEX.vvvv = 1111.
.insn EVEX.L0.M4.W0 0x8f, %rax, {rn-sae},%r8
# pop2 %r11, %r11
.insn EVEX.L0.NP.M4.W0 0x8f/0, {sae}, %xmm11, %xmm11
#EVEX_MAP4 movbe %r18w,%ax set EVEX.nf = 1.
.insn EVEX.L0.66.M12.W0 0x60, %di, %ax {%k4}

View File

@ -1,3 +1,14 @@
.*: Assembler messages:
.*:3: Error: instruction length of 16 bytes exceeds the limit of 15
.*:4: Error: instruction length of 16 bytes exceeds the limit of 15
.*:5: Error: \{nf\} unsupported for `adc'
.*:6: Error: \{nf\} unsupported for `not'
.*:7: Error: \{nf\} unsupported for `rcl'
.*:8: Error: \{nf\} unsupported for `rcr'
.*:9: Error: \{nf\} unsupported for `sbb'
.*:10: Error: \{nf\} unsupported for `pop2'
.*:11: Error: \{nf\} unsupported for `push2'
.*:12: Error: \{nf\} unsupported for `adcx'
.*:13: Error: \{nf\} unsupported for `mulx'
.*:14: Error: \{nf\} cannot be combined with \{vex\}/\{vex3\}
.*:15: Error: \{nf\} cannot be combined with \{vex\}/\{vex3\}

View File

@ -2,3 +2,14 @@
.text
addq $0xe0, %fs:0, %rdx
xorq $0xe0, foo(%eax,%edx), %rdx
{nf} adc $1, (%rax)
{nf} not %r15
{nf} rcl $0x7b,%r15
{nf} rcr $0x7b,%r15
{nf} sbb $0x7b,%r15
{nf} pop2 %rax, %rbx
{nf} push2 %rbx, %rax
{nf} adcx %r15,%r15
{nf} mulx %r15,%r15,%r11
{nf} {vex} bextr %ecx, %edx, %r10d
{vex} {nf} bextr %ecx, %edx, %r10d

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -386,6 +386,8 @@ run_dump_test "x86-64-apx-ndd-wig"
run_dump_test "x86-64-apx-jmpabs"
run_dump_test "x86-64-apx-jmpabs-intel"
run_dump_test "x86-64-apx-jmpabs-inval"
run_dump_test "x86-64-apx-nf"
run_dump_test "x86-64-apx-nf-intel"
run_dump_test "x86-64-avx512f-rcigrz-intel"
run_dump_test "x86-64-avx512f-rcigrz"
run_dump_test "x86-64-clwb"

View File

@ -51,33 +51,33 @@
},
/* REG_EVEX_MAP4_80 */
{
{ "addA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "orA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "%NFaddA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "%NForA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "adcA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "sbbA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "andA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "subA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "xorA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "%NFandA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "%NFsubA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "%NFxorA", { VexGb, Eb, Ib }, NO_PREFIX },
},
/* REG_EVEX_MAP4_81 */
{
{ "addQ", { VexGv, Ev, Iv }, PREFIX_NP_OR_DATA },
{ "orQ", { VexGv, Ev, Iv }, PREFIX_NP_OR_DATA },
{ "%NFaddQ", { VexGv, Ev, Iv }, PREFIX_NP_OR_DATA },
{ "%NForQ", { VexGv, Ev, Iv }, PREFIX_NP_OR_DATA },
{ "adcQ", { VexGv, Ev, Iv }, PREFIX_NP_OR_DATA },
{ "sbbQ", { VexGv, Ev, Iv }, PREFIX_NP_OR_DATA },
{ "andQ", { VexGv, Ev, Iv }, PREFIX_NP_OR_DATA },
{ "subQ", { VexGv, Ev, Iv }, PREFIX_NP_OR_DATA },
{ "xorQ", { VexGv, Ev, Iv }, PREFIX_NP_OR_DATA },
{ "%NFandQ", { VexGv, Ev, Iv }, PREFIX_NP_OR_DATA },
{ "%NFsubQ", { VexGv, Ev, Iv }, PREFIX_NP_OR_DATA },
{ "%NFxorQ", { VexGv, Ev, Iv }, PREFIX_NP_OR_DATA },
},
/* REG_EVEX_MAP4_83 */
{
{ "addQ", { VexGv, Ev, sIb }, PREFIX_NP_OR_DATA },
{ "orQ", { VexGv, Ev, sIb }, PREFIX_NP_OR_DATA },
{ "%NFaddQ", { VexGv, Ev, sIb }, PREFIX_NP_OR_DATA },
{ "%NForQ", { VexGv, Ev, sIb }, PREFIX_NP_OR_DATA },
{ "adcQ", { VexGv, Ev, sIb }, PREFIX_NP_OR_DATA },
{ "sbbQ", { VexGv, Ev, sIb }, PREFIX_NP_OR_DATA },
{ "andQ", { VexGv, Ev, sIb }, PREFIX_NP_OR_DATA },
{ "subQ", { VexGv, Ev, sIb }, PREFIX_NP_OR_DATA },
{ "xorQ", { VexGv, Ev, sIb }, PREFIX_NP_OR_DATA },
{ "%NFandQ", { VexGv, Ev, sIb }, PREFIX_NP_OR_DATA },
{ "%NFsubQ", { VexGv, Ev, sIb }, PREFIX_NP_OR_DATA },
{ "%NFxorQ", { VexGv, Ev, sIb }, PREFIX_NP_OR_DATA },
},
/* REG_EVEX_MAP4_8F */
{
@ -88,24 +88,32 @@
{ Bad_Opcode },
{ Bad_Opcode },
{ "notA", { VexGb, Eb }, NO_PREFIX },
{ "negA", { VexGb, Eb }, NO_PREFIX },
{ "%NFnegA", { VexGb, Eb }, NO_PREFIX },
{ "%NFmulA", { Eb }, NO_PREFIX },
{ "%NFimulA", { Eb }, NO_PREFIX },
{ "%NFdivA", { Eb }, NO_PREFIX },
{ "%NFidivA", { Eb }, NO_PREFIX },
},
/* REG_EVEX_MAP4_F7 */
{
{ Bad_Opcode },
{ Bad_Opcode },
{ "notQ", { VexGv, Ev }, PREFIX_NP_OR_DATA },
{ "negQ", { VexGv, Ev }, PREFIX_NP_OR_DATA },
{ "%NFnegQ", { VexGv, Ev }, PREFIX_NP_OR_DATA },
{ "%NFmulQ", { Ev }, PREFIX_NP_OR_DATA },
{ "%NFimulQ", { Ev }, PREFIX_NP_OR_DATA },
{ "%NFdivQ", { Ev }, PREFIX_NP_OR_DATA },
{ "%NFidivQ", { Ev }, PREFIX_NP_OR_DATA },
},
/* REG_EVEX_MAP4_FE */
{
{ "incA", { VexGb, Eb }, NO_PREFIX },
{ "decA", { VexGb, Eb }, NO_PREFIX },
{ "%NFincA", { VexGb, Eb }, NO_PREFIX },
{ "%NFdecA", { VexGb, Eb }, NO_PREFIX },
},
/* REG_EVEX_MAP4_FF */
{
{ "incQ", { VexGv, Ev }, PREFIX_NP_OR_DATA },
{ "decQ", { VexGv, Ev }, PREFIX_NP_OR_DATA },
{ "%NFincQ", { VexGv, Ev }, PREFIX_NP_OR_DATA },
{ "%NFdecQ", { VexGv, Ev }, PREFIX_NP_OR_DATA },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },

View File

@ -875,64 +875,64 @@ static const struct dis386 evex_table[][256] = {
/* EVEX_MAP4_ */
{
/* 00 */
{ "addB", { VexGb, Eb, Gb }, NO_PREFIX },
{ "addS", { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
{ "addB", { VexGb, Gb, EbS }, NO_PREFIX },
{ "addS", { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
{ "%NFaddB", { VexGb, Eb, Gb }, NO_PREFIX },
{ "%NFaddS", { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
{ "%NFaddB", { VexGb, Gb, EbS }, NO_PREFIX },
{ "%NFaddS", { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
/* 08 */
{ "orB", { VexGb, Eb, Gb }, NO_PREFIX },
{ "orS", { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
{ "orB", { VexGb, Gb, EbS }, NO_PREFIX },
{ "orS", { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
{ "%NForB", { VexGb, Eb, Gb }, NO_PREFIX },
{ "%NForS", { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
{ "%NForB", { VexGb, Gb, EbS }, NO_PREFIX },
{ "%NForS", { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
/* 10 */
{ "adcB", { VexGb, Eb, Gb }, NO_PREFIX },
{ "adcS", { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
{ "adcB", { VexGb, Gb, EbS }, NO_PREFIX },
{ "adcS", { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
{ "adcB", { VexGb, Eb, Gb }, NO_PREFIX },
{ "adcS", { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
{ "adcB", { VexGb, Gb, EbS }, NO_PREFIX },
{ "adcS", { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
/* 18 */
{ "sbbB", { VexGb, Eb, Gb }, NO_PREFIX },
{ "sbbS", { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
{ "sbbB", { VexGb, Gb, EbS }, NO_PREFIX },
{ "sbbS", { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
{ "sbbB", { VexGb, Eb, Gb }, NO_PREFIX },
{ "sbbS", { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
{ "sbbB", { VexGb, Gb, EbS }, NO_PREFIX },
{ "sbbS", { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
/* 20 */
{ "andB", { VexGb, Eb, Gb }, NO_PREFIX },
{ "andS", { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
{ "andB", { VexGb, Gb, EbS }, NO_PREFIX },
{ "andS", { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
{ "shldS", { VexGv, Ev, Gv, Ib }, PREFIX_NP_OR_DATA },
{ "%NFandB", { VexGb, Eb, Gb }, NO_PREFIX },
{ "%NFandS", { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
{ "%NFandB", { VexGb, Gb, EbS }, NO_PREFIX },
{ "%NFandS", { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
{ "%NFshldS", { VexGv, Ev, Gv, Ib }, PREFIX_NP_OR_DATA },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
/* 28 */
{ "subB", { VexGb, Eb, Gb }, NO_PREFIX },
{ "subS", { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
{ "subB", { VexGb, Gb, EbS }, NO_PREFIX },
{ "subS", { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
{ "shrdS", { VexGv, Ev, Gv, Ib }, PREFIX_NP_OR_DATA },
{ "%NFsubB", { VexGb, Eb, Gb }, NO_PREFIX },
{ "%NFsubS", { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
{ "%NFsubB", { VexGb, Gb, EbS }, NO_PREFIX },
{ "%NFsubS", { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
{ "%NFshrdS", { VexGv, Ev, Gv, Ib }, PREFIX_NP_OR_DATA },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
/* 30 */
{ "xorB", { VexGb, Eb, Gb }, NO_PREFIX },
{ "xorS", { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
{ "xorB", { VexGb, Gb, EbS }, NO_PREFIX },
{ "xorS", { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
{ "%NFxorB", { VexGb, Eb, Gb }, NO_PREFIX },
{ "%NFxorS", { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
{ "%NFxorB", { VexGb, Gb, EbS }, NO_PREFIX },
{ "%NFxorS", { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
@ -993,9 +993,9 @@ static const struct dis386 evex_table[][256] = {
{ Bad_Opcode },
/* 68 */
{ Bad_Opcode },
{ "%NFimulS", { Gv, Ev, Iv }, PREFIX_NP_OR_DATA },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ "%NFimulS", { Gv, Ev, sIb }, PREFIX_NP_OR_DATA },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
@ -1028,7 +1028,7 @@ static const struct dis386 evex_table[][256] = {
{ Bad_Opcode },
{ Bad_Opcode },
/* 88 */
{ Bad_Opcode },
{ "%NFpopcntS", { Gv, Ev }, PREFIX_NP_OR_DATA },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
@ -1060,7 +1060,7 @@ static const struct dis386 evex_table[][256] = {
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ "shldS", { VexGv, Ev, Gv, CL }, PREFIX_NP_OR_DATA },
{ "%NFshldS", { VexGv, Ev, Gv, CL }, PREFIX_NP_OR_DATA },
{ Bad_Opcode },
{ Bad_Opcode },
/* A8 */
@ -1069,9 +1069,9 @@ static const struct dis386 evex_table[][256] = {
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ "shrdS", { VexGv, Ev, Gv, CL }, PREFIX_NP_OR_DATA },
{ "%NFshrdS", { VexGv, Ev, Gv, CL }, PREFIX_NP_OR_DATA },
{ Bad_Opcode },
{ "imulS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA },
{ "%NFimulS", { VexGv, Gv, Ev }, PREFIX_NP_OR_DATA },
/* B0 */
{ Bad_Opcode },
{ Bad_Opcode },
@ -1149,8 +1149,8 @@ static const struct dis386 evex_table[][256] = {
{ PREFIX_TABLE (PREFIX_EVEX_MAP4_F1) },
{ PREFIX_TABLE (PREFIX_EVEX_MAP4_F2) },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ "%NFtzcntS", { Gv, Ev }, PREFIX_NP_OR_DATA },
{ "%NFlzcntS", { Gv, Ev }, PREFIX_NP_OR_DATA },
{ REG_TABLE (REG_EVEX_MAP4_F6) },
{ REG_TABLE (REG_EVEX_MAP4_F7) },
/* F8 */

View File

@ -225,6 +225,7 @@ struct instr_info
bool zeroing;
bool b;
bool no_broadcast;
bool nf;
}
vex;
@ -1808,6 +1809,7 @@ struct dis386 {
"XV" => print "{vex} " pseudo prefix
"XE" => print "{evex} " pseudo prefix if no EVEX-specific functionality is
is used by an EVEX-encoded (AVX512VL) instruction.
"NF" => print "{nf} " pseudo prefix when EVEX.NF = 1.
"YK" keep unused, to avoid ambiguity with the combined use of Y and K.
"YX" keep unused, to avoid ambiguity with the combined use of Y and X.
"LQ" => print 'l' ('d' in Intel mode) or 'q' for memory operand, cond
@ -2612,25 +2614,25 @@ static const struct dis386 reg_table[][8] = {
},
/* REG_C0 */
{
{ "rolA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "rorA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "%NFrolA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "%NFrorA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "rclA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "rcrA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "shlA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "shrA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "shlA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "sarA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "%NFshlA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "%NFshrA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "%NFshlA", { VexGb, Eb, Ib }, NO_PREFIX },
{ "%NFsarA", { VexGb, Eb, Ib }, NO_PREFIX },
},
/* REG_C1 */
{
{ "rolQ", { VexGv, Ev, Ib }, PREFIX_NP_OR_DATA },
{ "rorQ", { VexGv, Ev, Ib }, PREFIX_NP_OR_DATA },
{ "%NFrolQ", { VexGv, Ev, Ib }, PREFIX_NP_OR_DATA },
{ "%NFrorQ", { VexGv, Ev, Ib }, PREFIX_NP_OR_DATA },
{ "rclQ", { VexGv, Ev, Ib }, PREFIX_NP_OR_DATA },
{ "rcrQ", { VexGv, Ev, Ib }, PREFIX_NP_OR_DATA },
{ "shlQ", { VexGv, Ev, Ib }, PREFIX_NP_OR_DATA },
{ "shrQ", { VexGv, Ev, Ib }, PREFIX_NP_OR_DATA },
{ "shlQ", { VexGv, Ev, Ib }, PREFIX_NP_OR_DATA },
{ "sarQ", { VexGv, Ev, Ib }, PREFIX_NP_OR_DATA },
{ "%NFshlQ", { VexGv, Ev, Ib }, PREFIX_NP_OR_DATA },
{ "%NFshrQ", { VexGv, Ev, Ib }, PREFIX_NP_OR_DATA },
{ "%NFshlQ", { VexGv, Ev, Ib }, PREFIX_NP_OR_DATA },
{ "%NFsarQ", { VexGv, Ev, Ib }, PREFIX_NP_OR_DATA },
},
/* REG_C6 */
{
@ -2656,47 +2658,47 @@ static const struct dis386 reg_table[][8] = {
},
/* REG_D0 */
{
{ "rolA", { VexGb, Eb, I1 }, NO_PREFIX },
{ "rorA", { VexGb, Eb, I1 }, NO_PREFIX },
{ "%NFrolA", { VexGb, Eb, I1 }, NO_PREFIX },
{ "%NFrorA", { VexGb, Eb, I1 }, NO_PREFIX },
{ "rclA", { VexGb, Eb, I1 }, NO_PREFIX },
{ "rcrA", { VexGb, Eb, I1 }, NO_PREFIX },
{ "shlA", { VexGb, Eb, I1 }, NO_PREFIX },
{ "shrA", { VexGb, Eb, I1 }, NO_PREFIX },
{ "shlA", { VexGb, Eb, I1 }, NO_PREFIX },
{ "sarA", { VexGb, Eb, I1 }, NO_PREFIX },
{ "%NFshlA", { VexGb, Eb, I1 }, NO_PREFIX },
{ "%NFshrA", { VexGb, Eb, I1 }, NO_PREFIX },
{ "%NFshlA", { VexGb, Eb, I1 }, NO_PREFIX },
{ "%NFsarA", { VexGb, Eb, I1 }, NO_PREFIX },
},
/* REG_D1 */
{
{ "rolQ", { VexGv, Ev, I1 }, PREFIX_NP_OR_DATA },
{ "rorQ", { VexGv, Ev, I1 }, PREFIX_NP_OR_DATA },
{ "%NFrolQ", { VexGv, Ev, I1 }, PREFIX_NP_OR_DATA },
{ "%NFrorQ", { VexGv, Ev, I1 }, PREFIX_NP_OR_DATA },
{ "rclQ", { VexGv, Ev, I1 }, PREFIX_NP_OR_DATA },
{ "rcrQ", { VexGv, Ev, I1 }, PREFIX_NP_OR_DATA },
{ "shlQ", { VexGv, Ev, I1 }, PREFIX_NP_OR_DATA },
{ "shrQ", { VexGv, Ev, I1 }, PREFIX_NP_OR_DATA },
{ "shlQ", { VexGv, Ev, I1 }, PREFIX_NP_OR_DATA },
{ "sarQ", { VexGv, Ev, I1 }, PREFIX_NP_OR_DATA },
{ "%NFshlQ", { VexGv, Ev, I1 }, PREFIX_NP_OR_DATA },
{ "%NFshrQ", { VexGv, Ev, I1 }, PREFIX_NP_OR_DATA },
{ "%NFshlQ", { VexGv, Ev, I1 }, PREFIX_NP_OR_DATA },
{ "%NFsarQ", { VexGv, Ev, I1 }, PREFIX_NP_OR_DATA },
},
/* REG_D2 */
{
{ "rolA", { VexGb, Eb, CL }, NO_PREFIX },
{ "rorA", { VexGb, Eb, CL }, NO_PREFIX },
{ "%NFrolA", { VexGb, Eb, CL }, NO_PREFIX },
{ "%NFrorA", { VexGb, Eb, CL }, NO_PREFIX },
{ "rclA", { VexGb, Eb, CL }, NO_PREFIX },
{ "rcrA", { VexGb, Eb, CL }, NO_PREFIX },
{ "shlA", { VexGb, Eb, CL }, NO_PREFIX },
{ "shrA", { VexGb, Eb, CL }, NO_PREFIX },
{ "shlA", { VexGb, Eb, CL }, NO_PREFIX },
{ "sarA", { VexGb, Eb, CL }, NO_PREFIX },
{ "%NFshlA", { VexGb, Eb, CL }, NO_PREFIX },
{ "%NFshrA", { VexGb, Eb, CL }, NO_PREFIX },
{ "%NFshlA", { VexGb, Eb, CL }, NO_PREFIX },
{ "%NFsarA", { VexGb, Eb, CL }, NO_PREFIX },
},
/* REG_D3 */
{
{ "rolQ", { VexGv, Ev, CL }, PREFIX_NP_OR_DATA },
{ "rorQ", { VexGv, Ev, CL }, PREFIX_NP_OR_DATA },
{ "%NFrolQ", { VexGv, Ev, CL }, PREFIX_NP_OR_DATA },
{ "%NFrorQ", { VexGv, Ev, CL }, PREFIX_NP_OR_DATA },
{ "rclQ", { VexGv, Ev, CL }, PREFIX_NP_OR_DATA },
{ "rcrQ", { VexGv, Ev, CL }, PREFIX_NP_OR_DATA },
{ "shlQ", { VexGv, Ev, CL }, PREFIX_NP_OR_DATA },
{ "shrQ", { VexGv, Ev, CL }, PREFIX_NP_OR_DATA },
{ "shlQ", { VexGv, Ev, CL }, PREFIX_NP_OR_DATA },
{ "sarQ", { VexGv, Ev, CL }, PREFIX_NP_OR_DATA },
{ "%NFshlQ", { VexGv, Ev, CL }, PREFIX_NP_OR_DATA },
{ "%NFshrQ", { VexGv, Ev, CL }, PREFIX_NP_OR_DATA },
{ "%NFshlQ", { VexGv, Ev, CL }, PREFIX_NP_OR_DATA },
{ "%NFsarQ", { VexGv, Ev, CL }, PREFIX_NP_OR_DATA },
},
/* REG_F6 */
{
@ -2937,9 +2939,9 @@ static const struct dis386 reg_table[][8] = {
/* REG_VEX_0F38F3_L_0_P_0 */
{
{ Bad_Opcode },
{ "blsrS", { VexGdq, Edq }, 0 },
{ "blsmskS", { VexGdq, Edq }, 0 },
{ "blsiS", { VexGdq, Edq }, 0 },
{ "%NFblsrS", { VexGdq, Edq }, 0 },
{ "%NFblsmskS", { VexGdq, Edq }, 0 },
{ "%NFblsiS", { VexGdq, Edq }, 0 },
},
/* REG_VEX_MAP7_F8_L_0_W_0 */
{
@ -4089,7 +4091,7 @@ static const struct dis386 prefix_table[][4] = {
/* PREFIX_VEX_0F38F2_L_0 */
{
{ "andnS", { Gdq, VexGdq, Edq }, 0 },
{ "%NFandnS", { Gdq, VexGdq, Edq }, 0 },
},
/* PREFIX_VEX_0F38F3_L_0 */
@ -4099,7 +4101,7 @@ static const struct dis386 prefix_table[][4] = {
/* PREFIX_VEX_0F38F5_L_0 */
{
{ "bzhiS", { Gdq, Edq, VexGdq }, 0 },
{ "%NFbzhiS", { Gdq, Edq, VexGdq }, 0 },
{ "pextS", { Gdq, VexGdq, Edq }, 0 },
{ Bad_Opcode },
{ "pdepS", { Gdq, VexGdq, Edq }, 0 },
@ -4115,7 +4117,7 @@ static const struct dis386 prefix_table[][4] = {
/* PREFIX_VEX_0F38F7_L_0 */
{
{ "bextrS", { Gdq, Edq, VexGdq }, 0 },
{ "%NFbextrS", { Gdq, Edq, VexGdq }, 0 },
{ "sarxS", { Gdq, Edq, VexGdq }, 0 },
{ "shlxS", { Gdq, Edq, VexGdq }, 0 },
{ "shrxS", { Gdq, Edq, VexGdq }, 0 },
@ -9140,6 +9142,9 @@ get_valid_dis386 (const struct dis386 *dp, instr_info *ins)
ins->vex.v = *ins->codep & 0x8;
ins->vex.mask_register_specifier = *ins->codep & 0x7;
ins->vex.zeroing = *ins->codep & 0x80;
/* Set the NF bit for EVEX-Promoted instructions, this bit will be cleared
when it's an evex_default one. */
ins->vex.nf = *ins->codep & 0x4;
if (ins->address_mode != mode_64bit)
{
@ -9593,6 +9598,15 @@ print_insn (bfd_vma pc, disassemble_info *info, int intel_syntax)
&& ins.vex.prefix == DATA_PREFIX_OPCODE)
sizeflag ^= DFLAG;
if(ins.evex_type == evex_default)
ins.vex.nf = false;
else
/* For EVEX-promoted formats, we need to clear EVEX.NF (ccmp and ctest
are cleared separately.) in mask_register_specifier and keep the low
2 bits of mask_register_specifier to report errors for invalid cases
. */
ins.vex.mask_register_specifier &= 0x3;
if (dp != NULL && putop (&ins, dp->name, sizeflag) == 0)
{
if (!get_sib (&ins, sizeflag))
@ -9645,6 +9659,9 @@ print_insn (bfd_vma pc, disassemble_info *info, int intel_syntax)
oappend (&ins, "/(bad)");
}
}
/* vex.nf is cleared after being consumed. */
if (ins.vex.nf)
oappend (&ins, "{bad-nf}");
/* Check whether rounding control was enabled for an insn not
supporting it, when evex.b is not treated as evex.nd. */
@ -10557,6 +10574,15 @@ putop (instr_info *ins, const char *in_template, int sizeflag)
}
else if (l == 1 && last[0] == 'C')
break;
else if (l == 1 && last[0] == 'N')
{
if (ins->vex.nf)
{
oappend (ins, "{nf} ");
/* This bit needs to be cleared after it is consumed. */
ins->vex.nf = false;
}
}
else
abort ();
break;

View File

@ -2365,7 +2365,8 @@ extern const char i386_mnemonics[];
#define MN__load_ 0x476b
#define MN__store_ 0x4772
#define MN__nooptimize_ 0x477a
#define MN__rex_ 0x4787
#define MN__evex_ 0x478d
#define MN__vex_ 0x4794
#define MN__insn 0x479a
#define MN__nf_ 0x4787
#define MN__rex_ 0x478c
#define MN__evex_ 0x4792
#define MN__vex_ 0x4799
#define MN__insn 0x479f

View File

@ -1018,6 +1018,7 @@ typedef struct insn_template
#define Prefix_REX 8 /* {rex} */
#define Prefix_REX2 9 /* {rex2} */
#define Prefix_NoOptimize 10 /* {nooptimize} */
#define Prefix_NF 11 /* {nf} */
/* the bits in opcode_modifier are used to generate the final opcode from
the base_opcode. These bits also are used to detect alternate forms of

View File

@ -320,17 +320,20 @@ sti, 0xfb, 0, NoSuf, {}
<alu2>, <alu2:opc> << 3, APX_F, D|<alu2:c>|W|CheckOperandSize|Modrm|No_sSuf|DstVVVV|EVexMap4|<alu2:nf>|<alu2:optz>, { Reg8|Reg16|Reg32|Reg64, Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg8|Reg16|Reg32|Reg64 }
<alu2>, <alu2:opc> << 3, 0, D|W|CheckOperandSize|Modrm|No_sSuf|HLEPrefixLock|<alu2:optz>|<alu2:optt>, { Reg8|Reg16|Reg32|Reg64, Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<alu2>, <alu2:opc> << 3, APX_F, D|W|CheckOperandSize|Modrm|No_sSuf|EVexMap4|<alu2:nf>, { Reg8|Reg16|Reg32|Reg64, Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<alu2>, 0x83/<alu2:opc>, APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|DstVVVV|EVexMap4|<alu2:nf>, { Imm8S, Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
<alu2>, 0x83/<alu2:opc>, 0, Modrm|No_bSuf|No_sSuf|HLEPrefixLock|<alu2:opti>, { Imm8S, Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<alu2>, 0x83/<alu2:opc>, 0, Modrm|No_bSuf|No_sSuf|EVexMap4|<alu2:nf>, { Imm8S, Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<alu2>, 0x04 | (<alu2:opc> << 3), 0, W|No_sSuf|<alu2:opti>, { Imm8|Imm16|Imm32|Imm32S, Acc|Byte|Word|Dword|Qword }
<alu2>, 0x80/<alu2:opc>, APX_F, W|Modrm|CheckOperandSize|No_sSuf|DstVVVV|EVexMap4|<alu2:nf>, { Imm8|Imm16|Imm32|Imm32S, Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg8|Reg16|Reg32|Reg64 }
<alu2>, 0x80/<alu2:opc>, 0, W|Modrm|No_sSuf|HLEPrefixLock|<alu2:opti>, { Imm8|Imm16|Imm32|Imm32S, Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<alu2>, 0x80/<alu2:opc>, APX_F, W|Modrm|EVexMap4|No_sSuf, { Imm8|Imm16|Imm32|Imm32S, Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<alu2>, 0x80/<alu2:opc>, APX_F, W|Modrm|EVexMap4|No_sSuf|<alu2:nf>, { Imm8|Imm16|Imm32|Imm32S, Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<alu2>
// clr with 1 operand is really xor with 2 operands.
clr, 0x30, 0, W|Modrm|No_sSuf|RegKludge|Optimize, { Reg8|Reg16|Reg32|Reg64 }
clr, 0x30, APX_F, W|Modrm|No_sSuf|RegKludge|EVexMap4|NF, { Reg8|Reg16|Reg32|Reg64 }
cmp, 0x38, 0, D|W|CheckOperandSize|Modrm|No_sSuf, { Reg8|Reg16|Reg32|Reg64, Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex }
cmp, 0x83/7, 0, Modrm|No_bSuf|No_sSuf, { Imm8S, Reg16|Reg32|Reg64|Unspecified|BaseIndex }
@ -346,6 +349,7 @@ test, 0xf6/0, 0, W|Modrm|No_sSuf|Optimize, { Imm8|Imm16|Imm32|Imm32S, Reg8|Reg16
<incdec>, 0x40 | (<incdec:opc> << 3), No64, No_bSuf|No_sSuf|No_qSuf, { Reg16|Reg32 }
<incdec>, 0xfe/<incdec:opc>, APX_F, W|Modrm|No_sSuf|CheckOperandSize|DstVVVV|EVexMap4|NF, {Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg8|Reg16|Reg32|Reg64}
<incdec>, 0xfe/<incdec:opc>, 0, W|Modrm|No_sSuf|HLEPrefixLock, { Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<incdec>, 0xfe/<incdec:opc>, APX_F, W|Modrm|No_sSuf|EVexMap4|NF, { Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<incdec>
@ -353,6 +357,7 @@ test, 0xf6/0, 0, W|Modrm|No_sSuf|Optimize, { Imm8|Imm16|Imm32|Imm32S, Reg8|Reg16
<alu1>, 0xf6/<alu1:opc>, APX_F, W|Modrm|CheckOperandSize|No_sSuf|DstVVVV|EVexMap4|<alu1:nf>, { Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg8|Reg16|Reg32|Reg64 }
<alu1>, 0xf6/<alu1:opc>, 0, W|Modrm|No_sSuf|HLEPrefixLock, { Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<alu1>, 0xf6/<alu1:opc>, APX_F, W|Modrm|No_sSuf|EVexMap4|<alu1:nf>, { Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<alu1>
@ -388,22 +393,30 @@ cqto, 0x99, x64, Size64|NoSuf, {}
<mul:opc, mul:4, imul:5>
<mul>, 0xf6/<mul:opc>, 0, W|Modrm|No_sSuf, { Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<mul>, 0xf6/<mul:opc>, APX_F, W|Modrm|No_sSuf|EVexMap4|NF, { Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex }
imul, 0xaf, APX_F, C|Modrm|CheckOperandSize|No_bSuf|No_sSuf|DstVVVV|EVexMap4|NF, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64, Reg16|Reg32|Reg64 }
imul, 0xfaf, i386, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
imul, 0xaf, APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4|NF, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
imul, 0x6b, i186, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Imm8S, Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
imul, 0x6b, APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4|NF, { Imm8S, Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
imul, 0x69, i186, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Imm16|Imm32|Imm32S, Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
imul, 0x69, APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4|NF, { Imm16|Imm32|Imm32S, Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
// imul with 2 operands mimics imul with 3 by putting the register in
// both i.rm.reg & i.rm.regmem fields. RegKludge enables this
// transformation.
imul, 0x6b, i186, Modrm|No_bSuf|No_sSuf|RegKludge, { Imm8S, Reg16|Reg32|Reg64 }
imul, 0x6b, APX_F, Modrm|No_bSuf|No_sSuf|RegKludge|EVexMap4|NF, { Imm8S, Reg16|Reg32|Reg64 }
imul, 0x69, i186, Modrm|No_bSuf|No_sSuf|RegKludge, { Imm16|Imm32|Imm32S, Reg16|Reg32|Reg64 }
imul, 0x69, APX_F, Modrm|No_bSuf|No_sSuf|RegKludge|EVexMap4|NF, { Imm16|Imm32|Imm32S, Reg16|Reg32|Reg64 }
<mul>
<div:opc, div:6, idiv:7>
<div>, 0xf6/<div:opc>, 0, W|Modrm|No_sSuf, { Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<div>, 0xf6/<div:opc>, APX_F, W|Modrm|No_sSuf|EVexMap4|NF, { Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<div>, 0xf6/<div:opc>, 0, W|CheckOperandSize|Modrm|No_sSuf, { Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex, Acc|Byte|Word|Dword|Qword }
<div>, 0xf6/<div:opc>, APX_F, W|CheckOperandSize|Modrm|No_sSuf|EVexMap4|NF, { Reg8|Reg16|Reg32|Reg64|Unspecified|BaseIndex, Acc|Byte|Word|Dword|Qword }
<div>
@ -434,8 +447,10 @@ imul, 0x69, i186, Modrm|No_bSuf|No_sSuf|RegKludge, { Imm16|Imm32|Imm32S, Reg16|R
sh<shd>d, 0x24 | <shd:opc>, APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|DstVVVV|EVexMap4|NF, { Imm8, Reg16|Reg32|Reg64, Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
sh<shd>d, 0x0fa4 | <shd:opc>, i386, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Imm8, Reg16|Reg32|Reg64, Reg16|Reg32|Reg64|Unspecified|BaseIndex }
sh<shd>d, 0x24 | <shd:opc>, APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4|NF, { Imm8, Reg16|Reg32|Reg64, Reg16|Reg32|Reg64|Unspecified|BaseIndex }
sh<shd>d, 0xa5 | <shd:opc>, APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|DstVVVV|EVexMap4|NF, { ShiftCount, Reg16|Reg32|Reg64, Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
sh<shd>d, 0x0fa5 | <shd:opc>, i386, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { ShiftCount, Reg16|Reg32|Reg64, Reg16|Reg32|Reg64|Unspecified|BaseIndex }
sh<shd>d, 0xa5 | <shd:opc>, APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4|NF, { ShiftCount, Reg16|Reg32|Reg64, Reg16|Reg32|Reg64|Unspecified|BaseIndex }
sh<shd>d, 0x0fa5 | <shd:opc>, i386, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Reg16|Reg32|Reg64, Reg16|Reg32|Reg64|Unspecified|BaseIndex }
<shd>
@ -896,7 +911,8 @@ rex.wrxb, 0x4f, x64, NoSuf|IsPrefix, {}
<pseudopfx:ident:cpu, disp8:Disp8:0, disp16:Disp16:No64, disp32:Disp32:i386, +
load:Load:0, store:Store:0, +
vex:VEX:0, vex2:VEX:0, vex3:VEX3:0, evex:EVEX:0, +
rex:REX:x64, rex2:REX2:APX_F, nooptimize:NoOptimize:0>
rex:REX:x64, rex2:REX2:APX_F, nf:NF:APX_F, +
nooptimize:NoOptimize:0>
{<pseudopfx>}, PSEUDO_PREFIX/Prefix_<pseudopfx:ident>, <pseudopfx:cpu>, NoSuf|IsPrefix, {}
@ -1944,6 +1960,7 @@ blsi, 0xf3/3, APX_F(BMI), Modrm|CheckOperandSize|Vex128|EVex128|Space0F38|VexVVV
blsmsk, 0xf3/2, APX_F(BMI), Modrm|CheckOperandSize|Vex128|EVex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf|NF, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 }
blsr, 0xf3/1, APX_F(BMI), Modrm|CheckOperandSize|Vex128|EVex128|Space0F38|VexVVVV|No_bSuf|No_wSuf|No_sSuf|NF, { Reg32|Reg64|Unspecified|BaseIndex, Reg32|Reg64 }
tzcnt, 0xf30fbc, BMI, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
tzcnt, 0xf4, BMI&APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4|NF, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
// TBM instructions
@ -2021,9 +2038,11 @@ insertq, 0xf20f78, SSE4a, Modrm|NoSuf, { Imm8, Imm8, RegXMM, RegXMM }
// LZCNT instruction
lzcnt, 0xf30fbd, LZCNT, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
lzcnt, 0xf5, LZCNT&APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4|NF, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
// POPCNT instruction
popcnt, 0xf30fb8, POPCNT, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
popcnt, 0x88, POPCNT&APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4|NF, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
// VIA PadLock extensions.
xstore-rng, 0xfa7c0, PadLock, NoSuf|RepPrefixOk, {}

File diff suppressed because it is too large Load Diff