[v1,2/2] Support x86 ACE ISA
Commit Message
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
Comments
> -----Original Message-----
> From: Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com>
> Sent: Saturday, June 27, 2026 7:56 PM
> To: binutils@sourceware.org
> Cc: Jiang, Haochen <haochen.jiang@intel.com>; Beulich, Jan
> <JBeulich@suse.com>; Ganesh Gopalasubramanian
> <Ganesh.Gopalasubramanian@amd.com>
> 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
On 30.06.2026 05:17, Hu, Lin1 wrote:
>> -----Original Message-----
>> From: Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com>
>> Sent: Saturday, June 27, 2026 7:56 PM
>>
>> @@ -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.
"invalid" as in "unnecessary"? Else please explain.
Also, as a general remark: Please trim reply context, especially when what
you reply to was large.
Jan
> From: Jan Beulich <jbeulich@suse.com>
> Sent: Tuesday, June 30, 2026 1:59 PM
> On 30.06.2026 05:17, Hu, Lin1 wrote:
> >> -----Original Message-----
> >> From: Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com>
> >> Sent: Saturday, June 27, 2026 7:56 PM
> >>
> >> @@ -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.
>
> "invalid" as in "unnecessary"? Else please explain.
>
> Also, as a general remark: Please trim reply context, especially when what you
> reply to was large.
>
Yes, it's unnecessary. ACE instructions don't set vex and evex at the same time.
BRs,
Lin
@@ -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.
@@ -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)
|| 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;
@@ -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}
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
@@ -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*"]
@@ -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 },
+ },
};
@@ -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 },
@@ -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 },
+ },
@@ -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 */
@@ -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;
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;
+ }
+ 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;
@@ -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
@@ -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. */
@@ -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
#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, 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.
@@ -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