[PATCH v5] Support ymm rounding control for Intel AVX10.2
Jiang, Haochen
haochen.jiang@intel.com
Tue Aug 27 07:08:11 GMT 2024
> From: Jan Beulich <jbeulich@suse.com>
> Sent: Monday, August 26, 2024 10:23 PM
>
> On 23.08.2024 10:38, Haochen Jiang wrote:
> > In the patch, in order to support ymm rounding for AVX10.2, we derive
> > evex attribute for all cases instead of only for rc_none to encode U bit.
> > Also changed some bad_opcode return due to the share of U bit with APX_F.
> >
> > Instead of adding new table entries, our current method is to alter the
> > CPUID part to add AVX10_2 explicitly for ymm rounding support, also
> > using similar way as APX_F for the CPUID combination, since ymm rounding
> > control is also somehow an instruction promotion, i.e.:
> >
> > #define AVX10_2(cpuid) cpuid&(cpuid|AVX10_2)
>
> The APX attribute was only added as necessary. Legacy insns being extended
> to use REX2 encodings weren't altered. Similarly no AVX10.1 attributes were
> added anywhere. IOW as before - please limit the opcode table changes to
> just those places where new insn forms need adding (I expect that's going
> to be a couple of convert insns with differring source/destination element
> sizes).
AVX10.1 definitely doesn't need to be added everywhere since we are actually
implying AVX512.
However, AVX10.2 is different, it does contain new feature for ymm rounding.
I am not changing everywhere but only altering those related instruction CPUID,
which is the maybe optimal change for now since splitting encoding_evex512
will be a separate patch. All of them are needed, which are actually the new insn
forms since ymm rounding doesn't exist before AVX10.2.
>
> > + u = (i.rounding.type != rc_none
> > + && i.tm.opcode_modifier.evex == EVEX256) ? false : true;
>
> What's the conditional operator for? This
>
> u = (i.rounding.type == rc_none
> || i.tm.opcode_modifier.evex != EVEX256);
>
> is imo easier to follow.
It comes from original 0-1. Yes, it should be that after changing to bool.
>
> > + enabled. There's no need to check all operands, though: Either of the
> > last two operands will be of the right size in all relevant templates. */
> > if (t->opcode_modifier.evex != EVEXLIG
> > && t->opcode_modifier.evex != EVEX512
> > + && (t->opcode_modifier.evex != EVEX256
> > + || !cpu_arch_flags.bitfield.cpuavx10_2)
> > && !i.types[t->operands - 1].bitfield.zmmword
> > - && !i.types[t->operands - 2].bitfield.zmmword)
> > + && !i.types[t->operands - 2].bitfield.zmmword
> > + && ((!i.types[t->operands - 1].bitfield.ymmword
> > + && !i.types[t->operands - 2].bitfield.ymmword)
> > + || !cpu_arch_flags.bitfield.cpuavx10_2))
> > {
> > i.error = operand_size_mismatch;
> > return 1;
>
> Since you now uniformly resolve t->opcode_modifier.evex when it's EVEXDYN,
> do you actually still need the .zmmword / .ymmword checks? In the
> calculation of the U bit you also rely on solely that attribute.
check_VecOperands() comes earlier than build_evex_prefix(). At this point,
the evex for EVEXDYN has not been derived. We could and I have considered to
move that part into check_VecOperands(), but I suppose it might be out of
scope for this function.
Thx,
Haochen
>
> Jan
More information about the Binutils
mailing list