[PATCH V3] Support APX NF

Cui, Lili lili.cui@intel.com
Tue Mar 26 06:28:04 GMT 2024


> On 19.03.2024 07:41, Cui, Lili wrote:
> > --- a/gas/testsuite/gas/i386/x86-64-apx-evex-promoted-bad.s
> > +++ b/gas/testsuite/gas/i386/x86-64-apx-evex-promoted-bad.s
> > @@ -23,7 +23,7 @@ _start:
> >  	.insn EVEX.L1.66.M12.W0 0x60, %di, %ax
> >
> >  	#EVEX_MAP4 movbe %r18w,%ax set EVEX.z == 0b1.
> > -	.insn EVEX.L0.66.M12.W0 0x60, %di, %ax {%k7}{z}
> > +	.insn EVEX.L0.66.M12.W0 0x60, %di, %ax {%k3}{z}
> >
> >  	#EVEX from VEX bzhi %rax,(%rax,%rbx),%rcx EVEX.aaa[1:0] (P[17:16])
> >  	#== 0b01
> > @@ -33,17 +33,23 @@ _start:
> >  	.insn EVEX.L1.NP.0f38.W1 0xf5, %rax, (%rax,%rbx), %rcx
> >
> >  	#EVEX from VEX bzhi %rax,(%rax,%rbx),%rcx EVEX.P[23](EVEX.z) == 0b1
> > -	.insn EVEX.L0.NP.0f38.W1 0xf5, %rax, (%rax,%rbx), %rcx {%k7}{z}
> > +	.insn EVEX.L0.NP.0f38.W1 0xf5, %rax, (%rax,%rbx), %rcx {%k3}{z}
> >
> >  	#EVEX from VEX bzhi %rax,(%rax,%rbx),%rcx EVEX.P[20](EVEX.b) == 0b1
> >  	.insn EVEX.L0.NP.0f38.W1 0xf5, %rax, (%rax,%rbx){1to8}, %rcx
> >
> >  	#{evex} inc %rax %rbx EVEX.vvvv != 1111 && EVEX.ND = 0.
> >  	.byte 0x62, 0xf4, 0xe4, 0x08, 0xff, 0x04, 0x08
> > +
> >  	# pop2 %rax, %r8 set EVEX.ND=0.
> >  	.byte 0x62, 0xf4, 0x3c, 0x08, 0x8f, 0xc0
> >  	.byte 0xff, 0xff, 0xff
> > +
> >  	# pop2 %rax, %r8 set EVEX.vvvv = 1111.
> >  	.insn EVEX.L0.M4.W0 0x8f,  %rax, {rn-sae},%r8
> > -	# pop2 %r8, %r8.
> > -	.byte 0x62, 0xd4, 0x3c, 0x18, 0x8f, 0xc0
> 
> This was already replaced, and not ...
> 
> > +	# pop2 %r11, %r11.
> > +	.byte 0x62, 0xd4, 0x24, 0x18, 0x8f, 0xc3
> 
> ... by byte. You want to rebase.
> 

Ok.

> > --- /dev/null
> > +++ b/gas/testsuite/gas/i386/x86-64-apx-nf.s
> > @@ -0,0 +1,1374 @@
> > +# Check 64bit APX_F instructions
> > +
> > +        .text
> > +_start:
> > +	{nf}	imul	%bl
> > +	{nf}	imul	%dx
> > +	{nf}	imul	%dx, %ax
> > +	{nf}	imul	%dx, %ax, %r9w
> > +	{nf}	imul	%ecx
> > +	{nf}	imul	%ecx, %edx
> > +	{nf}	imul	%ecx, %edx, %r10d
> > +	{nf}	imul	%r9
> > +	{nf}	imul	%r9, %r31
> > +	{nf}	imul	%r9, %r31, %r11
> > +	{nf}	imulb	291(%r8, %rax, 4)
> > +	{nf}	imulw	291(%r8, %rax, 4)
> > +	{nf}	imul	291(%r8, %rax, 4), %dx
> > +	{nf}	imul	291(%r8, %rax, 4), %dx, %ax
> > +	{nf}	imull	291(%r8, %rax, 4)
> > +	{nf}	imul	291(%r8, %rax, 4), %ecx
> > +	{nf}	imul	291(%r8, %rax, 4), %ecx, %edx
> > +	{nf}	imulq	291(%r8, %rax, 4)
> > +	{nf}	imul	291(%r8, %rax, 4), %r9
> > +	{nf}	imul	291(%r8, %rax, 4), %r9, %r31
> > +	{nf}	imul	$0x7b, %dx, %ax
> > +	{nf}	imul	$0x7b, %ecx, %edx
> > +	{nf}	imul	$0x7b, %r9, %r15
> > +	{nf}	imul	$0x7b, 291(%r8, %rax, 4), %dx
> > +	{nf}	imul	$0x7b, 291(%r8, %rax, 4), %ecx
> > +	{nf}	imul	$0x7b, 291(%r8, %rax, 4), %r9
> > +	{nf}	imul	$0xff90, %dx, %ax
> > +	{nf}	imul	$0xff90, %ecx, %edx
> > +	{nf}	imul	$0xff90, %r9, %r15
> > +	{nf}	imul	$0xff90, 291(%r8, %rax, 4), %dx
> > +	{nf}	imul	$0xff90, 291(%r8, %rax, 4), %ecx
> > +	{nf}	imul	$0xff90, 291(%r8, %rax, 4), %r9
> 
> Just to mention it here as well: The two-operand forms (immediate and
> register) also want testing (and, as you had indicated, also enabling in the
> opcode table).
> 

Done.

> > --- a/opcodes/i386-dis-evex.h
> > +++ b/opcodes/i386-dis-evex.h
> > @@ -875,19 +875,19 @@ static const struct dis386 evex_table[][256] = {
> >    /* EVEX_MAP4_ */
> >    {
> >      /* 00 */
> > -    { "addB",             { VexGb, Eb, Gb }, NO_PREFIX },
> > -    { "addS",             { VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
> > -    { "addB",             { VexGb, Gb, EbS }, NO_PREFIX },
> > -    { "addS",             { VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
> > +    { "%NFaddB",		{ VexGb, Eb, Gb }, NO_PREFIX },
> > +    { "%NFaddS",		{ VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
> > +    { "%NFaddB",		{ VexGb, Gb, EbS }, NO_PREFIX },
> > +    { "%NFaddS",		{ VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
> 
> While I appreciate you switching from space to tab padding, as is used
> elsewhere, I'm under the impression that the operand column doesn't align
> properly anymore throughout ...
> 
> >      { Bad_Opcode },
> >      { Bad_Opcode },
> >      { Bad_Opcode },
> >      { Bad_Opcode },
> >      /* 08 */
> > -    { "orB",		{ VexGb, Eb, Gb }, NO_PREFIX },
> > -    { "orS",		{ VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
> > -    { "orB",		{ VexGb, Gb, EbS }, NO_PREFIX },
> > -    { "orS",		{ VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
> > +    { "%NForB",		{ VexGb, Eb, Gb }, NO_PREFIX },
> > +    { "%NForS",		{ VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
> > +    { "%NForB",		{ VexGb, Gb, EbS }, NO_PREFIX },
> > +    { "%NForS",		{ VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
> >      { Bad_Opcode },
> >      { Bad_Opcode },
> >      { Bad_Opcode },
> > @@ -911,28 +911,28 @@ static const struct dis386 evex_table[][256] = {
> >      { Bad_Opcode },
> >      { Bad_Opcode },
> >      /* 20 */
> > -    { "andB",		{ VexGb, Eb, Gb }, NO_PREFIX },
> > -    { "andS",		{ VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
> > -    { "andB",		{ VexGb, Gb, EbS }, NO_PREFIX },
> > -    { "andS",		{ VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
> > -    { "shldS",		{ VexGv, Ev, Gv, Ib }, PREFIX_NP_OR_DATA },
> > +    { "%NFandB",		{ VexGb, Eb, Gb }, NO_PREFIX },
> > +    { "%NFandS",		{ VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
> > +    { "%NFandB",		{ VexGb, Gb, EbS }, NO_PREFIX },
> > +    { "%NFandS",		{ VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
> > +    { "%NFshldS",		{ VexGv, Ev, Gv, Ib }, PREFIX_NP_OR_DATA },
> >      { Bad_Opcode },
> >      { Bad_Opcode },
> >      { Bad_Opcode },
> >      /* 28 */
> > -    { "subB",		{ VexGb, Eb, Gb }, NO_PREFIX },
> > -    { "subS",		{ VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
> > -    { "subB",		{ VexGb, Gb, EbS }, NO_PREFIX },
> > -    { "subS",		{ VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
> > -    { "shrdS",		{ VexGv, Ev, Gv, Ib }, PREFIX_NP_OR_DATA },
> > +    { "%NFsubB",		{ VexGb, Eb, Gb }, NO_PREFIX },
> > +    { "%NFsubS",		{ VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
> > +    { "%NFsubB",		{ VexGb, Gb, EbS }, NO_PREFIX },
> > +    { "%NFsubS",		{ VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
> > +    { "%NFshrdS",		{ VexGv, Ev, Gv, Ib }, PREFIX_NP_OR_DATA },
> >      { Bad_Opcode },
> >      { Bad_Opcode },
> >      { Bad_Opcode },
> >      /* 30 */
> > -    { "xorB",		{ VexGb, Eb, Gb }, NO_PREFIX },
> > -    { "xorS",		{ VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
> > -    { "xorB",		{ VexGb, Gb, EbS }, NO_PREFIX },
> > -    { "xorS",		{ VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
> > +    { "%NFxorB",		{ VexGb, Eb, Gb }, NO_PREFIX },
> > +    { "%NFxorS",		{ VexGv, Ev, Gv }, PREFIX_NP_OR_DATA },
> > +    { "%NFxorB",		{ VexGb, Gb, EbS }, NO_PREFIX },
> > +    { "%NFxorS",		{ VexGv, Gv, EvS }, PREFIX_NP_OR_DATA },
> 
> ... here.
> 

Done.

> > @@ -9652,6 +9666,9 @@ print_insn (bfd_vma pc, disassemble_info *info, int
> intel_syntax)
> >  		    oappend (&ins, "/(bad)");
> >  		}
> >  	    }
> > +	  /* vex.nf is cleared after being consumed.  */
> > +	  if (ins.vex.nf)
> 
> Just like you have it here, ...
> 
> > +	    oappend (&ins, "{bad-nf}");
> >
> >  	  /* Check whether rounding control was enabled for an insn not
> >  	     supporting it, when evex.b is not treated as evex.nd.  */ @@
> > -10564,6 +10581,15 @@ putop (instr_info *ins, const char *in_template, int
> sizeflag)
> >  	    }
> >  	  else if (l == 1 && last[0] == 'C')
> >  	    break;
> > +	  else if (l == 1 && last[0] == 'N')
> > +	    {
> > +	      if (ins->vex.nf == true)
> 
> ... no comparison against true (or false) please.
> 

Done.

> > // clr with 1 operand is really xor with 2 operands.
> >  clr, 0x30, 0, W|Modrm|No_sSuf|RegKludge|Optimize, {
> > Reg8|Reg16|Reg32|Reg64 }
> > +clr, 0x30, APX_F, W|Modrm|No_sSuf|RegKludge|EVexMap4, {
> > +Reg8|Reg16|Reg32|Reg64 }
> 
> Shouldn't this also have NF?
> 

Yes, added NF and test cases for it.

Thanks,
Lili.


More information about the Binutils mailing list