[PATCH] Add AMD znver6 processor support
Jan Beulich
jbeulich@suse.com
Fri Nov 7 13:20:13 GMT 2025
On 07.11.2025 10:34, Umesh Kalvakuntla wrote:
> Hi,
>
> This patch adds support for AMD znver6 processor.
> Please find the ISA descriptions for AVX512_BMM instructions below.
>
> ------------------
>
> AVX512 Bit Manipulation Instructions
> ==============================
> The AVX512BMM instructions include Bit Matrix Multiply and Bit Reversal
> operations.
>
> CPUID
> --------
> Support is indicated by the new CPUID 8000_0021, EAX bit 23, labeled AVX512_BMM.
>
> Encoding
> ------------
> VBMACOR16x16x16
> EVEX.256.NP.MAP6.W0 80 /r VBMACOR16x16x16 ymm1, ymm2, ymm3/m256
> EVEX.512.NP.MAP6.W0 80 /r VBMACOR16x16x16 zmm1, zmm2, zmm3/m512
>
> VBMACXOR16x16x16
> EVEX.256.NP.MAP6.W1 80 /r VBMACXOR16x16x16 ymm1, ymm2, ymm3/m256
> EVEX.512.NP.MAP6.W1 80 /r VBMACXOR16x16x16 zmm1, zmm2, zmm3/m512
>
> DESCRIPTION
> ------------------
> 256 BIT VERSIONS
> ------------------------
> 16x16 non-transposed fused BMM-accumulate (BMAC) with OR/XOR reduction.
> A ymm register holds a 16x16 bit matrix. The third source matrix for
> accumulation is in ymm1.
>
> 512 BIT VERSIONS
> ------------------------
> 2 parallel 16x16 non-transposed fused BMM-accumulate (BMAC) with OR/XOR
> reduction.
> Each 256-bit chunk of a zmm register holds a 16x16 bit matrix. The third source
> matrices for accumulation are in zmm1.
>
> VBITREV
> -----------
> EVEX.128.NP.MAP6.W0 81 /r VBITREV xmm1{k1}{z}, xmm2/m128
> EVEX.256.NP.MAP6.W0 81 /r VBITREV ymm1{k1}{z}, ymm2/m256
> EVEX.512.NP.MAP6.W0 81 /r VBITREV zmm1{k1}{z}, zmm2/m512
>
> DESCRIPTION
> ------------------
> Bit reversal within a byte boundary. Only applied to input bytes where the
> corresponding mask bit is set; otherwise, bytes are left untouched or zeroed out
> if zero masking is indicated.
>
> ------------------
>
> Thanks,
> Umesh
>
> ---
The separator give the impression that none of the above is meant to go into
the eventual commit message. Especially as long as there's no other doc
available, I think the doc part should be put there.
> From ba1f86768ccf5cf2f00b81c31ef092fc9bf1a80d Mon Sep 17 00:00:00 2001
> From: Umesh Kalvakuntla <Umesh.Kalvakuntla@amd.com>
> Date: Fri, 7 Nov 2025 12:10:05 +0530
> Subject: [PATCH] Add AMD znver6 processor support
>
> binutils/ChangeLog:
>
> * readelf.c (decode_x86_compat_2_isa): Add AVX512_BMM.
>
> gas/ChangeLog:
>
> * config/tc-i386.c: Add znver6 ARCH, avx512_bmm SUBARCH.
> * doc/c-i386.texi: Add znver6, avx512_bmm.
> * testsuite/gas/i386/i386.exp: Add znver6 test cases.
> * testsuite/gas/i386/arch-16-znver6.d: New test.
> * testsuite/gas/i386/arch-16.d: New test.
> * testsuite/gas/i386/arch-16.s: New test.
> * testsuite/gas/i386/avx512bmm.d: New test.
> * testsuite/gas/i386/avx512bmm.s: New test.
> * testsuite/gas/i386/x86-64-arch-6.d: New test.
> * testsuite/gas/i386/x86-64-arch-6.s: New test.
>
> include/ChangeLog:
>
> * elf/common.h (GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BMM):
> New macro.
>
> opcodes/ChangeLog:
>
> * i386-dis-evex-prefix.h: Likewise.
> * i386-dis-evex-w.h: Likewise.
> * i386-dis-evex.h: Likewise.
> * i386-dis.c: Add PREFIX_EVEX_MAP6_80, PREFIX_EVEX_MAP6_81,
> EVEX_W_MAP6_80_P_0.
> * i386-gen.c: Likewise.
> * i386-init.h: Re-generated.
> * i386-mnem.h: Re-generated.
> * i386-opc.h (enum i386_cpu): Add CpuAVX512_BMM.
> (i386_cpu_flags): Add cpuvavx512_bmm.
> * i386-opc.tbl: Add vbmacor16x16x16, vbmacxor16x16x16, vbitrev.
> * i386-tbl.h: Re-generated.
Mentioning the generated files here is fine, but please omit them from the
actual patch body. The emails get overly large (and hance hard to manage)
with them included.
> --- a/gas/NEWS
> +++ b/gas/NEWS
> @@ -1,5 +1,7 @@
> -*- text -*-
>
> +* Add support for AMD znver6 processor.
Isn't the official naming Zen6, with znver being a binutils internal way
of expressing things?
> --- a/gas/doc/c-i386.texi
> +++ b/gas/doc/c-i386.texi
> @@ -126,6 +126,7 @@ processor names are recognized:
> @code{znver3},
> @code{znver4},
> @code{znver5},
> +@code{znver6},
> @code{btver1},
> @code{btver2},
> @code{generic32} and
> @@ -198,6 +199,7 @@ accept various extension mnemonics. For example,
> @code{avx512_bf16},
> @code{avx_vnni},
> @code{avx512_fp16},
> +@code{avx512_bmm},
> @code{prefetchi},
> @code{avx_ifma},
> @code{avx_vnni_int8},
> @@ -1692,7 +1694,8 @@ supported on the CPU specified. The choices for @var{cpu_type} are:
> @item @samp{k6} @tab @samp{k6_2} @tab @samp{athlon} @tab @samp{k8}
> @item @samp{amdfam10} @tab @samp{bdver1} @tab @samp{bdver2} @tab @samp{bdver3}
> @item @samp{bdver4} @tab @samp{znver1} @tab @samp{znver2} @tab @samp{znver3}
> -@item @samp{znver4} @tab @samp{znver5} @tab @samp{btver1} @tab @samp{btver2}
> +@item @samp{znver4} @tab @samp{znver5} @tab @samp{znver6} @tab @samp{btver1}
> +@item @samp{btver2}
> @item @samp{generic32}
Please don't leave two successive single-item lines.
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/arch-16-znver6.d
> @@ -0,0 +1,5 @@
> +#source: arch-16.s
> +#as: -march=znver6
> +#objdump: -dw
> +#name: i386 arch 16 (znver6)
> +#dump: arch-16.d
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/arch-16.d
> @@ -0,0 +1,14 @@
> +#objdump: -dw
> +#name: x86-64 arch 6
> +
> +.*: file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+ <.text>:
> +[ ]*[a-f0-9]+:\s*62 f6 6c 28 80 d9\s+vbmacor16x16x16 %ymm1,%ymm2,%ymm3
> +[ ]*[a-f0-9]+:\s*62 f6 ec 48 80 d9\s+vbmacxor16x16x16 %zmm1,%zmm2,%zmm3
> +[ ]*[a-f0-9]+:\s*62 f6 7c 48 81 d1\s+vbitrev %zmm1,%zmm2
> +[ ]*[a-f0-9]+:\s*62 f6 7c 89 81 94 f4 c0 1d fe ff\s+vbitrev -0x1e240\(%esp,%esi,8\),%xmm2\{%k1\}\{z\}
> +#pass
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/arch-16.s
> @@ -0,0 +1,7 @@
> +# Test -march=
Well, do you, actually? All of ...
> + .text
> +
> + vbmacor16x16x16 %ymm1, %ymm2, %ymm3
> + vbmacxor16x16x16 %zmm1, %zmm2, %zmm3
> + vbitrev %zmm1, %zmm2
> + vbitrev -123456(%esp,%esi,8), %xmm2{%k1}{z}
... this will assemble fine without -march=znver6.
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/avx512bmm.s
> @@ -0,0 +1,24 @@
> +# Check AVX512_BMM instructions
> +
> + .text
> +bmm:
> + vbmacor16x16x16 %ymm1, %ymm2, %ymm3
> + vbmacor16x16x16 %zmm1, %zmm2, %zmm3
> + vbmacor16x16x16 -123456(%esp,%esi,8), %ymm1, %ymm2
> + vbmacor16x16x16 -123456(%esp,%esi,8), %zmm1, %zmm2
> + vbmacxor16x16x16 %ymm1, %ymm2, %ymm3
> + vbmacxor16x16x16 %zmm1, %zmm2, %zmm3
> + vbmacxor16x16x16 -123456(%esp,%esi,8), %ymm1, %ymm2
> + vbmacxor16x16x16 -123456(%esp,%esi,8), %zmm1, %zmm2
> + vbitrev %xmm1, %xmm2
> + vbitrev %ymm1, %ymm2
> + vbitrev %zmm1, %zmm2
> + vbitrev %xmm1, %xmm2{%k1}{z}
> + vbitrev %ymm1, %ymm2{%k1}{z}
> + vbitrev %zmm1, %zmm2{%k1}{z}
> + vbitrev -123456(%esp,%esi,8), %xmm2
> + vbitrev -123456(%esp,%esi,8), %ymm2
> + vbitrev -123456(%esp,%esi,8), %zmm2
> + vbitrev -123456(%esp,%esi,8), %xmm2{%k1}{z}
> + vbitrev -123456(%esp,%esi,8), %ymm2{%k1}{z}
> + vbitrev -123456(%esp,%esi,8), %zmm2{%k1}{z}
Please can you get indentation consistent at least within a single testcase?
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/x86-64-arch-6.s
> @@ -0,0 +1,7 @@
> +# Test -march=
> + .text
> +
> + vbmacor16x16x16 %ymm1, %ymm2, %ymm3
> + vbmacxor16x16x16 %zmm1, %zmm2, %zmm3
> + vbitrev %zmm1, %zmm2
> + vbitrev -123456(%esp,%esi,8), %xmm2{%k1}{z}
Same remark here as above.
> --- a/include/elf/common.h
> +++ b/include/elf/common.h
> @@ -1051,6 +1051,7 @@
> #define GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2 (1U << 22)
> #define GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI (1U << 23)
> #define GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16 (1U << 24)
> +#define GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BMM (1U << 25)
Is this bit assignment your own, or did you request it from the psABI? I don't
recall seeing anything there. I also question the need for this. The set isn't
quite complete anyway, and hence only of limited use.
> --- a/opcodes/i386-dis-evex-prefix.h
> +++ b/opcodes/i386-dis-evex-prefix.h
> @@ -709,6 +709,20 @@
> { Bad_Opcode },
> { "vfcmaddcs%XH", { { DistinctDest_Fixup, scalar_mode }, VexScalar, EXd, EXxEVexR }, 0 },
> },
> + /* PREFIX_EVEX_MAP6_80 */
> + {
> + { VEX_W_TABLE (EVEX_W_MAP6_80_P_0) },
> + { Bad_Opcode },
> + { Bad_Opcode },
> + { Bad_Opcode },
> + },
> + /* PREFIX_EVEX_MAP6_81 */
> + {
> + { "vbitrev", { XM, EXx}, NO_PREFIX },
This whole construct, including NO_PREFIX, wants to go in the parent table entry.
NO_PREFIX eliminates the need to go through prefix_table[] in the first place.
The other two insns similarly don't look to need to take this extra decode step.
Otoh, EVEX.W needs decoding for vbitrev, according to the doc you provided. Just
like for opcode 0x80 you will need to decode L'L, such that the 128-bit form is
properly disassembled as invalid (which will also want covering by a testcase).
Finally, nit: Missing blank ahead of the inner closing figure brace.
Jan
More information about the Binutils
mailing list