[PATCH v4 7/7] x86: add ACE V1 tile outer product instructions

Rohan Shenoy RohanRadhesh.Shenoy@amd.com
Tue Sep 29 18:30:15 GMT 2026


Add assembler and disassembler support for TOP2BF16PS, TOP4B*, and TOP4MX*.

Reference: AI Compute Extensions (ACE) Specification, v1.16.2
https://x86ecosystem.org/wp-content/uploads/2026/06/ACE_v1_Specification_public.pdf

Co-authored-by: Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com>
Co-authored-by: Umesh Kalvakuntla <Umesh.Kalvakuntla@amd.com>
---
 gas/NEWS                               |  2 ++
 gas/testsuite/gas/i386/x86-64-ace_v1.d | 10 +++++++++
 gas/testsuite/gas/i386/x86-64-ace_v1.s | 14 +++++++++++++
 opcodes/i386-dis-evex-len.h            | 28 ++++++++++++++++++++++++++
 opcodes/i386-dis-evex-prefix.h         | 26 ++++++++++++++++++++++++
 opcodes/i386-dis-evex-w.h              | 16 +++++++++++++++
 opcodes/i386-dis-evex-x86-64.h         | 20 ++++++++++++++++++
 opcodes/i386-dis-evex.h                |  8 ++++----
 opcodes/i386-dis.c                     | 16 +++++++++++++++
 opcodes/i386-opc.tbl                   | 16 +++++++++++++--
 10 files changed, 150 insertions(+), 6 deletions(-)

diff --git a/gas/NEWS b/gas/NEWS
index e7f9aebd256..6b625b1345e 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,7 @@
 -*- text -*-
 
+* Add support for the x86 ACE V1 instructions.
+
 * Support for .previous, .pushsection and .popsection for COFF targets.
   The semantics are the same as for ELF targets. This allows one to
   compile the Linux kernel as a Windows/ReactOS driver.
diff --git a/gas/testsuite/gas/i386/x86-64-ace_v1.d b/gas/testsuite/gas/i386/x86-64-ace_v1.d
index 030a5dd4425..bacffa04974 100644
--- a/gas/testsuite/gas/i386/x86-64-ace_v1.d
+++ b/gas/testsuite/gas/i386/x86-64-ace_v1.d
@@ -39,3 +39,13 @@ Disassembly of section \.text:
 [ 	]*[a-f0-9]+:[ 	]*c4 e2 fb 49 c0[ 	]+bsrinit %bsr0
 [ 	]*[a-f0-9]+:[ 	]*62 f6 f4 48 95 c3[ 	]+bsrmovf %zmm3,%zmm1,%bsr0
 [ 	]*[a-f0-9]+:[ 	]*62 f6 f4 48 95 41 7f[ 	]+bsrmovf 0x1fc0\(%rcx\),%zmm1,%bsr0
+[ 	]*[a-f0-9]+:[ 	]*62 f3 6c 48 8d c9 00[ 	]+top4mxbf8ps \$0x0,%zmm2,%zmm1,%tmm1
+[ 	]*[a-f0-9]+:[ 	]*62 f3 6f 48 8d c9 00[ 	]+top4mxbhf8ps \$0x0,%zmm2,%zmm1,%tmm1
+[ 	]*[a-f0-9]+:[ 	]*62 f3 6e 48 8d c9 00[ 	]+top4mxhbf8ps \$0x0,%zmm2,%zmm1,%tmm1
+[ 	]*[a-f0-9]+:[ 	]*62 f3 6d 48 8d c9 00[ 	]+top4mxhf8ps \$0x0,%zmm2,%zmm1,%tmm1
+[ 	]*[a-f0-9]+:[ 	]*62 f3 6f 48 8f c9 00[ 	]+top4mxbssps \$0x0,%zmm2,%zmm1,%tmm1
+[ 	]*[a-f0-9]+:[ 	]*62 f2 6e 48 5c c1[ 	]+top2bf16ps %zmm2,%zmm1,%tmm0
+[ 	]*[a-f0-9]+:[ 	]*62 f2 6f 48 5e c1[ 	]+top4bssd %zmm2,%zmm1,%tmm0
+[ 	]*[a-f0-9]+:[ 	]*62 f2 6e 48 5e c1[ 	]+top4bsud %zmm2,%zmm1,%tmm0
+[ 	]*[a-f0-9]+:[ 	]*62 f2 6d 48 5e c1[ 	]+top4busd %zmm2,%zmm1,%tmm0
+[ 	]*[a-f0-9]+:[ 	]*62 f2 6c 48 5e c1[ 	]+top4buud %zmm2,%zmm1,%tmm0
diff --git a/gas/testsuite/gas/i386/x86-64-ace_v1.s b/gas/testsuite/gas/i386/x86-64-ace_v1.s
index 76bf8b5b927..e2cc80ab689 100644
--- a/gas/testsuite/gas/i386/x86-64-ace_v1.s
+++ b/gas/testsuite/gas/i386/x86-64-ace_v1.s
@@ -34,3 +34,17 @@ start:
 	bsrinit %bsr0
 	bsrmovf %zmm3, %zmm1, %bsr0
 	bsrmovf 8128(%rcx), %zmm1, %bsr0
+
+	top4mxbf8ps  $0, %zmm2, %zmm1, %tmm1
+	top4mxbhf8ps $0, %zmm2, %zmm1, %tmm1
+	top4mxhbf8ps $0, %zmm2, %zmm1, %tmm1
+	top4mxhf8ps  $0, %zmm2, %zmm1, %tmm1
+
+	top4mxbssps $0, %zmm2, %zmm1, %tmm1
+
+	top2bf16ps %zmm2, %zmm1, %tmm0
+
+	top4bssd   %zmm2, %zmm1, %tmm0
+	top4bsud   %zmm2, %zmm1, %tmm0
+	top4busd   %zmm2, %zmm1, %tmm0
+	top4buud   %zmm2, %zmm1, %tmm0
diff --git a/opcodes/i386-dis-evex-len.h b/opcodes/i386-dis-evex-len.h
index 7adc8c2081e..6c801e1ed3e 100644
--- a/opcodes/i386-dis-evex-len.h
+++ b/opcodes/i386-dis-evex-len.h
@@ -79,6 +79,20 @@ static const struct dis386 evex_len_table[][3] = {
     { VEX_W_TABLE (EVEX_W_0F385B_L_2) },
   },
 
+  /* EVEX_LEN_0F385C_X86_64_W_0 */
+  {
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { PREFIX_TABLE (PREFIX_EVEX_0F385C_X86_64_W_0_L_2) },
+  },
+
+  /* EVEX_LEN_0F385E_X86_64_W_0 */
+  {
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { PREFIX_TABLE (PREFIX_EVEX_0F385E_X86_64_W_0_L_2) },
+  },
+
   /* EVEX_LEN_0F386D_X86_64_W_0_M_1 */
   {
     { Bad_Opcode },
@@ -212,6 +226,20 @@ static const struct dis386 evex_len_table[][3] = {
     { PREFIX_TABLE (PREFIX_EVEX_0F3A77_X86_64_W_0_L_2) },
   },
 
+  /* EVEX_LEN_0F3A8D_X86_64_W_0 */
+  {
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { PREFIX_TABLE (PREFIX_EVEX_0F3A8D_X86_64_W_0_L_2) },
+  },
+
+  /* EVEX_LEN_0F3A8F_X86_64_W_0 */
+  {
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { PREFIX_TABLE (PREFIX_EVEX_0F3A8F_X86_64_W_0_L_2) },
+  },
+
   /* EVEX_LEN_MAP5_6E */
   {
     { PREFIX_TABLE (PREFIX_EVEX_MAP5_6E_L_0) },
diff --git a/opcodes/i386-dis-evex-prefix.h b/opcodes/i386-dis-evex-prefix.h
index 9a1e2ba984f..90e0b2ffce2 100644
--- a/opcodes/i386-dis-evex-prefix.h
+++ b/opcodes/i386-dis-evex-prefix.h
@@ -280,6 +280,18 @@
     { VEX_W_TABLE (VEX_W_0F3853) },
     { "vp4dpws%XSds",	{ XM, Vex, Mxmm }, 0 },
   },
+  /* PREFIX_EVEX_0F385C_X86_64_W_0_L_2 */
+  {
+    { Bad_Opcode },
+    { "top2bf16ps",	{ TMM, Ux, Vex }, 0 },
+  },
+  /* PREFIX_EVEX_0F385E_X86_64_W_0_L_2 */
+  {
+    { "top4buud",	{ TMM, Ux, Vex }, 0 },
+    { "top4bsud",	{ TMM, Ux, Vex }, 0 },
+    { "top4busd",	{ TMM, Ux, Vex }, 0 },
+    { "top4bssd",	{ TMM, Ux, Vex }, 0 },
+  },
   /* PREFIX_EVEX_0F3868 */
   {
     { Bad_Opcode },
@@ -433,6 +445,20 @@
     { Bad_Opcode },
     { "tcvtrowps2phl",	{ XM, Rtmm, Ib }, 0 },
   },
+  /* PREFIX_EVEX_0F3A8D_X86_64_W_0_L_2 */
+  {
+    { "top4mxbf8ps",	{ TMM, Ux, Vex, Ib }, 0 },
+    { "top4mxhbf8ps",	{ TMM, Ux, Vex, Ib }, 0 },
+    { "top4mxhf8ps",	{ TMM, Ux, Vex, Ib }, 0 },
+    { "top4mxbhf8ps",	{ TMM, Ux, Vex, Ib }, 0 },
+  },
+  /* PREFIX_EVEX_0F3A8F_X86_64_W_0_L_2 */
+  {
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { "top4mxbssps",	{ TMM, Ux, Vex, Ib }, 0 },
+  },
   /* PREFIX_EVEX_0F3AC2 */
   {
     { "vcmpp%XH", { MaskG, Vex, EXxh, EXxEVexS, CMP }, 0 },
diff --git a/opcodes/i386-dis-evex-w.h b/opcodes/i386-dis-evex-w.h
index 589745fb628..deea024ef0e 100644
--- a/opcodes/i386-dis-evex-w.h
+++ b/opcodes/i386-dis-evex-w.h
@@ -375,6 +375,14 @@
     { "vbroadcasti32x8",	{ XM, Mymm }, PREFIX_DATA },
     { "vbroadcasti64x4",	{ XM, Mymm }, PREFIX_DATA },
   },
+  /* EVEX_W_0F385C_X86_64 */
+  {
+    { EVEX_LEN_TABLE (EVEX_LEN_0F385C_X86_64_W_0) },
+  },
+  /* EVEX_W_0F385E_X86_64 */
+  {
+    { EVEX_LEN_TABLE (EVEX_LEN_0F385E_X86_64_W_0) },
+  },
   /* EVEX_W_0F386D_X86_64 */
   {
     { EVEX_LEN_TABLE (EVEX_LEN_0F386D_X86_64_W_0) },
@@ -488,6 +496,14 @@
   {
     { EVEX_LEN_TABLE (EVEX_LEN_0F3A77_X86_64_W_0) },
   },
+  /* EVEX_W_0F3A8D_X86_64 */
+  {
+    { EVEX_LEN_TABLE (EVEX_LEN_0F3A8D_X86_64_W_0) },
+  },
+  /* EVEX_W_0F3A8F_X86_64 */
+  {
+    { EVEX_LEN_TABLE (EVEX_LEN_0F3A8F_X86_64_W_0) },
+  },
   /* EVEX_W_MAP4_8F_R_0 */
   {
     { "pop2", { { PUSH2_POP2_Fixup, q_mode}, Eq }, NO_PREFIX },
diff --git a/opcodes/i386-dis-evex-x86-64.h b/opcodes/i386-dis-evex-x86-64.h
index 79b2ed618c5..d51db1b2ec7 100644
--- a/opcodes/i386-dis-evex-x86-64.h
+++ b/opcodes/i386-dis-evex-x86-64.h
@@ -8,6 +8,16 @@
     { Bad_Opcode },
     { EVEX_LEN_TABLE (EVEX_LEN_0F384B_X86_64) },
   },
+  /* X86_64_EVEX_0F385C */
+  {
+    { Bad_Opcode },
+    { VEX_W_TABLE (EVEX_W_0F385C_X86_64) },
+  },
+  /* X86_64_EVEX_0F385E */
+  {
+    { Bad_Opcode },
+    { VEX_W_TABLE (EVEX_W_0F385E_X86_64) },
+  },
   /* X86_64_EVEX_0F386D */
   {
     { Bad_Opcode },
@@ -28,6 +38,16 @@
     { Bad_Opcode },
     { VEX_W_TABLE (EVEX_W_0F3A77_X86_64) },
   },
+  /* X86_64_EVEX_0F3A8D */
+  {
+    { Bad_Opcode },
+    { VEX_W_TABLE (EVEX_W_0F3A8D_X86_64) },
+  },
+  /* X86_64_EVEX_0F3A8F */
+  {
+    { Bad_Opcode },
+    { VEX_W_TABLE (EVEX_W_0F3A8F_X86_64) },
+  },
   /* X86_64_EVEX_MAP5_6F */
   {
     { Bad_Opcode },
diff --git a/opcodes/i386-dis-evex.h b/opcodes/i386-dis-evex.h
index 9e92abba55c..00a6fdc9460 100644
--- a/opcodes/i386-dis-evex.h
+++ b/opcodes/i386-dis-evex.h
@@ -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) },
+    { X86_64_TABLE (X86_64_EVEX_0F385C) },
     { Bad_Opcode },
-    { Bad_Opcode },
-    { Bad_Opcode },
+    { X86_64_TABLE (X86_64_EVEX_0F385E) },
     { Bad_Opcode },
     /* 60 */
     { Bad_Opcode },
@@ -742,9 +742,9 @@ static const struct dis386 evex_table[][256] = {
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
+    { X86_64_TABLE (X86_64_EVEX_0F3A8D) },
     { Bad_Opcode },
-    { Bad_Opcode },
-    { Bad_Opcode },
+    { X86_64_TABLE (X86_64_EVEX_0F3A8F) },
     /* 90 */
     { Bad_Opcode },
     { Bad_Opcode },
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index fdd165f2e05..43743679bbd 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -1225,6 +1225,8 @@ enum
   PREFIX_EVEX_0F384B_X86_64_W_1_L_2,
   PREFIX_EVEX_0F3852,
   PREFIX_EVEX_0F3853,
+  PREFIX_EVEX_0F385C_X86_64_W_0_L_2,
+  PREFIX_EVEX_0F385E_X86_64_W_0_L_2,
   PREFIX_EVEX_0F3868,
   PREFIX_EVEX_0F386D_X86_64_W_0_L_2,
   PREFIX_EVEX_0F3872,
@@ -1249,6 +1251,8 @@ enum
   PREFIX_EVEX_0F3A66,
   PREFIX_EVEX_0F3A67,
   PREFIX_EVEX_0F3A77_X86_64_W_0_L_2,
+  PREFIX_EVEX_0F3A8D_X86_64_W_0_L_2,
+  PREFIX_EVEX_0F3A8F_X86_64_W_0_L_2,
   PREFIX_EVEX_0F3AC2,
 
   PREFIX_EVEX_MAP4_4x,
@@ -1418,10 +1422,14 @@ enum
 
   X86_64_EVEX_0F384A,
   X86_64_EVEX_0F384B,
+  X86_64_EVEX_0F385C,
+  X86_64_EVEX_0F385E,
   X86_64_EVEX_0F386D,
   X86_64_EVEX_0F3A07,
   X86_64_EVEX_0F3A2F,
   X86_64_EVEX_0F3A77,
+  X86_64_EVEX_0F3A8D,
+  X86_64_EVEX_0F3A8F,
 
   X86_64_EVEX_MAP5_6F,
   X86_64_EVEX_MAP6_95,
@@ -1624,6 +1632,8 @@ enum
   EVEX_LEN_0F384B_X86_64,
   EVEX_LEN_0F385A,
   EVEX_LEN_0F385B,
+  EVEX_LEN_0F385C_X86_64_W_0,
+  EVEX_LEN_0F385E_X86_64_W_0,
   EVEX_LEN_0F386D_X86_64_W_0,
   EVEX_LEN_0F38C6,
   EVEX_LEN_0F38C7,
@@ -1643,6 +1653,8 @@ enum
   EVEX_LEN_0F3A3B,
   EVEX_LEN_0F3A43,
   EVEX_LEN_0F3A77_X86_64_W_0,
+  EVEX_LEN_0F3A8D_X86_64_W_0,
+  EVEX_LEN_0F3A8F_X86_64_W_0,
 
   EVEX_LEN_MAP5_6E,
   EVEX_LEN_MAP5_7E,
@@ -1868,6 +1880,8 @@ enum
   EVEX_W_0F3859,
   EVEX_W_0F385A_L_n,
   EVEX_W_0F385B_L_2,
+  EVEX_W_0F385C_X86_64,
+  EVEX_W_0F385E_X86_64,
   EVEX_W_0F386D_X86_64,
   EVEX_W_0F3870,
   EVEX_W_0F3872_P_2,
@@ -1893,6 +1907,8 @@ enum
   EVEX_W_0F3A70,
   EVEX_W_0F3A72,
   EVEX_W_0F3A77_X86_64,
+  EVEX_W_0F3A8D_X86_64,
+  EVEX_W_0F3A8F_X86_64,
 
   EVEX_W_MAP4_8F_R_0,
   EVEX_W_MAP4_F8_P1_M_1,
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
index 7eeb5219d04..3e6cb546343 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -3279,8 +3279,6 @@ tdpfp16ps, 0xf25c, AMX_FP16, Modrm|Vex128|Space0F38|Src2VVVV|VexW0|NoSuf, { RegT
 
 tdpb<tdpb>d, 0x<tdpb:pfx>5e, AMX_INT8, Modrm|Vex128|Space0F38|Src2VVVV|VexW0|NoSuf, { RegTMM, RegTMM, RegTMM }
 
-<tdpb>
-
 tileloadd, 0xf24b, APX_F(AMX_TILE), Sibmem|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex, RegTMM }
 tileloaddt1, 0x664b, APX_F(AMX_TILE), Sibmem|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex, RegTMM }
 tileloaddrs, 0xf24a, APX_F(AMX_MOVRS), Sibmem|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex, RegTMM }
@@ -3330,6 +3328,20 @@ tilemovcol, 0x664b, ACE_V1, Modrm|EVex512|Space0F38|VexW1|Src2VVVV|NoSuf, { Reg3
 tilemovrow, 0x6607, ACE_V1, Modrm|EVex512|Space0F3A|VexW1|NoSuf, { Imm8, RegZMM, RegTMM }
 tilemovrow, 0x664a, ACE_V1, Modrm|EVex512|Space0F38|VexW1|Src2VVVV|NoSuf, { Reg32, RegZMM, RegTMM }
 
+top2bf16ps, 0xf35c, ACE_V1, Modrm|EVex512|Space0F38|VexW0|Src2VVVV|NoSuf, { RegZMM, RegZMM, RegTMM }
+
+top4b<tdpb>d, 0x<tdpb:pfx>5e, ACE_V1, Modrm|EVex512|Space0F38|VexW0|Src2VVVV|NoSuf, { RegZMM, RegZMM, RegTMM }
+
+<tdpb>
+
+<top4mx8:pfx, bf:, hf:66, bhf:f2, hbf:f3>
+
+top4mx<top4mx8>8ps, 0x<top4mx8:pfx>8d, ACE_V1, Modrm|EVex512|Space0F3A|VexW0|Src2VVVV|NoSuf, { Imm8, RegZMM, RegZMM, RegTMM }
+
+<top4mx8>
+
+top4mxbssps, 0xf28f, ACE_V1, Modrm|EVex512|Space0F3A|VexW0|Src2VVVV|NoSuf, { Imm8, RegZMM, RegZMM, RegTMM }
+
 // ACE instructions end.
 
 // KEYLOCKER instructions.
-- 
2.34.1



More information about the Binutils mailing list