[PATCH v1 2/2] Support x86 ACE ISA

Ganesh Gopalasubramanian Ganesh.Gopalasubramanian@amd.com
Sat Jun 27 11:53:38 GMT 2026


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)
 	   || 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;
 	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;
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
 
 #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.
 
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



More information about the Binutils mailing list