[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