[PATCH v4 4/7] x86: ACE V1 support for AMX-shared instructions

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


Enable ACE V1 architecture, and reuse the pre-existing AMX-shared
instructions for tile management, row moves, and row converts under
ACE_V1, also allowing TMM register usage.

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/config/tc-i386.c                       |  8 +++-
 gas/doc/c-i386.texi                        |  3 +-
 gas/testsuite/gas/i386/x86-64-ace_v1.d     | 26 +++++++++++++
 gas/testsuite/gas/i386/x86-64-ace_v1.s     | 22 +++++++++++
 gas/testsuite/gas/i386/x86-64-noamx-tile.l |  2 +-
 gas/testsuite/gas/i386/x86-64-noamx-tile.s |  1 +
 gas/testsuite/gas/i386/x86-64.exp          |  1 +
 opcodes/i386-gen.c                         |  3 ++
 opcodes/i386-opc.h                         |  3 ++
 opcodes/i386-opc.tbl                       | 44 ++++++++++++----------
 opcodes/i386-reg.tbl                       |  2 +-
 11 files changed, 90 insertions(+), 25 deletions(-)
 create mode 100644 gas/testsuite/gas/i386/x86-64-ace_v1.d
 create mode 100644 gas/testsuite/gas/i386/x86-64-ace_v1.s

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 4c8acb0df5b..de99474e847 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -1207,6 +1207,7 @@ static const arch_entry cpu_arch[] =
   SUBARCH (pconfig, PCONFIG, PCONFIG, false),
   SUBARCH (waitpkg, WAITPKG, WAITPKG, false),
   SUBARCH (cldemote, CLDEMOTE, CLDEMOTE, false),
+  SUBARCH (ace_v1, ACE_V1, ANY_ACE_V1, 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),
@@ -1907,6 +1908,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_V1:   return a->bitfield.cpuace_v1;
     case Cpu64:       return a->bitfield.cpu64;
     case CpuNo64:     return a->bitfield.cpuno64;
     default:
@@ -3353,8 +3355,10 @@ static void isa_disable (unsigned int idx)
   cpu_arch_isa_flags
     = cpu_flags_and_not (cpu_arch_isa_flags, cpu_arch[idx].disable);
 
-  /* TILE is internal. .noamx_tile does not automatically clear it.  */
-  if (!cpu_arch_flags.bitfield.cpuamx_tile)
+  /* TILE is internal. .noamx_tile and .noace_v1 do not automatically clear
+     it.  */
+  if (!cpu_arch_flags.bitfield.cpuamx_tile
+      && !cpu_arch_flags.bitfield.cpuace_v1)
     {
       cpu_arch_flags.bitfield.cputile = 0;
       cpu_arch_isa_flags.bitfield.cputile = 0;
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
index 3ce70810d4e..f0aec60fda8 100644
--- a/gas/doc/c-i386.texi
+++ b/gas/doc/c-i386.texi
@@ -245,6 +245,7 @@ accept various extension mnemonics.  For example,
 @code{amx_movrs},
 @code{amx_avx512},
 @code{amx_tile},
+@code{ace_v1},
 @code{vmx},
 @code{vmfunc},
 @code{smx},
@@ -1737,7 +1738,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_v1}
 @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_v1.d b/gas/testsuite/gas/i386/x86-64-ace_v1.d
new file mode 100644
index 00000000000..df5290c55a9
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-ace_v1.d
@@ -0,0 +1,26 @@
+#as: -march=generic64+ace_v1
+#objdump: -dw
+#name: 64-bit ACE v1 insns
+#source: x86-64-ace_v1.s
+
+.*: +file format .*
+
+Disassembly of section \.text:
+
+[0-9a-f]+ <start>:
+[ 	]*[a-f0-9]+:[ 	]*c4 e2 7b 49 c0[ 	]+tilezero %tmm0
+[ 	]*[a-f0-9]+:[ 	]*c4 e2 78 49 01[ 	]+ldtilecfg \(%rcx\)
+[ 	]*[a-f0-9]+:[ 	]*c4 e2 79 49 01[ 	]+sttilecfg \(%rcx\)
+[ 	]*[a-f0-9]+:[ 	]*c4 e2 78 49 c0[ 	]+tilerelease
+[ 	]*[a-f0-9]+:[ 	]*62 f2 65 48 4a ca[ 	]+tilemovrow %ebx,%tmm2,%zmm1
+[ 	]*[a-f0-9]+:[ 	]*62 f3 7d 48 07 ca 08[ 	]+tilemovrow \$0x8,%tmm2,%zmm1
+[ 	]*[a-f0-9]+:[ 	]*62 62 6e 48 4a f5[ 	]+tcvtrowd2ps %edx,%tmm5,%zmm30
+[ 	]*[a-f0-9]+:[ 	]*62 63 7e 48 07 f5 08[ 	]+tcvtrowd2ps \$0x8,%tmm5,%zmm30
+[ 	]*[a-f0-9]+:[ 	]*62 62 6f 48 6d f5[ 	]+tcvtrowps2bf16h %edx,%tmm5,%zmm30
+[ 	]*[a-f0-9]+:[ 	]*62 63 7f 48 07 f5 08[ 	]+tcvtrowps2bf16h \$0x8,%tmm5,%zmm30
+[ 	]*[a-f0-9]+:[ 	]*62 62 6c 48 6d f5[ 	]+tcvtrowps2phh %edx,%tmm5,%zmm30
+[ 	]*[a-f0-9]+:[ 	]*62 63 7c 48 07 f5 08[ 	]+tcvtrowps2phh \$0x8,%tmm5,%zmm30
+[ 	]*[a-f0-9]+:[ 	]*62 62 6e 48 6d f5[ 	]+tcvtrowps2bf16l %edx,%tmm5,%zmm30
+[ 	]*[a-f0-9]+:[ 	]*62 63 7e 48 77 f5 08[ 	]+tcvtrowps2bf16l \$0x8,%tmm5,%zmm30
+[ 	]*[a-f0-9]+:[ 	]*62 62 6d 48 6d f5[ 	]+tcvtrowps2phl %edx,%tmm5,%zmm30
+[ 	]*[a-f0-9]+:[ 	]*62 63 7f 48 77 f5 08[ 	]+tcvtrowps2phl \$0x8,%tmm5,%zmm30
diff --git a/gas/testsuite/gas/i386/x86-64-ace_v1.s b/gas/testsuite/gas/i386/x86-64-ace_v1.s
new file mode 100644
index 00000000000..5bec9cf9e89
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-ace_v1.s
@@ -0,0 +1,22 @@
+# Check 64-bit ACE V1 instructions
+
+	.text
+start:
+	tilezero %tmm0
+	ldtilecfg (%rcx)
+	sttilecfg (%rcx)
+	tilerelease
+
+	tilemovrow %ebx, %tmm2, %zmm1
+	tilemovrow $8, %tmm2, %zmm1
+
+	tcvtrowd2ps     %edx, %tmm5, %zmm30
+	tcvtrowd2ps     $8, %tmm5, %zmm30
+
+	.irp p, h, l
+	tcvtrowps2bf16\p %edx, %tmm5, %zmm30
+	tcvtrowps2bf16\p $8, %tmm5, %zmm30
+
+	tcvtrowps2ph\p   %edx, %tmm5, %zmm30
+	tcvtrowps2ph\p   $8, %tmm5, %zmm30
+	.endr
diff --git a/gas/testsuite/gas/i386/x86-64-noamx-tile.l b/gas/testsuite/gas/i386/x86-64-noamx-tile.l
index 93a3f4b04e5..0b6217622e0 100644
--- a/gas/testsuite/gas/i386/x86-64-noamx-tile.l
+++ b/gas/testsuite/gas/i386/x86-64-noamx-tile.l
@@ -1,2 +1,2 @@
 .*: Assembler messages:
-.*:3: Error: `ldtilecfg' is not supported on `.*\.noamx_tile'
+.*:4: Error: `ldtilecfg' is not supported on `.*\.noamx_tile\.noace_v1'
diff --git a/gas/testsuite/gas/i386/x86-64-noamx-tile.s b/gas/testsuite/gas/i386/x86-64-noamx-tile.s
index 398c07a2eee..5a12b4c277f 100644
--- a/gas/testsuite/gas/i386/x86-64-noamx-tile.s
+++ b/gas/testsuite/gas/i386/x86-64-noamx-tile.s
@@ -1,3 +1,4 @@
 	.text
 	.arch .noamx_tile
+	.arch .noace_v1
 	ldtilecfg (%rax)
diff --git a/gas/testsuite/gas/i386/x86-64.exp b/gas/testsuite/gas/i386/x86-64.exp
index 9e7ac49abd2..968c8ff6950 100644
--- a/gas/testsuite/gas/i386/x86-64.exp
+++ b/gas/testsuite/gas/i386/x86-64.exp
@@ -692,6 +692,7 @@ run_list_test "x86-64-noamx-tile"
 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_v1"
 
 if { ![istarget "*-*-aix*"]
      && ![istarget "*-*-*bsd*"]
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index 15ba45edd70..308f8284909 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -271,6 +271,8 @@ static const dependency isa_dependencies[] =
     "RTM" },
   { "TILE",
     "XSAVE|64" },
+  { "ACE_V1",
+    "TILE|AVX10_V2_AUX|AVX10_1_AUX" },
   { "AMX_TILE",
     "TILE" },
   { "AMX_INT8",
@@ -480,6 +482,7 @@ static bitfield cpu_flags[] =
   BITFIELD (WAITPKG),
   BITFIELD (UINTR),
   BITFIELD (CLDEMOTE),
+  BITFIELD (ACE_V1),
   BITFIELD (AMX_INT8),
   BITFIELD (AMX_BF16),
   BITFIELD (AMX_FP16),
diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h
index 10fc3d3ddb5..b3bff8c35d7 100644
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -369,6 +369,8 @@ enum i386_cpu
   CpuAVX10_2,
   /* Intel AMX-TRANSPOSE Instructions support required.  */
   CpuAMX_TRANSPOSE,
+  /* ACE V1 instructions support required.  */
+  CpuACE_V1,
   /* Not supported in the 64bit mode  */
   CpuNo64,
 
@@ -407,6 +409,7 @@ enum i386_cpu
 		   cpuapx_f:1, \
 		   cpuavx10_2:1, \
 		   cpuamx_transpose:1, \
+		   cpuace_v1:1, \
       /* NOTE: This field needs to remain last. */ \
 		   cpuno64:1
 
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
index 40f22756659..2cf717b48a1 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -3239,11 +3239,34 @@ xresldtrk, 0xf20f01e9, TSXLDTRK, NoSuf, {}
 
 // TSXLDTRK instructions end.
 
-// AMX instructions.
+// AMX and ACE shared instructions.
 
 ldtilecfg, 0x49/0, APX_F(TILE), Modrm|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex }
 sttilecfg, 0x6649/0, APX_F(TILE), Modrm|Vex128|EVex128|Space0F38|VexW0|NoSuf, { Unspecified|BaseIndex }
 
+tilerelease, 0x49c0, TILE, Vex128|Space0F38|VexW0|NoSuf, {}
+
+tilezero, 0xf249, TILE, Modrm|Vex128|Space0F38|VexW0|NoSuf, { RegTMM }
+
+tcvtrowd2ps, 0xf34a, AMX_AVX512|ACE_V1, Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, RegZMM }
+tcvtrowd2ps, 0xf307, AMX_AVX512|ACE_V1, Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM }
+
+tcvtrowps2bf16h, 0xf26d, AMX_AVX512|ACE_V1, Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, RegZMM }
+tcvtrowps2bf16h, 0xf207, AMX_AVX512|ACE_V1, Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM }
+tcvtrowps2bf16l, 0xf36d, AMX_AVX512|ACE_V1, Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, RegZMM }
+tcvtrowps2bf16l, 0xf377, AMX_AVX512|ACE_V1, Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM }
+tcvtrowps2phh, 0x6d, AMX_AVX512|ACE_V1, Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, RegZMM }
+tcvtrowps2phh, 0x07, AMX_AVX512|ACE_V1, Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM }
+tcvtrowps2phl, 0x666d, AMX_AVX512|ACE_V1, Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, RegZMM }
+tcvtrowps2phl, 0xf277, AMX_AVX512|ACE_V1, Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM }
+
+tilemovrow, 0x664a, AMX_AVX512|ACE_V1, Modrm|EVex512|Space0F38|Src2VVVV|VexW0|NoSuf, { Reg32, RegTMM, RegZMM }
+tilemovrow, 0x6607, AMX_AVX512|ACE_V1, Modrm|EVex512|Space0F3A|VexW0|NoSuf, { Imm8, RegTMM, RegZMM }
+
+// AMX and ACE shared instructions end.
+
+// AMX instructions.
+
 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 }
 
@@ -3262,10 +3285,6 @@ tileloaddrs, 0xf24a, APX_F(AMX_MOVRS), Sibmem|Vex128|EVex128|Space0F38|VexW0|NoS
 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 }
 
-tilerelease, 0x49c0, TILE, Vex128|Space0F38|VexW0|NoSuf, {}
-
-tilezero, 0xf249, TILE, Modrm|Vex128|Space0F38|VexW0|NoSuf, { RegTMM }
-
 <z:pfx, z0:, z1:66>
 
 <loc:opc, $t:0x0, t1:0x1>
@@ -3295,21 +3314,6 @@ 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 }
-
-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 }
-
-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 }
-
 // AMX instructions end.
 
 // KEYLOCKER instructions.
diff --git a/opcodes/i386-reg.tbl b/opcodes/i386-reg.tbl
index 74234c503d6..c042c182921 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
-- 
2.34.1



More information about the Binutils mailing list