RE: [PATCH v1 2/2] Support x86 ACE ISA
"Hu, Lin1" <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils |
|---|---|
| Message-ID | <PH3PPF801A91A7D9BCD052BC2228570C282A6F72@PH3PPF801A91A7D.namprd11.prod.outlook.com> |
> -----Original Message----- > From: Ganesh Gopalasubramanian <[email protected]> > Sent: Saturday, June 27, 2026 7:56 PM > To: [email protected] > Cc: Jiang, Haochen <[email protected]>; Beulich, Jan > <[email protected]>; Ganesh Gopalasubramanian > <[email protected]> > Subject: [PATCH v1 2/2] Support x86 ACE ISA > > Adds assembler and disassembler support for ACE tile, block scale register, outer > product, and MX FP8/INT8/BF16 instructions including: > bsrinit, bsrmovf/h/l, tilemovcol, tilemovrow, top2bf16ps, top4bssd/bsud/ > busd/buud, and top4mx* variants. > > All ACE v1 instructions are enumerated under a single ACE feature flag > (CPUID.(EAX=07H,ECX=1):ECX[11]), matching the specification. > > Key changes: > - opcodes/i386-opc.tbl: ACE instruction definitions with EVexMap6 macro > - opcodes/i386-gen.c: single ACE CPU feature and RegBS register class > - opcodes/i386-dis*.h: Disassembler dispatch tables for MAP6, 0F3A, 0F38 > - gas/config/tc-i386.c: ACE operand validation with proper scoping to > avoid interfering with AMX-AVX512 tilemovrow/tilemovcol variants > - gas/testsuite: ACE instruction test case > > The generated tables (opcodes/i386-init.h, opcodes/i386-mnem.h and > opcodes/i386-tbl.h) are omitted from this mail to keep it within the list size limit; > they are regenerated from opcodes/i386-opc.tbl and opcodes/i386-reg.tbl by > i386-gen and are reflected in the diffstat. > > Reference: AI Compute Extensions (ACE) Specification, v1.15 > https://x86ecosystem.org/wp- > content/uploads/2026/06/ACE_v1_Specification_public_1_15.pdf > > gas/ChangeLog: > > * NEWS: Mention x86 ACE instruction support. > * config/tc-i386.c (enum i386_error): Add unsupported_tile_index. > (cpu_arch): Add ace. > (_is_cpu): Handle CpuACE. > (type_names): Add RegBS ("bsr") entry. > (install_template): Handle CpuACE. > (i386_assemble): Handle unsupported_tile_index. > (check_ACE_operands): New function. > (match_template): Call check_ACE_operands. > (process_operands): Handle bsrinit like tilezero. > (output_insn): Set GNU_PROPERTY_X86_FEATURE_2_TMM for ACE. > (check_register): Allow TMM registers and the block scale > register for ACE. > * doc/c-i386.texi: Document .ace. > * testsuite/gas/i386/x86-64.exp: Run ACE tests. > * testsuite/gas/i386/x86-64-ace.d: New test. > * testsuite/gas/i386/x86-64-ace-intel.d: Ditto. > * testsuite/gas/i386/x86-64-ace.s: Ditto. > > opcodes/ChangeLog: > > * i386-dis.c (OP_BSR): New function. > (att_names_bsr): New. > (bsr, zmm_mode): New enumerators. > (REG_VEX_0F3849_X86_64_L_0_W_1_M_1_P_3): New. > (MOD_VEX_0F3849_X86_64_L_0_W_1): Ditto. > (RM_VEX_0F3849_X86_64_L_0_W_1_M_1_P_3_R_0): Ditto. > (PREFIX_VEX_0F3849_X86_64_L_0_W_1_M_1): Ditto. > (PREFIX_EVEX_0F384A, PREFIX_EVEX_0F384B, PREFIX_EVEX_0F385C): > Ditto. > (PREFIX_EVEX_0F385E, PREFIX_EVEX_0F3A07, PREFIX_EVEX_0F3A2F): > Ditto. > (PREFIX_EVEX_0F3A8D, PREFIX_EVEX_0F3A8F, PREFIX_EVEX_MAP6_95): > Ditto. > (EVEX_LEN_0F384B, EVEX_LEN_MAP6_95_P_0_W_1): Ditto. > (EVEX_W_MAP6_95_P_0, EVEX_W_MAP6_95_P_1, > EVEX_W_MAP6_95_P_3): Ditto. > (BSR, EXzmm, Rzmm, VexGd): Define. > (reg_table): Add REG_VEX_0F3849_X86_64_L_0_W_1_M_1_P_3. > (prefix_table): Add PREFIX_VEX_0F3849_X86_64_L_0_W_1_M_1. > (vex_w_table): Add W_1 entry to VEX_W_0F3849_X86_64_L_0. > (mod_table): Add MOD_VEX_0F3849_X86_64_L_0_W_1. > (rm_table): Add RM_VEX_0F3849_X86_64_L_0_W_1_M_1_P_3_R_0 > (bsrinit). > (intel_operand_size): Handle zmm_mode. > (OP_E_memory): Handle zmm_mode. > (print_vector_reg): Handle zmm_mode. > (OP_VEX): Select 512-bit register names by bytemode. > * i386-dis-evex.h: Add ACE entries to evex_table. > * i386-dis-evex-len.h: Add EVEX_LEN_0F384B and > EVEX_LEN_MAP6_95_P_0_W_1. > * i386-dis-evex-prefix.h: Add PREFIX_EVEX_0F384A, > PREFIX_EVEX_0F384B, > PREFIX_EVEX_0F385C, PREFIX_EVEX_0F385E, PREFIX_EVEX_0F3A07, > PREFIX_EVEX_0F3A2F, PREFIX_EVEX_0F3A8D, PREFIX_EVEX_0F3A8F and > PREFIX_EVEX_MAP6_95. > * i386-dis-evex-w.h: Add PREFIX_EVEX_0F384A and > PREFIX_EVEX_0F3A07 > entries; add EVEX_W_MAP6_95_P_0, EVEX_W_MAP6_95_P_1 and > EVEX_W_MAP6_95_P_3. > * i386-gen.c (isa_dependencies): Add ACE. > (cpu_flags): Add ACE. > (operand_classes): Add RegBS. > * i386-opc.h (CpuACE): New. > (i386_cpu): Add cpuace. > (operand_class): Add RegBS. > * i386-opc.tbl: Add RegBS and EVexMap6 macros. Add ACE > instructions and enable the AMX tile, tcvtrow* and tilemovrow > insns for ACE. > * i386-reg.tbl: Add bsr0 block scale register. > * i386-init.h: Regenerated. > * i386-mnem.h: Ditto. > * i386-tbl.h: Ditto. > > Co-authored-by: Umesh Kalvakuntla > --- > gas/NEWS | 4 + > gas/config/tc-i386.c | 52 +- > gas/doc/c-i386.texi | 3 +- > gas/testsuite/gas/i386/x86-64-ace-intel.d | 43 + > gas/testsuite/gas/i386/x86-64-ace.d | 43 + > gas/testsuite/gas/i386/x86-64-ace.s | 45 + > gas/testsuite/gas/i386/x86-64.exp | 2 + > opcodes/i386-dis-evex-len.h | 13 + > opcodes/i386-dis-evex-prefix.h | 57 + > opcodes/i386-dis-evex-w.h | 19 +- > opcodes/i386-dis-evex.h | 14 +- > opcodes/i386-dis.c | 115 +- > opcodes/i386-gen.c | 4 + > opcodes/i386-init.h | 608 +- > opcodes/i386-mnem.h | 3093 ++-- > opcodes/i386-opc.h | 4 + > opcodes/i386-opc.tbl | 68 +- > opcodes/i386-reg.tbl | 4 +- > opcodes/i386-tbl.h | 18961 ++++++++++---------- > 19 files changed, 11964 insertions(+), 11188 deletions(-) create mode 100644 > gas/testsuite/gas/i386/x86-64-ace-intel.d > create mode 100644 gas/testsuite/gas/i386/x86-64-ace.d > create mode 100644 gas/testsuite/gas/i386/x86-64-ace.s > > diff --git a/gas/NEWS b/gas/NEWS > index ef4bd048e4b..a02f11a46ed 100644 > --- a/gas/NEWS > +++ b/gas/NEWS > @@ -1,5 +1,9 @@ > -*- text -*- > > +* Add support for the x86 ACE (AI Compute Extensions) instructions, > + including tile data movement, block scale register operations and > +tile > + outer products. > + > * Add support for the x86 AVX10_V2_AUX instructions, providing FP8, FP4 > and FP6 format conversion instructions. > > diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index > d82ed061a78..f6f40589d11 100644 > --- a/gas/config/tc-i386.c > +++ b/gas/config/tc-i386.c > @@ -272,6 +272,7 @@ enum i386_error > unsupported_rc_sae, > unsupported_vector_size, > unsupported_rsp_register, > + unsupported_tile_index, > internal_error, > }; > > @@ -1200,6 +1201,7 @@ static const arch_entry cpu_arch[] = > SUBARCH (pconfig, PCONFIG, PCONFIG, false), > SUBARCH (waitpkg, WAITPKG, WAITPKG, false), > SUBARCH (cldemote, CLDEMOTE, CLDEMOTE, false), > + SUBARCH (ace, ACE, ACE, false), > SUBARCH (amx_int8, AMX_INT8, ANY_AMX_INT8, false), > SUBARCH (amx_bf16, AMX_BF16, ANY_AMX_BF16, false), > SUBARCH (amx_fp16, AMX_FP16, ANY_AMX_FP16, false), @@ -1894,6 +1896,7 > @@ _is_cpu (const i386_cpu_attr *a, enum i386_cpu cpu) > case CpuAPX_F: return a->bitfield.cpuapx_f; > case CpuAVX10_2: return a->bitfield.cpuavx10_2; > case CpuAMX_TRANSPOSE: return a->bitfield.cpuamx_transpose; > + case CpuACE: return a->bitfield.cpuace; > case Cpu64: return a->bitfield.cpu64; > case CpuNo64: return a->bitfield.cpuno64; > default: > @@ -3933,6 +3936,7 @@ const type_names[] = > { { .bitfield = { .class = RegSIMD, .zmmword = 1 } }, "rZMM" }, > { { .bitfield = { .class = RegSIMD, .tmmword = 1 } }, "rTMM" }, > { { .bitfield = { .class = RegMask } }, "Mask reg" }, > + { { .bitfield = { .class = RegBS } }, "bsr" }, > }; > > static void > @@ -4253,6 +4257,7 @@ install_template (const insn_template *t) > } > > if ((maybe_cpu (t, CpuCMPCCXADD) || maybe_cpu (t, CpuAMX_TILE) > + || maybe_cpu (t, CpuACE) Outer condition is if (t->opcode_modifier.vex && t->opcode_modifier.evex), seems that the line is invalid. > || maybe_cpu (t, CpuAVX512F) || maybe_cpu (t, CpuAVX512DQ) > || maybe_cpu (t, CpuAVX512BW) || maybe_cpu (t, CpuBMI) > || maybe_cpu (t, CpuBMI2) || maybe_cpu (t, CpuUSER_MSR) @@ - > 7498,6 +7503,9 @@ i386_assemble (char *line) > case unsupported_rsp_register: > err_msg = _("'rsp' register cannot be used"); > break; > + case unsupported_tile_index: > + err_msg = _("immediate value must be in range 0-15"); > + break; > case internal_error: > err_msg = _("internal error"); > break; > @@ -9323,6 +9331,29 @@ check_APX_operands (const insn_template *t) > return 0; > } > > +/* Check if ACE operands are valid for the instruction. */ static bool > +check_ACE_operands (const insn_template *t) { > + switch (t->mnem_off) > + { > + case MN_tilemovrow: > + case MN_tilemovcol: > + if (is_cpu (t, CpuACE) > + && i.op[0].imms && i.op[0].imms->X_op == O_constant) > + { > + offsetT val = i.op[0].imms->X_add_number; > + if (val < 0 || val > 15) > + { > + i.error = unsupported_tile_index; > + return 1; > + } > + } > + break; > + } > + return 0; > +} > + > /* Check if the instruction use the REX registers or REX prefix. */ static bool > check_Rex_required (void) @@ -9905,6 +9936,13 @@ match_template (char > mnem_suffix) > continue; > } > > + /* Check if ACE operands are valid. */ > + if (check_ACE_operands (t)) > + { > + specific_error = progress (i.error); > + continue; > + } > + > /* Check whether to use the shorter VEX encoding for certain insns where > the EVEX encoding comes first in the table. This requires the respective > AVX-* feature to be explicitly enabled. > @@ -10994,7 +11032,7 @@ process_operands (void) > not ModR/M.rm. To avoid special casing this in build_modrm_byte(), fake a > new destination operand here, while converting the source one to register > number 0. */ > - if (i.tm.mnem_off == MN_tilezero) > + if (i.tm.mnem_off == MN_tilezero || i.tm.mnem_off == MN_bsrinit) > { > copy_operand (1, 0); > i.op[0].regs -= i.op[0].regs->reg_num; @@ -12475,7 +12513,8 @@ > output_insn (const struct last_insn *last_insn) > unsigned int feature_2_used = 0; > > if ((i.xstate & xstate_tmm) == xstate_tmm > - || is_cpu (&i.tm, CpuAMX_TILE)) > + || is_cpu (&i.tm, CpuAMX_TILE) > + || is_cpu (&i.tm, CpuACE)) > feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_TMM; > > if (is_cpu (&i.tm, Cpu8087) > @@ -16943,13 +16982,18 @@ static bool check_register (const reg_entry *r) > return false; > > if (r->reg_type.bitfield.tmmword > - && (!cpu_arch_flags.bitfield.cpuamx_tile > - || flag_code != CODE_64BIT)) > + && ((!cpu_arch_flags.bitfield.cpuamx_tile > + && !cpu_arch_flags.bitfield.cpuace) > + || flag_code != CODE_64BIT)) > return false; > > if (r->reg_type.bitfield.class == RegBND && !cpu_arch_flags.bitfield.cpumpx) > return false; > > + if (r->reg_type.bitfield.class == RegBS > + && !cpu_arch_flags.bitfield.cpuace) > + return false; > + > /* Don't allow fake index register unless allow_index_reg isn't 0. */ > if (!allow_index_reg && r->reg_num == RegIZ) > return false; > diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi index > 9f6e8da443d..5d1e15816af 100644 > --- a/gas/doc/c-i386.texi > +++ b/gas/doc/c-i386.texi > @@ -242,6 +242,7 @@ accept various extension mnemonics. For example, > @code{amx_movrs}, @code{amx_avx512}, @code{amx_tile}, > +@code{ace}, > @code{vmx}, > @code{vmfunc}, > @code{smx}, > @@ -1731,7 +1732,7 @@ supported on the CPU specified. The choices for > @var{cpu_type} are: > @item @samp{.amx_int8} @tab @samp{.amx_bf16} @tab @samp{.amx_fp16} > @item @samp{.amx_complex} @tab @samp{.amx_transpose} @tab > @samp{.amx_tf32} @item @samp{.amx_fp8} @tab @samp{.amx_movrs} @tab > @samp{.amx_avx512} -@item @samp{.amx_tile} > +@item @samp{.amx_tile} @tab @samp{.ace} > @item @samp{.kl} @tab @samp{.widekl} @tab @samp{.uintr} @tab > @samp{.hreset} @item @samp{.3dnow} @tab @samp{.3dnowa} @tab > @samp{.sse4a} @tab @samp{.sse5} @item @samp{.syscall} @tab > @samp{.rdtscp} @tab @samp{.svme} diff --git a/gas/testsuite/gas/i386/x86-64- > ace-intel.d b/gas/testsuite/gas/i386/x86-64-ace-intel.d > new file mode 100644 > index 00000000000..b116845d240 > --- /dev/null > +++ b/gas/testsuite/gas/i386/x86-64-ace-intel.d > @@ -0,0 +1,43 @@ > +#objdump: -dw -Mintel > +#name: 64-bit ACE insns (Intel disassembly) > +#source: x86-64-ace.s > + > +.*: +file format .* > + > +Disassembly of section \.text: > + > +[0-9a-f]+ <start>: > +[\s]*[a-f0-9]+:[\s]*c4 e2 fb 49 c0[\s]*bsrinit bsr0 > +[\s]*[a-f0-9]+:[\s]*62 f6 f4 48 95 c3[\s]*bsrmovf bsr0,zmm1,zmm3 > +[\s]*[a-f0-9]+:[\s]*62 d6 ff 48 95 c2[\s]*bsrmovh bsr0,zmm10 > +[\s]*[a-f0-9]+:[\s]*62 d6 fe 48 95 c2[\s]*bsrmovl bsr0,zmm10 > +[\s]*[a-f0-9]+:[\s]*67 62 f6 ff 48 95 00[\s]*bsrmovh bsr0,ZMMWORD PTR > +\[eax\] > +[\s]*[a-f0-9]+:[\s]*67 62 f6 fe 48 95 00[\s]*bsrmovl bsr0,ZMMWORD PTR > +\[eax\] > +[\s]*[a-f0-9]+:[\s]*62 f6 7f 48 95 c4[\s]*bsrmovh zmm4,bsr0 > +[\s]*[a-f0-9]+:[\s]*62 f6 7e 48 95 c4[\s]*bsrmovl zmm4,bsr0 > +[\s]*[a-f0-9]+:[\s]*67 62 f6 7f 48 95 00[\s]*bsrmovh ZMMWORD PTR > +\[eax\],bsr0 > +[\s]*[a-f0-9]+:[\s]*67 62 f6 7e 48 95 00[\s]*bsrmovl ZMMWORD PTR > +\[eax\],bsr0 > +[\s]*[a-f0-9]+:[\s]*62 f3 fd 48 2f ca 08[\s]*tilemovcol tmm1,zmm2,0x8 > +[\s]*[a-f0-9]+:[\s]*62 f3 fd 48 07 ca 08[\s]*tilemovrow tmm1,zmm2,0x8 > +[\s]*[a-f0-9]+:[\s]*62 f2 e5 48 4b ca[\s]*tilemovcol tmm1,zmm2,ebx > +[\s]*[a-f0-9]+:[\s]*62 f2 e5 48 4a ca[\s]*tilemovrow tmm1,zmm2,ebx > +[\s]*[a-f0-9]+:[\s]*62 f2 6e 48 5c c1[\s]*top2bf16ps tmm0,zmm1,zmm2 > +[\s]*[a-f0-9]+:[\s]*62 f2 6f 48 5e c1[\s]*top4bssd tmm0,zmm1,zmm2 > +[\s]*[a-f0-9]+:[\s]*62 f2 6e 48 5e c1[\s]*top4bsud tmm0,zmm1,zmm2 > +[\s]*[a-f0-9]+:[\s]*62 f2 6d 48 5e c1[\s]*top4busd tmm0,zmm1,zmm2 > +[\s]*[a-f0-9]+:[\s]*62 f2 6c 48 5e c1[\s]*top4buud tmm0,zmm1,zmm2 > +[\s]*[a-f0-9]+:[\s]*62 f3 6c 48 8d c9 07[\s]*top4mxbf8ps > +tmm1,zmm1,zmm2,0x7 > +[\s]*[a-f0-9]+:[\s]*62 f3 6f 48 8d c9 07[\s]*top4mxbhf8ps > +tmm1,zmm1,zmm2,0x7 > +[\s]*[a-f0-9]+:[\s]*62 f3 6e 48 8d c9 07[\s]*top4mxhbf8ps > +tmm1,zmm1,zmm2,0x7 > +[\s]*[a-f0-9]+:[\s]*62 f3 6d 48 8d c9 07[\s]*top4mxhf8ps > +tmm1,zmm1,zmm2,0x7 > +[\s]*[a-f0-9]+:[\s]*62 f3 6f 48 8f c9 07[\s]*top4mxbssps > +tmm1,zmm1,zmm2,0x7 > +[\s]*[a-f0-9]+:[\s]*62 62 6e 48 4a f5[\s]*tcvtrowd2ps zmm30,tmm5,edx > +[\s]*[a-f0-9]+:[\s]*62 63 7e 48 07 f5 7b[\s]*tcvtrowd2ps > +zmm30,tmm5,0x7b > +[\s]*[a-f0-9]+:[\s]*62 62 6f 48 6d f5[\s]*tcvtrowps2bf16h > +zmm30,tmm5,edx > +[\s]*[a-f0-9]+:[\s]*62 63 7f 48 07 f5 7b[\s]*tcvtrowps2bf16h > +zmm30,tmm5,0x7b > +[\s]*[a-f0-9]+:[\s]*62 62 6e 48 6d f5[\s]*tcvtrowps2bf16l > +zmm30,tmm5,edx > +[\s]*[a-f0-9]+:[\s]*62 63 7e 48 77 f5 7b[\s]*tcvtrowps2bf16l > +zmm30,tmm5,0x7b > +[\s]*[a-f0-9]+:[\s]*62 62 6c 48 6d f5[\s]*tcvtrowps2phh zmm30,tmm5,edx > +[\s]*[a-f0-9]+:[\s]*62 63 7c 48 07 f5 7b[\s]*tcvtrowps2phh > +zmm30,tmm5,0x7b > +[\s]*[a-f0-9]+:[\s]*62 62 6d 48 6d f5[\s]*tcvtrowps2phl zmm30,tmm5,edx > +[\s]*[a-f0-9]+:[\s]*62 63 7f 48 77 f5 7b[\s]*tcvtrowps2phl > +zmm30,tmm5,0x7b > diff --git a/gas/testsuite/gas/i386/x86-64-ace.d b/gas/testsuite/gas/i386/x86- > 64-ace.d > new file mode 100644 > index 00000000000..cc91aa7fede > --- /dev/null > +++ b/gas/testsuite/gas/i386/x86-64-ace.d > @@ -0,0 +1,43 @@ > +#objdump: -dw > +#name: 64-bit ACE insns > +#source: x86-64-ace.s > + > +.*: +file format .* > + > +Disassembly of section \.text: > + > +[0-9a-f]+ <start>: > +[\s]*[a-f0-9]+:[\s]*c4 e2 fb 49 c0[\s]*bsrinit %bsr0 > +[\s]*[a-f0-9]+:[\s]*62 f6 f4 48 95 c3[\s]*bsrmovf %zmm3,%zmm1,%bsr0 > +[\s]*[a-f0-9]+:[\s]*62 d6 ff 48 95 c2[\s]*bsrmovh %zmm10,%bsr0 > +[\s]*[a-f0-9]+:[\s]*62 d6 fe 48 95 c2[\s]*bsrmovl %zmm10,%bsr0 > +[\s]*[a-f0-9]+:[\s]*67 62 f6 ff 48 95 00[\s]*bsrmovh \(%eax\),%bsr0 > +[\s]*[a-f0-9]+:[\s]*67 62 f6 fe 48 95 00[\s]*bsrmovl \(%eax\),%bsr0 > +[\s]*[a-f0-9]+:[\s]*62 f6 7f 48 95 c4[\s]*bsrmovh %bsr0,%zmm4 > +[\s]*[a-f0-9]+:[\s]*62 f6 7e 48 95 c4[\s]*bsrmovl %bsr0,%zmm4 > +[\s]*[a-f0-9]+:[\s]*67 62 f6 7f 48 95 00[\s]*bsrmovh %bsr0,\(%eax\) > +[\s]*[a-f0-9]+:[\s]*67 62 f6 7e 48 95 00[\s]*bsrmovl %bsr0,\(%eax\) > +[\s]*[a-f0-9]+:[\s]*62 f3 fd 48 2f ca 08[\s]*tilemovcol > +\$0x8,%zmm2,%tmm1 > +[\s]*[a-f0-9]+:[\s]*62 f3 fd 48 07 ca 08[\s]*tilemovrow > +\$0x8,%zmm2,%tmm1 > +[\s]*[a-f0-9]+:[\s]*62 f2 e5 48 4b ca[\s]*tilemovcol %ebx,%zmm2,%tmm1 > +[\s]*[a-f0-9]+:[\s]*62 f2 e5 48 4a ca[\s]*tilemovrow %ebx,%zmm2,%tmm1 > +[\s]*[a-f0-9]+:[\s]*62 f2 6e 48 5c c1[\s]*top2bf16ps %zmm2,%zmm1,%tmm0 > +[\s]*[a-f0-9]+:[\s]*62 f2 6f 48 5e c1[\s]*top4bssd %zmm2,%zmm1,%tmm0 > +[\s]*[a-f0-9]+:[\s]*62 f2 6e 48 5e c1[\s]*top4bsud %zmm2,%zmm1,%tmm0 > +[\s]*[a-f0-9]+:[\s]*62 f2 6d 48 5e c1[\s]*top4busd %zmm2,%zmm1,%tmm0 > +[\s]*[a-f0-9]+:[\s]*62 f2 6c 48 5e c1[\s]*top4buud %zmm2,%zmm1,%tmm0 > +[\s]*[a-f0-9]+:[\s]*62 f3 6c 48 8d c9 07[\s]*top4mxbf8ps > +\$0x7,%zmm2,%zmm1,%tmm1 > +[\s]*[a-f0-9]+:[\s]*62 f3 6f 48 8d c9 07[\s]*top4mxbhf8ps > +\$0x7,%zmm2,%zmm1,%tmm1 > +[\s]*[a-f0-9]+:[\s]*62 f3 6e 48 8d c9 07[\s]*top4mxhbf8ps > +\$0x7,%zmm2,%zmm1,%tmm1 > +[\s]*[a-f0-9]+:[\s]*62 f3 6d 48 8d c9 07[\s]*top4mxhf8ps > +\$0x7,%zmm2,%zmm1,%tmm1 > +[\s]*[a-f0-9]+:[\s]*62 f3 6f 48 8f c9 07[\s]*top4mxbssps > +\$0x7,%zmm2,%zmm1,%tmm1 > +[\s]*[a-f0-9]+:[\s]*62 62 6e 48 4a f5[\s]*tcvtrowd2ps %edx,%tmm5,%zmm30 > +[\s]*[a-f0-9]+:[\s]*62 63 7e 48 07 f5 7b[\s]*tcvtrowd2ps > +\$0x7b,%tmm5,%zmm30 > +[\s]*[a-f0-9]+:[\s]*62 62 6f 48 6d f5[\s]*tcvtrowps2bf16h > +%edx,%tmm5,%zmm30 > +[\s]*[a-f0-9]+:[\s]*62 63 7f 48 07 f5 7b[\s]*tcvtrowps2bf16h > +\$0x7b,%tmm5,%zmm30 > +[\s]*[a-f0-9]+:[\s]*62 62 6e 48 6d f5[\s]*tcvtrowps2bf16l > +%edx,%tmm5,%zmm30 > +[\s]*[a-f0-9]+:[\s]*62 63 7e 48 77 f5 7b[\s]*tcvtrowps2bf16l > +\$0x7b,%tmm5,%zmm30 > +[\s]*[a-f0-9]+:[\s]*62 62 6c 48 6d f5[\s]*tcvtrowps2phh > +%edx,%tmm5,%zmm30 > +[\s]*[a-f0-9]+:[\s]*62 63 7c 48 07 f5 7b[\s]*tcvtrowps2phh > +\$0x7b,%tmm5,%zmm30 > +[\s]*[a-f0-9]+:[\s]*62 62 6d 48 6d f5[\s]*tcvtrowps2phl > +%edx,%tmm5,%zmm30 > +[\s]*[a-f0-9]+:[\s]*62 63 7f 48 77 f5 7b[\s]*tcvtrowps2phl > +\$0x7b,%tmm5,%zmm30 > diff --git a/gas/testsuite/gas/i386/x86-64-ace.s b/gas/testsuite/gas/i386/x86-64- > ace.s > new file mode 100644 > index 00000000000..9c7bf8a2214 > --- /dev/null > +++ b/gas/testsuite/gas/i386/x86-64-ace.s > @@ -0,0 +1,45 @@ > +# Check 64-bit ACE instructions > + > + .text > +start: > + bsrinit %bsr0 > + bsrmovf %zmm3, %zmm1, %bsr0 > + > + bsrmovh %zmm10, %bsr0 > + bsrmovl %zmm10, %bsr0 > + bsrmovh (%eax), %bsr0 > + bsrmovl (%eax), %bsr0 > + > + bsrmovh %bsr0, %zmm4 > + bsrmovl %bsr0, %zmm4 > + bsrmovh %bsr0, (%eax) > + bsrmovl %bsr0, (%eax) > + > + tilemovcol $8, %zmm2, %tmm1 > + tilemovrow $8, %zmm2, %tmm1 > + > + tilemovcol %ebx, %zmm2, %tmm1 > + tilemovrow %ebx, %zmm2, %tmm1 > + > + top2bf16ps %zmm2, %zmm1, %tmm0 > + top4bssd %zmm2, %zmm1, %tmm0 > + top4bsud %zmm2, %zmm1, %tmm0 > + top4busd %zmm2, %zmm1, %tmm0 > + top4buud %zmm2, %zmm1, %tmm0 > + > + top4mxbf8ps $7, %zmm2, %zmm1, %tmm1 > + top4mxbhf8ps $7, %zmm2, %zmm1, %tmm1 > + top4mxhbf8ps $7, %zmm2, %zmm1, %tmm1 > + top4mxhf8ps $7, %zmm2, %zmm1, %tmm1 > + top4mxbssps $7, %zmm2, %zmm1, %tmm1 > + > + tcvtrowd2ps %edx, %tmm5, %zmm30 > + tcvtrowd2ps $0x7b, %tmm5, %zmm30 > + tcvtrowps2bf16h %edx, %tmm5, %zmm30 > + tcvtrowps2bf16h $0x7b, %tmm5, %zmm30 > + tcvtrowps2bf16l %edx, %tmm5, %zmm30 > + tcvtrowps2bf16l $0x7b, %tmm5, %zmm30 > + tcvtrowps2phh %edx, %tmm5, %zmm30 > + tcvtrowps2phh $0x7b, %tmm5, %zmm30 > + tcvtrowps2phl %edx, %tmm5, %zmm30 > + tcvtrowps2phl $0x7b, %tmm5, %zmm30 > diff --git a/gas/testsuite/gas/i386/x86-64.exp b/gas/testsuite/gas/i386/x86- > 64.exp > index d0d3cb47117..ae5d8bff1ba 100644 > --- a/gas/testsuite/gas/i386/x86-64.exp > +++ b/gas/testsuite/gas/i386/x86-64.exp > @@ -689,6 +689,8 @@ run_list_test "x86-64-amx-inval" > run_dump_test "x86-64-amx" > run_dump_test "x86-64-amx-intel" > run_dump_test "x86-64-amx-bad" > +run_dump_test "x86-64-ace" > +run_dump_test "x86-64-ace-intel" > > if { ![istarget "*-*-aix*"] > && ![istarget "*-*-beos*"] > diff --git a/opcodes/i386-dis-evex-len.h b/opcodes/i386-dis-evex-len.h index > 370710915de..273c6d40d12 100644 > --- a/opcodes/i386-dis-evex-len.h > +++ b/opcodes/i386-dis-evex-len.h > @@ -51,6 +51,13 @@ static const struct dis386 evex_len_table[][3] = { > { PREFIX_TABLE (PREFIX_EVEX_0F384A_X86_64_W_0_L_2) }, > }, > > + /* EVEX_LEN_0F384B */ > + { > + { X86_64_EVEX_W_TABLE (VEX_W_0F384B_X86_64_L_0) }, > + { Bad_Opcode }, > + { PREFIX_TABLE (PREFIX_EVEX_0F384B) }, }, > + > /* EVEX_LEN_0F385A */ > { > { Bad_Opcode }, > @@ -207,4 +214,10 @@ static const struct dis386 evex_len_table[][3] = { > { "vbmacxor16x16x16", { XM, Vex, EXx }, NO_PREFIX }, > { "vbmacxor16x16x16", { XM, Vex, EXx }, NO_PREFIX }, > }, > + /* EVEX_LEN_MAP6_95_P_0_W_1 */ > + { > + { Bad_Opcode }, > + { Bad_Opcode }, > + { "bsrmovf", { BSR, Vex, EXx }, 0 }, }, > }; > diff --git a/opcodes/i386-dis-evex-prefix.h b/opcodes/i386-dis-evex-prefix.h > index ffecef5e796..f3b031470df 100644 > --- a/opcodes/i386-dis-evex-prefix.h > +++ b/opcodes/i386-dis-evex-prefix.h > @@ -254,6 +254,18 @@ > { "tcvtrowd2ps", { XM, Rtmm, VexGdq }, 0 }, > { "tilemovrow", { XM, Rtmm, VexGdq }, 0 }, > }, > + /* PREFIX_EVEX_0F384A */ > + { > + { Bad_Opcode }, > + { Bad_Opcode }, > + { "tilemovrow", { TMM, Rzmm, VexGd }, 0 }, > + }, > + /* PREFIX_EVEX_0F384B */ > + { > + { Bad_Opcode }, > + { Bad_Opcode }, > + { "tilemovcol", { TMM, Rzmm, VexGd }, 0 }, > + }, > /* PREFIX_EVEX_0F3852 */ > { > { "vdpphp%XS", { XM, Vex, EXx }, 0 }, > @@ -268,6 +280,18 @@ > { VEX_W_TABLE (VEX_W_0F3853) }, > { "vp4dpws%XSds", { XM, Vex, Mxmm }, 0 }, > }, > + /* PREFIX_EVEX_0F385C */ > + { > + { Bad_Opcode }, > + { "top2bf16ps", { TMM, Rzmm, Vex }, 0 }, > + }, > + /* PREFIX_EVEX_0F385E */ > + { > + { "top4buud", { TMM, Rzmm, Vex }, 0 }, > + { "top4bsud", { TMM, Rzmm, Vex }, 0 }, > + { "top4busd", { TMM, Rzmm, Vex }, 0 }, > + { "top4bssd", { TMM, Rzmm, Vex }, 0 }, > + }, > /* PREFIX_EVEX_0F3868 */ > { > { Bad_Opcode }, > @@ -331,6 +355,12 @@ > { "tilemovrow", { XM, Rtmm, Ib }, 0 }, > { "tcvtrowps2bf16h", { XM, Rtmm, Ib }, 0 }, > }, > + /* PREFIX_EVEX_0F3A07 */ > + { > + { Bad_Opcode }, > + { Bad_Opcode }, > + { "tilemovrow", { TMM, Rzmm, Ib }, 0 }, }, > /* PREFIX_EVEX_0F3A08 */ > { > { "vrndscalep%XH", { XM, EXxh, EXxEVexS, Ib }, 0 }, @@ -357,6 +387,12 @@ > { Bad_Opcode }, > { "vgetmants%XW", { XMScalar, VexScalar, EXdq, EXxEVexS, Ib }, 0 }, > }, > + /* PREFIX_EVEX_0F3A2F */ > + { > + { Bad_Opcode }, > + { Bad_Opcode }, > + { "tilemovcol", { TMM, Rzmm, Ib }, 0 }, }, > /* PREFIX_EVEX_0F3A42_W_0 */ > { > { Bad_Opcode }, > @@ -409,6 +445,20 @@ > { Bad_Opcode }, > { "tcvtrowps2phl", { XM, Rtmm, Ib }, 0 }, > }, > + /* PREFIX_EVEX_0F3A8D */ > + { > + { "top4mxbf8ps", { TMM, Rzmm, Vex, Ib }, 0 }, > + { "top4mxhbf8ps", { TMM, Rzmm, Vex, Ib }, 0 }, > + { "top4mxhf8ps", { TMM, Rzmm, Vex, Ib }, 0 }, > + { "top4mxbhf8ps", { TMM, Rzmm, Vex, Ib }, 0 }, > + }, > + /* PREFIX_EVEX_0F3A8F */ > + { > + { Bad_Opcode }, > + { Bad_Opcode }, > + { Bad_Opcode }, > + { "top4mxbssps", { TMM, Rzmm, Vex, Ib }, 0 }, > + }, > /* PREFIX_EVEX_0F3AC2 */ > { > { "vcmpp%XH", { MaskG, Vex, EXxh, EXxEVexS, CMP }, 0 }, @@ -833,6 +883,13 > @@ > { Bad_Opcode }, > { "vfnmsub231p%XH", { XM, Vex, EXxh, EXxEVexR }, 0 }, > }, > + /* PREFIX_EVEX_MAP6_95 */ > + { > + { VEX_W_TABLE (EVEX_W_MAP6_95_P_0) }, > + { VEX_W_TABLE (EVEX_W_MAP6_95_P_1) }, > + { Bad_Opcode }, > + { VEX_W_TABLE (EVEX_W_MAP6_95_P_3) }, }, > /* PREFIX_EVEX_MAP6_D6 */ > { > { Bad_Opcode }, > diff --git a/opcodes/i386-dis-evex-w.h b/opcodes/i386-dis-evex-w.h index > 6e94bc45fe1..8e0529e1a08 100644 > --- a/opcodes/i386-dis-evex-w.h > +++ b/opcodes/i386-dis-evex-w.h > @@ -349,6 +349,7 @@ > /* EVEX_W_0F384A_X86_64 */ > { > { EVEX_LEN_TABLE (EVEX_LEN_0F384A_X86_64_W_0) }, > + { PREFIX_TABLE (PREFIX_EVEX_0F384A) }, > }, > /* EVEX_W_0F3859 */ > { > @@ -395,6 +396,7 @@ > /* EVEX_W_0F3A07_X86_64 */ > { > { EVEX_LEN_TABLE (EVEX_LEN_0F3A07_X86_64_W_0) }, > + { PREFIX_TABLE (PREFIX_EVEX_0F3A07) }, > }, > /* EVEX_W_0F3A18_L_n */ > { > @@ -553,4 +555,19 @@ > { > { "vbitrevb", { XM, EXx }, NO_PREFIX }, > { Bad_Opcode } > - } > + }, > + /* EVEX_W_MAP6_95_P_0 */ > + { > + { Bad_Opcode }, > + { EVEX_LEN_TABLE (EVEX_LEN_MAP6_95_P_0_W_1) }, }, > + /* EVEX_W_MAP6_95_P_1 */ > + { > + { "bsrmovl", { EXzmm, BSR }, 0 }, > + { "bsrmovl", { BSR, EXzmm }, 0 }, > + }, > + /* EVEX_W_MAP6_95_P_3 */ > + { > + { "bsrmovh", { EXzmm, BSR }, 0 }, > + { "bsrmovh", { BSR, EXzmm }, 0 }, > + }, > diff --git a/opcodes/i386-dis-evex.h b/opcodes/i386-dis-evex.h index > 7d555aa9e11..9ad57912231 100644 > --- a/opcodes/i386-dis-evex.h > +++ b/opcodes/i386-dis-evex.h > @@ -377,7 +377,7 @@ static const struct dis386 evex_table[][256] = { > { Bad_Opcode }, > { X86_64_EVEX_MEM_W_TABLE (VEX_W_0F3849_X86_64_L_0) }, > { X86_64_TABLE (X86_64_EVEX_0F384A) }, > - { X86_64_EVEX_MEM_W_TABLE (VEX_W_0F384B_X86_64_L_0) }, > + { EVEX_LEN_TABLE (EVEX_LEN_0F384B) }, > { "vrcp14p%XW", { XM, EXx }, PREFIX_DATA }, > { "vrcp14s%XW", { XMScalar, VexScalar, EXdq }, PREFIX_DATA }, > { "vrsqrt14p%XW", { XM, EXx }, 0 }, > @@ -396,9 +396,9 @@ static const struct dis386 evex_table[][256] = { > { VEX_W_TABLE (EVEX_W_0F3859) }, > { EVEX_LEN_TABLE (EVEX_LEN_0F385A) }, > { EVEX_LEN_TABLE (EVEX_LEN_0F385B) }, > + { PREFIX_TABLE (PREFIX_EVEX_0F385C) }, > { Bad_Opcode }, > - { Bad_Opcode }, > - { Bad_Opcode }, > + { PREFIX_TABLE (PREFIX_EVEX_0F385E) }, > { Bad_Opcode }, > /* 60 */ > { Bad_Opcode }, > @@ -636,7 +636,7 @@ static const struct dis386 evex_table[][256] = { > { Bad_Opcode }, > { Bad_Opcode }, > { Bad_Opcode }, > - { Bad_Opcode }, > + { PREFIX_TABLE (PREFIX_EVEX_0F3A2F) }, > /* 30 */ > { Bad_Opcode }, > { Bad_Opcode }, > @@ -742,9 +742,9 @@ static const struct dis386 evex_table[][256] = { > { Bad_Opcode }, > { Bad_Opcode }, > { Bad_Opcode }, > + { PREFIX_TABLE (PREFIX_EVEX_0F3A8D) }, > { Bad_Opcode }, > - { Bad_Opcode }, > - { Bad_Opcode }, > + { PREFIX_TABLE (PREFIX_EVEX_0F3A8F) }, > /* 90 */ > { Bad_Opcode }, > { Bad_Opcode }, > @@ -1624,7 +1624,7 @@ static const struct dis386 evex_table[][256] = { > { Bad_Opcode }, > { Bad_Opcode }, > { Bad_Opcode }, > - { Bad_Opcode }, > + { PREFIX_TABLE (PREFIX_EVEX_MAP6_95) }, > { "vfmaddsub132p%XH", { XM, Vex, EXxh, EXxEVexR }, PREFIX_DATA }, > { "vfmsubadd132p%XH", { XM, Vex, EXxh, EXxEVexR }, PREFIX_DATA }, > /* 98 */ > diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index > 5643cfe55d5..f39774f2a83 100644 > --- a/opcodes/i386-dis.c > +++ b/opcodes/i386-dis.c > @@ -70,6 +70,7 @@ static bool OP_D (instr_info *, int, int); static bool OP_T > (instr_info *, int, int); static bool OP_MMX (instr_info *, int, int); static bool > OP_XMM (instr_info *, int, int); > +static bool OP_BSR (instr_info *, int, int); > static bool OP_EM (instr_info *, int, int); static bool OP_EX (instr_info *, int, int); > static bool OP_EMC (instr_info *, int,int); @@ -513,6 +514,7 @@ fetch_error > (const instr_info *ins) #define RMBH { OP_REG, bh_reg } #define RMAX > { OP_REG, ax_reg } #define RMDX { OP_REG, dx_reg } > +#define BSR { OP_BSR, bsr } > > #define eAX { OP_IMREG, eAX_reg } > #define AL { OP_IMREG, al_reg } > @@ -566,6 +568,7 @@ fetch_error (const instr_info *ins) #define EXxS { OP_EX, > x_swap_mode } #define EXxmm { OP_EX, xmm_mode } #define EXymm { OP_EX, > ymm_mode } > +#define EXzmm { OP_EX, zmm_mode } > #define EXxmmq { OP_EX, xmmq_mode } > #define EXxmmqh { OP_EX, evex_half_bcst_xmmqh_mode } #define > EXEvexHalfBcstXmmq { OP_EX, evex_half_bcst_xmmq_mode } @@ -583,6 > +586,7 @@ fetch_error (const instr_info *ins) #define Uxmm { OP_R, > xmm_mode } #define Rxmmq { OP_R, xmmq_mode } #define Rymm { OP_R, > ymm_mode } > +#define Rzmm { OP_R, zmm_mode } > #define Rtmm { OP_R, tmm_mode } > #define EMCq { OP_EMC, q_mode } > #define MXC { OP_MXC, 0 } > @@ -600,6 +604,7 @@ fetch_error (const instr_info *ins) #define VexGatherQ > { OP_VEX, vex_vsib_q_w_dq_mode } #define VexGdq { OP_VEX, dq_mode } > #define VexGb { OP_VEX, b_mode } > +#define VexGd { OP_VEX, d_mode } > #define VexGv { OP_VEX, v_mode } > #define VexTmm { OP_VEX, tmm_mode } > #define XMVexI4 { OP_REG_VexI4, x_mode } @@ -720,6 +725,8 @@ enum > ymm_mode, > /* quad word, ymmword or zmmword memory operand. */ > ymmq_mode, > + /* 64-byte ZMM operand */ > + zmm_mode, > /* TMM operand */ > tmm_mode, > /* d_mode in 32bit, q_mode in 64bit mode. */ @@ -821,6 +828,8 @@ enum > rSI_reg, > rDI_reg, > > + bsr, > + > z_mode_ax_reg, > indir_dx_reg > }; > @@ -908,6 +917,7 @@ enum > REG_VEX_0F73, > REG_VEX_0FAE, > REG_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0, > + REG_VEX_0F3849_X86_64_L_0_W_1_M_1_P_3, > REG_VEX_0F38F3_L_0_P_0, > REG_VEX_MAP7_F6_L_0_W_0, > REG_VEX_MAP7_F8_L_0_W_0, > @@ -971,6 +981,7 @@ enum > MOD_0F38F8, > > MOD_VEX_0F3849_X86_64_L_0_W_0, > + MOD_VEX_0F3849_X86_64_L_0_W_1, > > MOD_EVEX_MAP4_60, > MOD_EVEX_MAP4_61, > @@ -995,6 +1006,7 @@ enum > > RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0_R_0, > RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_3, > + RM_VEX_0F3849_X86_64_L_0_W_1_M_1_P_3_R_0, > }; > > enum > @@ -1141,6 +1153,7 @@ enum > PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_0, > PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_1, > PREFIX_VEX_0F384A_X86_64_W_0_L_0, > + PREFIX_VEX_0F3849_X86_64_L_0_W_1_M_1, > PREFIX_VEX_0F384B_X86_64_L_0_W_0, > PREFIX_VEX_0F3850_W_0, > PREFIX_VEX_0F3851_W_0, > @@ -1213,8 +1226,12 @@ enum > PREFIX_EVEX_0F383A, > PREFIX_EVEX_0F3841, > PREFIX_EVEX_0F384A_X86_64_W_0_L_2, > + PREFIX_EVEX_0F384A, > + PREFIX_EVEX_0F384B, > PREFIX_EVEX_0F3852, > PREFIX_EVEX_0F3853, > + PREFIX_EVEX_0F385C, > + PREFIX_EVEX_0F385E, > PREFIX_EVEX_0F3868, > PREFIX_EVEX_0F386D_X86_64_W_0_L_2, > PREFIX_EVEX_0F3872, > @@ -1225,10 +1242,12 @@ enum > PREFIX_EVEX_0F38AB, > > PREFIX_EVEX_0F3A07_X86_64_W_0_L_2, > + PREFIX_EVEX_0F3A07, > PREFIX_EVEX_0F3A08, > PREFIX_EVEX_0F3A0A, > PREFIX_EVEX_0F3A26, > PREFIX_EVEX_0F3A27, > + PREFIX_EVEX_0F3A2F, > PREFIX_EVEX_0F3A42_W_0, > PREFIX_EVEX_0F3A52, > PREFIX_EVEX_0F3A53, > @@ -1237,6 +1256,8 @@ enum > PREFIX_EVEX_0F3A66, > PREFIX_EVEX_0F3A67, > PREFIX_EVEX_0F3A77_X86_64_W_0_L_2, > + PREFIX_EVEX_0F3A8D, > + PREFIX_EVEX_0F3A8F, > PREFIX_EVEX_0F3AC2, > > PREFIX_EVEX_MAP4_4x, > @@ -1310,6 +1331,7 @@ enum > PREFIX_EVEX_MAP6_BA, > PREFIX_EVEX_MAP6_BC, > PREFIX_EVEX_MAP6_BE, > + PREFIX_EVEX_MAP6_95, > PREFIX_EVEX_MAP6_D6, > PREFIX_EVEX_MAP6_D7, > }; > @@ -1601,6 +1623,7 @@ enum > EVEX_LEN_0F381B, > EVEX_LEN_0F3836, > EVEX_LEN_0F384A_X86_64_W_0, > + EVEX_LEN_0F384B, > EVEX_LEN_0F385A, > EVEX_LEN_0F385B, > EVEX_LEN_0F386D_X86_64_W_0, > @@ -1625,6 +1648,7 @@ enum > EVEX_LEN_MAP5_7E, > EVEX_LEN_MAP6_80_W_0, > EVEX_LEN_MAP6_80_W_1, > + EVEX_LEN_MAP6_95_P_0_W_1, > }; > > enum > @@ -1884,6 +1908,9 @@ enum > EVEX_W_MAP5_7E_P_1, > EVEX_W_MAP6_80, > EVEX_W_MAP6_81, > + EVEX_W_MAP6_95_P_0, > + EVEX_W_MAP6_95_P_1, > + EVEX_W_MAP6_95_P_3, > }; > > typedef bool (*op_rtn) (instr_info *ins, int bytemode, int sizeflag); @@ -2709,6 > +2736,10 @@ static const char att_names_tmm[][8] = { > "%tmm4", "%tmm5", "%tmm6", "%tmm7" > }; > > +static const char att_names_bsr[][8] = { > + "%bsr0" > +}; > + > static const char att_names_mask[][8] = { > "%k0", "%k1", "%k2", "%k3", "%k4", "%k5", "%k6", "%k7" > }; > @@ -3095,6 +3126,10 @@ static const struct dis386 reg_table[][8] = { > { > { RM_TABLE (RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0_R_0) }, > }, > + /* REG_VEX_0F3849_X86_64_L_0_W_1_M_1_P_3 */ { > + { RM_TABLE (RM_VEX_0F3849_X86_64_L_0_W_1_M_1_P_3_R_0) }, }, > /* REG_VEX_0F38F3_L_0_P_0 */ > { > { Bad_Opcode }, > @@ -4176,6 +4211,14 @@ static const struct dis386 prefix_table[][4] = { > { "tileloaddrs", { TMM, MVexSIBMEM }, 0 }, > }, > > + /* PREFIX_VEX_0F3849_X86_64_L_0_W_1_M_1 */ { > + { Bad_Opcode }, > + { Bad_Opcode }, > + { Bad_Opcode }, > + { REG_TABLE (REG_VEX_0F3849_X86_64_L_0_W_1_M_1_P_3) }, }, > + > /* PREFIX_VEX_0F384B_X86_64_L_0_W_0 */ > { > { Bad_Opcode }, > @@ -8107,6 +8150,7 @@ static const struct dis386 vex_w_table[][2] = { > { > /* VEX_W_0F3849_X86_64_L_0 */ > { MOD_TABLE (MOD_VEX_0F3849_X86_64_L_0_W_0) }, > + { MOD_TABLE (MOD_VEX_0F3849_X86_64_L_0_W_1) }, > }, > { > /* VEX_W_0F384A_X86_64 */ > @@ -8683,6 +8727,11 @@ static const struct dis386 mod_table[][2] = { > { PREFIX_TABLE (PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_0) }, > { PREFIX_TABLE (PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_1) }, > }, > + { > + /* MOD_VEX_0F3849_X86_64_L_0_W_1 */ > + { Bad_Opcode }, > + { PREFIX_TABLE (PREFIX_VEX_0F3849_X86_64_L_0_W_1_M_1) }, }, > > #include "i386-dis-evex-mod.h" > }; > @@ -8793,6 +8842,10 @@ static const struct dis386 rm_table[][8] = { > /* RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_3 */ > { "tilezero", { TMM, Skip_MODRM }, 0 }, > }, > + { > + /* RM_VEX_0F3849_X86_64_L_0_W_1_M_1_P_3_R_0 */ > + { "bsrinit", { BSR, Skip_MODRM }, 0 }, > + }, > }; > > #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>") > @@ -11920,6 +11973,9 @@ intel_operand_size (instr_info *ins, int bytemode, > int sizeflag) > case ymm_mode: > oappend (ins, "YMMWORD PTR "); > break; > + case zmm_mode: > + oappend (ins, "ZMMWORD PTR "); > + break; > case xmmq_mode: > case evex_half_bcst_xmmqh_mode: > case evex_half_bcst_xmmq_mode: > @@ -12357,6 +12413,9 @@ OP_E_memory (instr_info *ins, int bytemode, int > sizeflag) > else if (bytemode == xmmdw_mode) > shift -= 3; > break; > + case zmm_mode: > + shift = 6; > + break; These lines may decode bsrmovh 0x40(%rax), %bsr0 incorrectly. Please verify the disp8 round-trip and add those tests. > case ymm_mode: > shift = 5; > break; > @@ -13407,6 +13466,8 @@ print_vector_reg (instr_info *ins, unsigned int reg, > int bytemode) > abort (); > } > } > + else if (bytemode == zmm_mode) > + names = att_names_zmm; > else if (bytemode == ymm_mode) > names = att_names_ymm; > else if (bytemode == tmm_mode) > @@ -13482,6 +13543,18 @@ OP_XMM (instr_info *ins, int bytemode, int sizeflag > ATTRIBUTE_UNUSED) > return true; > } > > +static bool > +OP_BSR (instr_info *ins, int bytemode ATTRIBUTE_UNUSED, int sizeflag > +ATTRIBUTE_UNUSED) { > + if (ins->modrm.reg) > + { > + oappend (ins, "(bad)"); > + return false; Should be return true, and can be merged into print_register, no need to define a new function. > + } > + oappend_register (ins, att_names_bsr[0]); > + return true; > +} > + > static bool > OP_EM (instr_info *ins, int bytemode, int sizeflag) { @@ -14252,9 +14325,45 > @@ OP_VEX (instr_info *ins, int bytemode, int sizeflag ATTRIBUTE_UNUSED) > } > break; > case 512: > - names = att_names_zmm; > - ins->evex_used |= EVEX_len_used; > - break; > + switch (bytemode) > + { > + case x_mode: > + case v_mode: > + names = att_names_zmm; > + ins->evex_used |= EVEX_len_used; > + break; > + case dq_mode: > + if (ins->rex & REX_W) > + names = att_names64; > + else if (bytemode == v_mode > + && !(sizeflag & DFLAG)) > + names = att_names16; > + else > + names = att_names32; > + break; > + case b_mode: > + names = att_names8rex; > + break; > + case d_mode: > + names = att_names32; > + break; > + case q_mode: > + names = att_names64; > + break; > + case mask_bd_mode: > + case mask_mode: > + if (reg > 0x7) > + { > + oappend (ins, "(bad)"); > + return true; > + } > + names = att_names_mask; > + break; > + default: > + abort (); > + return true; > + } > + break; > default: > abort (); > break; > diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c index > 11cc4ff19dc..dded2d906e6 100644 > --- a/opcodes/i386-gen.c > +++ b/opcodes/i386-gen.c > @@ -263,6 +263,8 @@ static const dependency isa_dependencies[] = > "RTM|HLE" }, > { "TSXLDTRK", > "RTM" }, > + { "ACE", > + "AVX512F|64" }, > { "AMX_TILE", > "XSAVE|64" }, > { "AMX_INT8", > @@ -470,6 +472,7 @@ static bitfield cpu_flags[] = > BITFIELD (WAITPKG), > BITFIELD (UINTR), > BITFIELD (CLDEMOTE), > + BITFIELD (ACE), > BITFIELD (AMX_INT8), > BITFIELD (AMX_BF16), > BITFIELD (AMX_FP16), > @@ -571,6 +574,7 @@ static const struct { > CLASS (RegSIMD), > CLASS (RegMask), > CLASS (RegBND), > + CLASS (RegBS), > }; > > #undef CLASS > diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h index > 0c5f7747ed2..a8d9ac59c8b 100644 > --- a/opcodes/i386-opc.h > +++ b/opcodes/i386-opc.h > @@ -359,6 +359,8 @@ enum i386_cpu > CpuAVX10_2, > /* Intel AMX-TRANSPOSE Instructions support required. */ > CpuAMX_TRANSPOSE, > + /* ACE instructions support required. */ CpuACE, > /* Not supported in the 64bit mode */ > CpuNo64, > > @@ -397,6 +399,7 @@ enum i386_cpu > cpuapx_f:1, \ > cpuavx10_2:1, \ > cpuamx_transpose:1, \ > + cpuace:1, \ > /* NOTE: This field needs to remain last. */ \ > cpuno64:1 > > @@ -889,6 +892,7 @@ enum operand_class > RegSIMD, /* XMM/YMM/ZMM registers, distinguished by operand size */ > RegMask, /* Vector Mask register */ > RegBND, /* Bound register */ > + RegBS, /* Block scale register */ > }; > > /* Special operand instances. */ > diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl index > 3d3e37b09aa..b85afcf5720 100644 > --- a/opcodes/i386-opc.tbl > +++ b/opcodes/i386-opc.tbl > @@ -62,6 +62,8 @@ > > #define RegBND Class=RegBND > > +#define RegBS Class=RegBS > + > #define Mmword Qword > #define Oword Xmmword > > @@ -118,6 +120,7 @@ > #define SpaceXOP0A OpcodeSpace=SPACE_XOP0A > > #define EVexMap4 OpcodeSpace=SPACE_MAP4|EVex128 > +#define EVexMap6 OpcodeSpace=SPACE_MAP6 You can use Map6 directly. > > #define Map5 OpcodeSpace=SPACE_MAP5 > #define Map6 OpcodeSpace=SPACE_MAP6 > @@ -3234,10 +3237,12 @@ xresldtrk, 0xf20f01e9, TSXLDTRK, NoSuf, {} > > // TSXLDTRK instructions end. > > -// AMX instructions. > +// AMX & ACE instructions. > > ldtilecfg, 0x49/0, APX_F(AMX_TILE), > Modrm|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex } > +ldtilecfg, 0x49/0, ACE, Modrm|Vex128|Space0F38|VexW0|NoSuf, { > +Unspecified|BaseIndex } > sttilecfg, 0x6649/0, APX_F(AMX_TILE), > Modrm|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex } > +sttilecfg, 0x6649/0, ACE, Modrm|Vex128|Space0F38|VexW0|NoSuf, { > +Unspecified|BaseIndex } > > tcmmimfp16ps, 0x666c, AMX_COMPLEX, > Modrm|Vex128|Space0F38|Src2VVVV|VexW0|NoSuf, { RegTMM, RegTMM, > RegTMM } tcmmrlfp16ps, 0x6c, AMX_COMPLEX, > Modrm|Vex128|Space0F38|Src2VVVV|VexW0|NoSuf, { RegTMM, RegTMM, > RegTMM } @@ -3250,14 +3255,18 @@ tdpbusd, 0x665e, AMX_INT8, > Modrm|Vex128|Space0F38|Src2VVVV|VexW0|NoSuf, { RegTMM tdpbsud, > 0xf35e, AMX_INT8, Modrm|Vex128|Space0F38|Src2VVVV|VexW0|NoSuf, > { RegTMM, RegTMM, RegTMM } > > tileloadd, 0xf24b, APX_F(AMX_TILE), > Sibmem|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex, > RegTMM } > +tileloadd, 0xf24b, ACE, Sibmem|Vex128|Space0F38|VexW0|NoSuf, { > +Unspecified|BaseIndex, RegTMM } > tileloaddt1, 0x664b, APX_F(AMX_TILE), > Sibmem|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex, > RegTMM } > +tileloaddt1, 0x664b, ACE, Sibmem|Vex128|Space0F38|VexW0|NoSuf, { > +Unspecified|BaseIndex, RegTMM } > tileloaddrs, 0xf24a, APX_F(AMX_MOVRS), > Sibmem|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex, > RegTMM } tileloaddrst1, 0x664a, APX_F(AMX_MOVRS), > Sibmem|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex, > RegTMM } tilestored, 0xf34b, APX_F(AMX_TILE), > Sibmem|Vex128|EVex128|Space0F38|VexW0|NoSuf, { RegTMM, > Unspecified|BaseIndex } > +tilestored, 0xf34b, ACE, Sibmem|Vex128|Space0F38|VexW0|NoSuf, { RegTMM, > +Unspecified|BaseIndex } > > tilerelease, 0x49c0, AMX_TILE, Vex128|Space0F38|VexW0|NoSuf, {} > +tilerelease, 0x49c0, ACE, Vex128|Space0F38|VexW0|NoSuf, {} > > -tilezero, 0xf249, AMX_TILE, Modrm|Vex128|Space0F38|VexW0|NoSuf, > { RegTMM } > +tilezero, 0xf249, AMX_TILE|ACE, Modrm|Vex128|Space0F38|VexW0|NoSuf, { > +RegTMM } > > <z:pfx, z0:, z1:66> > > @@ -3288,22 +3297,51 @@ tdpbhf8ps, 0xf2fd, AMX_FP8, > Modrm|Vex128|Map5|Src2VVVV|VexW0|NoSuf, { RegTMM, Re tdphbf8ps, > 0xf3fd, AMX_FP8, Modrm|Vex128|Map5|Src2VVVV|VexW0|NoSuf, { RegTMM, > RegTMM, RegTMM } tdphf8ps, 0x66fd, AMX_FP8, > Modrm|Vex128|Map5|Src2VVVV|VexW0|NoSuf, { RegTMM, RegTMM, > RegTMM } > > -tcvtrowd2ps, 0xf34a, AMX_AVX512, > Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, > RegZMM } -tcvtrowd2ps, 0xf307, AMX_AVX512, > Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM } > +tcvtrowd2ps, 0xf34a, AMX_AVX512|ACE, > +Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, > RegZMM } > +tcvtrowd2ps, 0xf307, AMX_AVX512|ACE, > +Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM } > + > +tcvtrowps2bf16h, 0xf26d, AMX_AVX512|ACE, > +Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, > RegZMM } > +tcvtrowps2bf16h, 0xf207, AMX_AVX512|ACE, > +Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM } > +tcvtrowps2bf16l, 0xf36d, AMX_AVX512|ACE, > +Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, > RegZMM } > +tcvtrowps2bf16l, 0xf377, AMX_AVX512|ACE, > +Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM } > +tcvtrowps2phh, 0x6d, AMX_AVX512|ACE, > +Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, > RegZMM } > +tcvtrowps2phh, 0x07, AMX_AVX512|ACE, > +Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM } > +tcvtrowps2phl, 0x666d, AMX_AVX512|ACE, > +Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, > RegZMM } > +tcvtrowps2phl, 0xf277, AMX_AVX512|ACE, > +Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM } > + > +tilemovrow, 0x664a, AMX_AVX512|ACE, > +Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, > RegZMM } > +tilemovrow, 0x6607, AMX_AVX512|ACE, > +Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM } > + > +// AMX & ACE instructions end. > + > +// ACE instructions. > + > +bsrinit, 0xf249, ACE, Modrm|Vex128|Space0F38|VexW1|NoSuf, { RegBS } > +bsrmovf, 0x95, ACE, Modrm|EVex512|EVexMap6|VexW1|Src1VVVV|NoSuf, { > +RegZMM|Unspecified|BaseIndex, RegZMM, RegBS } bsrmovh, 0xf295, ACE, > +Modrm|EVex512|EVexMap6|VexW1|NoSuf, > { RegZMM|Unspecified|BaseIndex, > +RegBS } bsrmovh, 0xf295, ACE, > +RegMem|Modrm|EVex512|EVexMap6|VexW0|NoSuf, { RegBS, RegMem is redundant here: another operand has BaseIndex, which already steers it into the r/m slot. BRs, Lin > +RegZMM|Unspecified|BaseIndex } bsrmovl, 0xf395, ACE, > +Modrm|EVex512|EVexMap6|VexW1|NoSuf, > { RegZMM|Unspecified|BaseIndex, > +RegBS } bsrmovl, 0xf395, ACE, > +RegMem|Modrm|EVex512|EVexMap6|VexW0|NoSuf, { RegBS, > +RegZMM|Unspecified|BaseIndex } > + > +tilemovcol, 0x662f, ACE, Modrm|EVex512|Space0F3A|VexW1|NoSuf, { Imm8, > +RegZMM, RegTMM } tilemovcol, 0x664b, ACE, > +Modrm|EVex512|Space0F38|VexW1|Src2VVVV|NoSuf, { Reg32, RegZMM, > RegTMM } > +tilemovrow, 0x6607, ACE, Modrm|EVex512|Space0F3A|VexW1|NoSuf, { Imm8, > +RegZMM, RegTMM } tilemovrow, 0x664a, ACE, > +Modrm|EVex512|Space0F38|VexW1|Src2VVVV|NoSuf, { Reg32, RegZMM, > RegTMM } > + > +top2bf16ps, 0xf35c, ACE, > Modrm|EVex512|Space0F38|VexW0|Src2VVVV|NoSuf, > +{ RegZMM, RegZMM, RegTMM } > > -tcvtrowps2bf16h, 0xf26d, AMX_AVX512, > Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, > RegZMM } -tcvtrowps2bf16h, 0xf207, AMX_AVX512, > Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM } - > tcvtrowps2bf16l, 0xf36d, AMX_AVX512, > Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, > RegZMM } -tcvtrowps2bf16l, 0xf377, AMX_AVX512, > Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM } - > tcvtrowps2phh, 0x6d, AMX_AVX512, > Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, > RegZMM } -tcvtrowps2phh, 0x07, AMX_AVX512, > Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM } - > tcvtrowps2phl, 0x666d, AMX_AVX512, > Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, > RegZMM } -tcvtrowps2phl, 0xf277, AMX_AVX512, > Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM } > +top4bssd, 0xf25e, ACE, Modrm|EVex512|Space0F38|VexW0|Src2VVVV|NoSuf, > { > +RegZMM, RegZMM, RegTMM } top4bsud, 0xf35e, ACE, > +Modrm|EVex512|Space0F38|VexW0|Src2VVVV|NoSuf, { RegZMM, RegZMM, > RegTMM > +} top4busd, 0x665e, ACE, > Modrm|EVex512|Space0F38|VexW0|Src2VVVV|NoSuf, > +{ RegZMM, RegZMM, RegTMM } top4buud, 0x5e, ACE, > +Modrm|EVex512|Space0F38|VexW0|Src2VVVV|NoSuf, { RegZMM, RegZMM, > RegTMM > +} > > -tilemovrow, 0x664a, AMX_AVX512, > Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, > RegZMM } -tilemovrow, 0x6607, AMX_AVX512, > Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM } > +top4mxbf8ps, 0x8d, ACE, > Modrm|EVex512|Space0F3A|VexW0|Src2VVVV|NoSuf, { > +Imm8, RegZMM, RegZMM, RegTMM } top4mxbhf8ps, 0xf28d, ACE, > +Modrm|EVex512|Space0F3A|VexW0|Src2VVVV|NoSuf, { Imm8, RegZMM, > RegZMM, > +RegTMM } top4mxhbf8ps, 0xf38d, ACE, > +Modrm|EVex512|Space0F3A|VexW0|Src2VVVV|NoSuf, { Imm8, RegZMM, > RegZMM, > +RegTMM } top4mxhf8ps, 0x668d, ACE, > +Modrm|EVex512|Space0F3A|VexW0|Src2VVVV|NoSuf, { Imm8, RegZMM, > RegZMM, > +RegTMM } top4mxbssps, 0xf28f, ACE, > +Modrm|EVex512|Space0F3A|VexW0|Src2VVVV|NoSuf, { Imm8, RegZMM, > RegZMM, > +RegTMM } > > -// AMX instructions end. > +// ACE instructions end. > > // KEYLOCKER instructions. > > diff --git a/opcodes/i386-reg.tbl b/opcodes/i386-reg.tbl index > 74234c503d6..ee6923252c9 100644 > --- a/opcodes/i386-reg.tbl > +++ b/opcodes/i386-reg.tbl > @@ -344,7 +344,7 @@ zmm28, Class=RegSIMD|Zmmword, RegVRex|RegRex, 4, > Dw2Inval, 79 zmm29, Class=RegSIMD|Zmmword, RegVRex|RegRex, 5, Dw2Inval, > 80 zmm30, Class=RegSIMD|Zmmword, RegVRex|RegRex, 6, Dw2Inval, 81 > zmm31, Class=RegSIMD|Zmmword, RegVRex|RegRex, 7, Dw2Inval, 82 -// TMM > registers for AMX > +// TMM registers for AMX/ACE > tmm0, Class=RegSIMD|Tmmword, 0, 0, Dw2Inval, Dw2Inval tmm1, > Class=RegSIMD|Tmmword, 0, 1, Dw2Inval, Dw2Inval tmm2, > Class=RegSIMD|Tmmword, 0, 2, Dw2Inval, Dw2Inval @@ -353,6 +353,8 @@ > tmm4, Class=RegSIMD|Tmmword, 0, 4, Dw2Inval, Dw2Inval tmm5, > Class=RegSIMD|Tmmword, 0, 5, Dw2Inval, Dw2Inval tmm6, > Class=RegSIMD|Tmmword, 0, 6, Dw2Inval, Dw2Inval tmm7, > Class=RegSIMD|Tmmword, 0, 7, Dw2Inval, Dw2Inval > +// Block scale register for ACE > +bsr0, Class=RegBS, 0, 0, Dw2Inval, Dw2Inval > // Bound registers for MPX > bnd0, Class=RegBND, 0, 0, Dw2Inval, 126 bnd1, Class=RegBND, 0, 1, Dw2Inval, > 127 > -- > 2.53.0