Re: [PATCH v2] Support AVX10_V2_AUX instructions

Jan Beulich <[email protected]>
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
On 25.08.2026 22:19, Rohan Shenoy wrote:
> Add assembler and disassembler support for AVX10_V2_AUX instructions.
> 
> AVX10_V2_AUX can be extended over AVX10.1, not only AVX10.2. Thus, the
> only name accepted for this feature is AVX10_V2_AUX/avx10v2aux.

I consider this a questionable justification, but well.

> --- a/gas/NEWS
> +++ b/gas/NEWS
> @@ -1,5 +1,8 @@
>  -*- text -*-
>  
> +* Add support for the x86 AVX10_V2_AUX instructions, providing FP8, FP4
> +  and FP6 format conversion instructions.

As the list isn't complete, I'm inclined to suggest to omit it altogether.

> --- a/gas/config/tc-i386.c
> +++ b/gas/config/tc-i386.c
> @@ -1255,6 +1255,7 @@ static const arch_entry cpu_arch[] =
>    VECARCH (avx10.1, AVX10_1, ANY_AVX512F, set),
>    VECARCH (avx10.1aux, AVX10_1_AUX, ANY_AVX10_1_AUX, set),
>    VECARCH (avx10.2, AVX10_2, ANY_AVX10_2, set),
> +  VECARCH (avx10v2aux, AVX10_V2_AUX, ANY_AVX10_V2_AUX, set),

This will need re-basing over the other patch that I have just committed for
you. As it was clear that the other one would want to go in first, I wonder
why you didn't put the one here on top of that one right away (mentioning
the dependency in the post-commit-message area).

> --- /dev/null
> +++ b/gas/testsuite/gas/i386/x86-64-avx10_v2_aux-intel.d
> @@ -0,0 +1,188 @@
> +#objdump: -dw -Mintel
> +#name: x86-64 AVX10 V2 AUX (Intel disassembly)
> +#source: x86-64-avx10_v2_aux.s
> +
> +.*: +file format .*
> +
> +Disassembly of section \.text:
> +
> +#...
> +[a-f0-9]+ <_intel>:
> +\s*[a-f0-9]+:\s*62 f5 7e 08 39 c1\s+vcvtps2bf8\s+xmm0,xmm1

Please can you replace \s by [ 	], like we do about everywhere else (especially
in newer tests)?

> +\s*[a-f0-9]+:\s*62 f5 7e 28 39 c1\s+vcvtps2bf8\s+xmm0,ymm1
> +\s*[a-f0-9]+:\s*62 f5 7e 48 39 c1\s+vcvtps2bf8\s+xmm0,zmm1
> +\s*[a-f0-9]+:\s*62 f5 7e 08 39 41 7f\s+vcvtps2bf8\s+xmm0,XMMWORD\s+PTR\s+\[rcx\+0x7f0\]
> +\s*[a-f0-9]+:\s*62 f5 7e 28 39 41 7f\s+vcvtps2bf8\s+xmm0,YMMWORD\s+PTR\s+\[rcx\+0xfe0\]
> +\s*[a-f0-9]+:\s*62 f5 7e 48 39 41 7f\s+vcvtps2bf8\s+xmm0,ZMMWORD\s+PTR\s+\[rcx\+0x1fc0\]
> +\s*[a-f0-9]+:\s*62 d5 7e 18 39 01\s+vcvtps2bf8\s+xmm0,DWORD\s+BCST\s+\[r9\]\{1to4\}

The fields between DWORD and BCST and [ really shouldn't be other than a single
blank. That'll then also help readability (and hence reviewability).

> --- /dev/null
> +++ b/gas/testsuite/gas/i386/x86-64-avx10_v2_aux.s
> @@ -0,0 +1,211 @@
> +# Check 64-bit AVX10 V2 AUX instructions
> +
> +	.arch generic64
> +	.arch .avx10v2aux
> +	.text
> +_start:
> +	.irp m, bf8, bf8s, hf8, hf8s
> +	vcvtps2\m	%xmm1, %xmm0
> +	vcvtps2\m	%ymm1, %xmm0
> +	vcvtps2\m	%zmm1, %xmm0
> +	vcvtps2\m\()x	2032(%rcx), %xmm0
> +	vcvtps2\m\()y	4064(%rcx), %xmm0
> +	vcvtps2\m\()z	8128(%rcx), %xmm0
> +	vcvtps2\m	(%r9){1to4}, %xmm0
> +	vcvtps2\m	(%r9){1to8}, %xmm0
> +	vcvtps2\m	(%r9){1to16}, %xmm0
> +	vcvtps2\m	%xmm1, %xmm0{%k1}
> +	vcvtps2\m	%xmm1, %xmm0{%k1}{z}
> +
> +	vcvtbiasps2\m	%xmm2, %xmm1, %xmm0
> +	vcvtbiasps2\m	%ymm2, %ymm1, %xmm0
> +	vcvtbiasps2\m	%zmm2, %zmm1, %xmm0
> +	vcvtbiasps2\m	2032(%rcx), %xmm1, %xmm0
> +	vcvtbiasps2\m	4064(%rcx), %ymm1, %xmm0
> +	vcvtbiasps2\m	8128(%rcx), %zmm1, %xmm0
> +	vcvtbiasps2\m	(%r9){1to4}, %xmm1, %xmm0
> +	vcvtbiasps2\m	(%r9){1to8}, %ymm1, %xmm0
> +	vcvtbiasps2\m	(%r9){1to16}, %zmm1, %xmm0
> +	vcvtbiasps2\m	%xmm2, %xmm1, %xmm0{%k1}
> +	vcvtbiasps2\m	%xmm2, %xmm1, %xmm0{%k1}{z}
> +	.endr
> +
> +	.irp m, hf8, hf8s
> +	vcvtrops2\m	%xmm1, %xmm0
> +	vcvtrops2\m	%ymm1, %xmm0
> +	vcvtrops2\m	%zmm1, %xmm0
> +	vcvtrops2\m\()x	2032(%rcx), %xmm0
> +	vcvtrops2\m\()y	4064(%rcx), %xmm0
> +	vcvtrops2\m\()z	8128(%rcx), %xmm0
> +	vcvtrops2\m	(%r9){1to4}, %xmm0
> +	vcvtrops2\m	(%r9){1to8}, %xmm0
> +	vcvtrops2\m	(%r9){1to16}, %xmm0
> +	vcvtrops2\m	%xmm1, %xmm0{%k1}
> +	vcvtrops2\m	%xmm1, %xmm0{%k1}{z}
> +	.endr
> +
> +	.irp f, bf, hf
> +	vcvt\f\()82ps	%xmm1, %xmm0
> +	vcvt\f\()82ps	%xmm1, %ymm0
> +	vcvt\f\()82ps	%xmm1, %zmm0
> +	vcvt\f\()82ps	508(%rcx), %xmm0
> +	vcvt\f\()82ps	1016(%rcx), %ymm0
> +	vcvt\f\()82ps	2032(%rcx), %zmm0
> +	vcvt\f\()82ps	%xmm1, %xmm0{%k1}
> +	vcvt\f\()82ps	%xmm1, %xmm0{%k1}{z}
> +
> +	vcvt\f\()82bf4s	%xmm1, %xmm0
> +	vcvt\f\()82bf4s	%ymm1, %xmm0
> +	vcvt\f\()82bf4s	%zmm1, %ymm0
> +	vcvt\f\()82bf4s	%xmm1, 1016(%rcx)
> +	vcvt\f\()82bf4s	%ymm1, 2032(%rcx)
> +	vcvt\f\()82bf4s	%zmm1, 4064(%rcx)
> +
> +	.endr

Nit: Stray blank line above here (or another one wants inserting after the
.irp one, but then similarly in the other .irp above).

> +	vcvtbf82bf6s	%xmm1, %xmm0
> +	vcvtbf82bf6s	%ymm1, %ymm0
> +	vcvtbf82bf6s	%zmm1, %zmm0
> +
> +	vcvthf82hf6s	%xmm1, %xmm0
> +	vcvthf82hf6s	%ymm1, %ymm0
> +	vcvthf82hf6s	%zmm1, %zmm0
> +
> +	vcvtbf42hf8	%xmm1, %xmm0
> +	vcvtbf42hf8	%xmm1, %ymm0
> +	vcvtbf42hf8	%ymm1, %zmm0
> +	vcvtbf42hf8	1016(%rcx), %xmm0
> +	vcvtbf42hf8	2032(%rcx), %ymm0
> +	vcvtbf42hf8	4064(%rcx), %zmm0
> +	vcvtbf42hf8	%xmm1, %xmm0{%k1}
> +	vcvtbf42hf8	%xmm1, %xmm0{%k1}{z}
> +
> +	.irp f, bf, hf
> +	vcvt\f\()62hf8	%xmm1, %xmm0
> +	vcvt\f\()62hf8	%ymm1, %ymm0
> +	vcvt\f\()62hf8	%zmm1, %zmm0
> +	vcvt\f\()62hf8	%xmm1, %xmm0{%k1}
> +	vcvt\f\()62hf8	%xmm1, %xmm0{%k1}{z}
> +	.endr
> +
> +	vpmovssdb	%xmm1, %xmm0
> +	vpmovssdb	%ymm1, %xmm0
> +	vpmovssdb	%zmm1, %xmm0
> +	vpmovssdb	%xmm1, 508(%rcx)
> +	vpmovssdb	%ymm1, 1016(%rcx)
> +	vpmovssdb	%zmm1, 2032(%rcx)
> +	vpmovssdb	%xmm1, %xmm0{%k1}
> +	vpmovssdb	%xmm1, %xmm0{%k1}{z}
> +
> +	vunpackb	$1, %xmm1, %xmm0
> +	vunpackb	$1, %ymm1, %ymm0
> +	vunpackb	$1, %zmm1, %zmm0
> +	vunpackb	$1, 2032(%rcx), %xmm0
> +	vunpackb	$1, 4064(%rcx), %ymm0
> +	vunpackb	$1, 8128(%rcx), %zmm0
> +	vunpackb	$1, %xmm1, %xmm0{%k1}
> +	vunpackb	$1, %xmm1, %xmm0{%k1}{z}

Please use immediates which are actually valid for the insn. We could
in principle add warnings for 0, 1, and everything 8 upwards, and doing
so should not result in the need to touch testcases like this one.

> --- a/opcodes/i386-dis-evex-mod.h
> +++ b/opcodes/i386-dis-evex-mod.h
> @@ -18,3 +18,18 @@
>      { "enqcmd",		{ Gva, M }, 0 },
>      { VEX_W_TABLE (EVEX_W_MAP4_F8_P3_M_1) },
>    },
> +  /* MOD_EVEX_MAP5_37_P_2 */
> +  {
> +    { Bad_Opcode },
> +    { "vcvt%XF62hf8",	{ XM, EXx }, 0 },
> +  },
> +  /* MOD_EVEX_MAP5_3C_W_0_P_1 */
> +  {
> +    { Bad_Opcode },
> +    { "vcvthf82hf6s",	{ XM, EXx }, 0 },
> +  },
> +  /* MOD_EVEX_MAP5_3E_W_1_P_1 */
> +  {
> +    { Bad_Opcode },
> +    { "vcvtbf82bf6s",	{ XM, EXx }, 0 },
> +  },

I think these can move up a level (i.e. without going through mod_table[]),
by using Ux in place of EXx. As you can see from other mod_table[] entries
(and respective prior commits), they always have both elements set to
something other than Bad_Opcode.

> --- a/opcodes/i386-dis-evex-w.h
> +++ b/opcodes/i386-dis-evex-w.h
> @@ -346,6 +346,11 @@
>    {
>      { "vpbroadcastmw2dY",	{ XM, MaskR }, 0 },
>    },
> +  /* EVEX_W_0F3841 */
> +  {
> +    { PREFIX_TABLE (PREFIX_EVEX_0F3841_W_0) },
> +    { Bad_Opcode },
> +  },

As you can see even from patch context here, there's no need for trailing
Bad_Opcode entries. Same about everywhere below.

> @@ -1935,6 +1958,7 @@ struct dis386 {
>     "XH" => print 'h' if EVEX.W=0, EVEX.W=1 is not a valid encoding (for FP16)
>     "XB" => print 'bf16' if EVEX.W=0, EVEX.W=1 is not a valid encoding
>  	   (for BF16)
> +   "XF" => print 'hf' if EVEX.W=0 or 'bf' if EVEX.W=1

HB would be the more natural name for this. Whether to include 'f' in the
expansion is uncertain, but I'm okay with keeping it like that for now (in
the interest of shorter string literals in the tables).

> @@ -11075,6 +11099,8 @@ putop (instr_info *ins, const char *in_template, int sizeflag)
>  		  ins->used_prefixes |= (ins->prefixes & PREFIX_ADDR);
>  		}
>  	    }
> +	  else if (l == 1 && last[0] == 'X')
> +	    oappend (ins, ins->vex.w ? "bf" : "hf");

I don't think using oappend() is valid here, as that'll insert markings
for dis_style_text. Like respective surrounding code does, you want to use
"*ins->obufp++ = ..." here.

> --- a/opcodes/i386-gen.c
> +++ b/opcodes/i386-gen.c
> @@ -251,6 +251,8 @@ static const dependency isa_dependencies[] =
>      "AVX10_1" },
>    { "AVX10_2",
>      "AVX10_1_AUX" },
> +  { "AVX10_V2_AUX",
> +    "AVX10_1" },

Just to double check: It's not AVX_1_AUX that this wants to depend upon?
I.e. in particular full-fledged ACE demands only 10.1 plus v2-aux? (I'm
leaving aside whether really we want to have ACE have a dependency on
whatever AVX10 variant it builds upon.)

> --- a/opcodes/i386-opc.h
> +++ b/opcodes/i386-opc.h
> @@ -332,6 +332,8 @@ enum i386_cpu
>    CpuAPX_NDD,
>    /* Intel APX No-Flags-update support required.  */
>    CpuAPX_NF,
> +  /* AVX10 V2 Auxiliary Instructions support required.  */
> +  CpuAVX10_V2_AUX,

I think this would best go right after CpuAVX10_1_AUX.

> --- a/opcodes/i386-opc.tbl
> +++ b/opcodes/i386-opc.tbl
> @@ -2266,6 +2266,13 @@ vpclmulhqhqdq, 0x6644/0x11, VPCLMULQDQ&(AVX|AVX512F), Modrm|Space0F3A|Vex|EVexDY
>      x:AVX512VL:EVex128|Disp8MemShift=4|ATTSyntax:::RegXMM|Unspecified|BaseIndex:RegXMM, +
>      y:AVX512VL:EVex256|Disp8MemShift=5|ATTSyntax:::RegYMM|Unspecified|BaseIndex:RegXMM>
>  
> +<Exyz:attr:src, +
> +    $i:Disp8ShiftVL|IntelSyntax:RegXMM|RegYMM|RegZMM|Unspecified|BaseIndex, +
> +    $a:Disp8ShiftVL|ATTSyntax:RegXMM|RegYMM|RegZMM|BaseIndex, +
> +    x:EVex128|Disp8MemShift=4|ATTSyntax:RegXMM|Unspecified|BaseIndex, +
> +    y:EVex256|Disp8MemShift=5|ATTSyntax:RegYMM|Unspecified|BaseIndex, +
> +    z:EVex512|Disp8MemShift=6|ATTSyntax:RegZMM|Unspecified|BaseIndex>

I can't quite spot why this is needed, i.e. why <xyz> cannot be reused.

> @@ -3614,6 +3621,62 @@ vucomxs<sdh>, 0x<sdh:spfx>2e, AVX10_2, Modrm|EVexLIG|<sdh:spc1>|<sdh:vexw>|Disp8
>  
>  // AVX10.2 instructions end.
>  
> +// AVX10_V2_AUX instructions.
> +
> +<cvtps8:opc, +
> +    bf8:39, +
> +    bf8s:3b, +
> +    hf8:38, +
> +    hf8s:3a>

This can go on a single line.

> +vcvtps2<cvtps8><Exyz>, 0xf3<cvtps8:opc>, AVX10_V2_AUX, Modrm|Map5|<Exyz:attr>|VexW0|Masking|Broadcast|NoSuf, { <Exyz:src>|Dword, RegXMM }
> +
> +vcvtbiasps2<cvtps8>, 0x<cvtps8:opc>, AVX10_V2_AUX, Modrm|Map5|Src1VVVV|VexW0|Masking|Broadcast|Disp8ShiftVL|CheckOperandSize|NoSuf, { RegXMM|RegYMM|RegZMM|Dword|Unspecified|BaseIndex, RegXMM|RegYMM|RegZMM, RegXMM }
> +
> +<cvtps8>
> +
> +<cvtrops8:opc, +
> +    hf8:38, +
> +    hf8s:3a>

Same here.

> +vcvtrops2<cvtrops8><Exyz>, 0x66<cvtrops8:opc>, AVX10_V2_AUX, Modrm|Map5|<Exyz:attr>|VexW0|Masking|Broadcast|NoSuf, { <Exyz:src>|Dword, RegXMM }
> +
> +<cvtrops8>
> +
> +<fp:vexw, +
> +    hf:VexW0, +
> +    bf:VexW1>

And here. For this one I further think <f8> would be a better name, and then
the '8' may want including in the expansions (but see below).

> +vcvt<fp>82ps, 0x36, AVX10_V2_AUX, Modrm|Map5|EVex128|<fp:vexw>|Masking|Disp8MemShift=2|NoSuf, { RegXMM|Dword|Unspecified|BaseIndex, RegXMM }
> +vcvt<fp>82ps, 0x36, AVX10_V2_AUX, Modrm|Map5|EVex256|<fp:vexw>|Masking|Disp8MemShift=3|NoSuf, { RegXMM|Qword|Unspecified|BaseIndex, RegYMM }
> +vcvt<fp>82ps, 0x36, AVX10_V2_AUX, Modrm|Map5|EVex512|<fp:vexw>|Masking|Disp8MemShift=4|NoSuf, { RegXMM|Unspecified|BaseIndex, RegZMM }
> +
> +vcvt<fp>82bf4s, 0xf33d, AVX10_V2_AUX, RegMem|Map5|EVex128|<fp:vexw>|Disp8MemShift=3|NoSuf, { RegXMM, RegXMM|Qword|Unspecified|BaseIndex }
> +vcvt<fp>82bf4s, 0xf33d, AVX10_V2_AUX, RegMem|Map5|EVex256|<fp:vexw>|Disp8MemShift=4|NoSuf, { RegYMM, RegXMM|Unspecified|BaseIndex }
> +vcvt<fp>82bf4s, 0xf33d, AVX10_V2_AUX, RegMem|Map5|EVex512|<fp:vexw>|Disp8MemShift=5|NoSuf, { RegZMM, RegYMM|Unspecified|BaseIndex }
> +
> +<fp>
> +
> +vcvtbf82bf6s, 0xf33e, AVX10_V2_AUX, Modrm|EVexDYN|Map5|VexW1|CheckOperandSize|NoSuf, { RegXMM|RegYMM|RegZMM, RegXMM|RegYMM|RegZMM }
> +
> +vcvthf82hf6s, 0xf33c, AVX10_V2_AUX, Modrm|EVexDYN|Map5|VexW0|CheckOperandSize|NoSuf, { RegXMM|RegYMM|RegZMM, RegXMM|RegYMM|RegZMM }

With an F6-opcode field added, <fp> from above looks to also be usable here.
Except that this may then need an adjustment to i386-gen, such that the
choice of h vs b can be suitably expressed for the 2nd occurrence of the
letters in the mnemonics. That is, without resorting to something like

<fp:form:vexw, $h:hf8:VexW0, $b:bf8:VexW1>

as that would result in somewhat awkward use in the mnemonics further up.

Overall - perhaps not worth it for the moment.

> +vcvtbf42hf8, 0x37, AVX10_V2_AUX, Modrm|Map5|EVex128|VexW0|Masking|Disp8MemShift=3|NoSuf, { RegXMM|Qword|Unspecified|BaseIndex, RegXMM }
> +vcvtbf42hf8, 0x37, AVX10_V2_AUX, Modrm|Map5|EVex256|VexW0|Masking|Disp8MemShift=4|NoSuf, { RegXMM|Unspecified|BaseIndex, RegYMM }
> +vcvtbf42hf8, 0x37, AVX10_V2_AUX, Modrm|Map5|EVex512|VexW0|Masking|Disp8MemShift=5|NoSuf, { RegYMM|Unspecified|BaseIndex, RegZMM }
> +
> +vcvtbf62hf8, 0x6637, AVX10_V2_AUX, Modrm|Map5|VexW1|Masking|CheckOperandSize|NoSuf, { RegXMM|RegYMM|RegZMM, RegXMM|RegYMM|RegZMM }
> +
> +vcvthf62hf8, 0x6637, AVX10_V2_AUX, Modrm|Map5|VexW0|Masking|CheckOperandSize|NoSuf, { RegXMM|RegYMM|RegZMM, RegXMM|RegYMM|RegZMM }

Without the '8' included in the expansion, <fp> from above would be usable here
with no adjustment at all, afaict. Then <f8> may not be a good name, yet <fp>
also doesn't look overly suitable (for being too broad a name). Maybe <hb> or
<hbf>?

Jan
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.