public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: "Cui, Lili" <lili.cui@intel.com>
To: "Beulich, Jan" <JBeulich@suse.com>
Cc: "Lu, Hongjiu" <hongjiu.lu@intel.com>,
	"binutils@sourceware.org" <binutils@sourceware.org>
Subject: RE: [PATCH V2 3/8] Support APX GPR32 with extend evex prefix
Date: Wed, 15 Nov 2023 06:03:53 +0000	[thread overview]
Message-ID: <SJ0PR11MB56004596A199CCE5E6E7768E9EB1A@SJ0PR11MB5600.namprd11.prod.outlook.com> (raw)
In-Reply-To: <4aebadde-7cba-050e-d2eb-188d6216c566@suse.com>

> > --- a/opcodes/i386-dis-evex-mod.h
> > +++ b/opcodes/i386-dis-evex-mod.h
> > @@ -1 +1,43 @@
> >  /* Nothing at present.  */
> 
> This comment needs to go away when new stuff is added here. However, I'm
> sure I requested before that no new entries be put here which have only one
> of their two slots populated. The reg-only and mem-only aspects can be
> expressed via proper choice of operand specifiers, at least in almost all cases.
> Note how you already use ...
> 
> > +  /* MOD_EVEX_MAP4_DA_PREFIX_1 */
> > +  {
> > +    { Bad_Opcode },
> > +    { "encodekey128", { Gd, Ed }, 0 },  },
> > +  /* MOD_EVEX_MAP4_DB_PREFIX_1 */
> > +  {
> > +    { Bad_Opcode },
> > +    { "encodekey256", { Gd, Ed }, 0 },  },
> > +  /* MOD_EVEX_MAP4_DC_PREFIX_1 */
> > +  {
> > +    { "aesenc128kl",    { XM, M }, 0 },
> > +  },
> > +  /* MOD_EVEX_MAP4_DD_PREFIX_1 */
> > +  {
> > +    { "aesdec128kl",    { XM, M }, 0 },
> > +  },
> > +  /* MOD_EVEX_MAP4_DE_PREFIX_1 */
> > +  {
> > +    { "aesenc256kl",    { XM, M }, 0 },
> > +  },
> > +  /* MOD_EVEX_MAP4_DF_PREFIX_1 */
> > +  {
> > +    { "aesdec256kl",    { XM, M }, 0 },
> > +  },
> > +  /* MOD_EVEX_MAP4_F8_PREFIX_1 */
> > +  {
> > +    { "enqcmds",	{ Gva, M },  0 },
> > +  },
> > +  /* MOD_EVEX_MAP4_F8_PREFIX_2 */
> > +  {
> > +    { "movdir64b",	{ Gva, M }, 0 },
> > +  },
> > +  /* MOD_EVEX_MAP4_F8_PREFIX_3 */
> > +  {
> > +    { "enqcmd",		{ Gva, M }, 0 },
> > +  },
> 
> ... M in many entries anyway. These can move one level up without needing
> further adjustment.

Done.

> +  /* PREFIX_EVEX_MAP4_F8 */
> +  {
> +    { Bad_Opcode },
> +    { MOD_TABLE (MOD_EVEX_MAP4_F8_PREFIX_1) },
> +    { MOD_TABLE (MOD_EVEX_MAP4_F8_PREFIX_2) },
> +    { MOD_TABLE (MOD_EVEX_MAP4_F8_PREFIX_3) },  },
> +  /* PREFIX_EVEX_MAP4_FC */
> +  {
> +    { "aadd",	{ Mdq, Gdq }, 0 },
> +    { "axor",	{ Mdq, Gdq }, 0 },
> +    { "aand",	{ Mdq, Gdq }, 0 },
> +    { "aor",	{ Mdq, Gdq }, 0 },
> +  },

>This looks to match the PREFIX_0F38FC entry.

Done.

> > --- a/opcodes/i386-dis-evex-reg.h
> > +++ b/opcodes/i386-dis-evex-reg.h
> > @@ -49,3 +49,17 @@
> >      { "vscatterpf0qp%XW",  { MVexVSIBQWpX }, PREFIX_DATA },
> >      { "vscatterpf1qp%XW",  { MVexVSIBQWpX }, PREFIX_DATA },
> >    },
> > +  /* REG_EVEX_0F38F3_L_0 */
> > +  {
> > +    { Bad_Opcode },
> > +    { "blsrS",		{ VexGdq, Edq }, 0 },
> > +    { "blsmskS",	{ VexGdq, Edq }, 0 },
> > +    { "blsiS",		{ VexGdq, Edq }, 0 },
> > +  },
> 
> Compared to the REG_VEX_0F38F3_L_0 entry this lacks PREFIX_OPCODE, but
> then the question is why you do not re-use that entry in the first place.
> 

Added PREFIX_TABLE for them.

> > +  /* REG_EVEX_MAP4_D8_PREFIX_1 */
> > +  {
> > +    { "aesencwide128kl",	{ M }, 0 },
> > +    { "aesdecwide128kl",	{ M }, 0 },
> > +    { "aesencwide256kl",	{ M }, 0 },
> > +    { "aesdecwide256kl",	{ M }, 0 },
> > +  },
> 
> How is this different from the REG_0F38D8_PREFIX_1 entry?
> 

They are same, deleted REG_EVEX_MAP4_D8_PREFIX_1 and share REG_0F38D8_PREFIX_1.

> > --- /dev/null
> > +++ b/opcodes/i386-dis-evex-x86-64.h
> > @@ -0,0 +1,140 @@
> > +  /* X86_64_EVEX_0F3849 */
> > +  {
> > +    { Bad_Opcode },
> > +    { VEX_LEN_TABLE (VEX_LEN_0F3849_X86_64) },  },
> > +  /* X86_64_EVEX_0F384B */
> > +  {
> > +    { Bad_Opcode },
> > +    { VEX_LEN_TABLE (VEX_LEN_0F384B_X86_64) },  },
> > +  /* X86_64_EVEX_0F38E0 */
> > +  {
> > +    { Bad_Opcode },
> > +    { "cmpoxadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA },  },
> 
> This and its sibling entries look to again fully match X86_64_VEX_0F38E<n>.

It cannot be moved to up level, it needs to go through i386-dis-evex-x86-64.h

> > --- a/opcodes/i386-dis-evex.h
> > +++ b/opcodes/i386-dis-evex.h
> >[...]
> > @@ -1113,19 +1113,19 @@ static const struct dis386 evex_table[][256] = {
> >      { Bad_Opcode },
> >      { Bad_Opcode },
> >      { Bad_Opcode },
> > -    { Bad_Opcode },
> > +    { "sha1rnds4", { XM, EXxmm, Ib }, 0 },
> 
> PREFIX_OPCODE? EVEX.W?
> 

Added PREFIX_TABLE , I think this instruction doesn't need to go through W_TABLE.

EVEX.LLZ.NP.MAP4. D4 /r ib
SHA1RNDS4 {NF=0} {ND=0} xmm1, xmm2/m128, imm8

> >      { Bad_Opcode },
> >      { Bad_Opcode },
> >      { Bad_Opcode },
> >      /* D8 */
> > -    { Bad_Opcode },
> > -    { Bad_Opcode },
> > -    { Bad_Opcode },
> > -    { Bad_Opcode },
> > -    { Bad_Opcode },
> > -    { Bad_Opcode },
> > -    { Bad_Opcode },
> > -    { Bad_Opcode },
> > +    { PREFIX_TABLE (PREFIX_EVEX_MAP4_D8) },
> > +    { "sha1msg1", { XM, EXxmm }, 0 },
> 
> Again.
> 

Done.

> > --- a/opcodes/i386-dis.c
> > +++ b/opcodes/i386-dis.c
> >[...]
> > @@ -4522,12 +4594,13 @@ static const struct dis386 x86_64_table[][2] = {
> >      { "cmpnlexadd", { Mdq, Gdq, VexGdq }, PREFIX_DATA },
> >    },
> >
> > +#include "i386-dis-evex-x86-64.h"
> > +
> >    /* X86_64_VEX_MAP7_F8_L_0_W_0_R_0 */
> >    {
> >      { Bad_Opcode },
> >      { PREFIX_TABLE (PREFIX_VEX_MAP7_F8_L_0_W_0_R_0_X86_64) },
> >    },
> > -
> >  };
> 
> Please can EVEX entries come after VEX ones?
> 

Done.

> > @@ -8979,9 +9055,13 @@ get_valid_dis386 (const struct dis386 *dp,
> instr_info *ins)
> >        if (!fetch_code (ins->info, ins->codep + 4))
> >  	return &err_opcode;
> >        /* The first byte after 0x62.  */
> > +      if (*ins->codep & 0x8)
> > +	ins->rex2 |= REX_B;
> > +      if (!(*ins->codep & 0x10))
> > +	ins->rex2 |= REX_R;
> 
> In patch 1 you check whether REX2 bits are properly consumed. While in
> principle I agree with re-using ->rex2 here, don't you need to take precautions
> to not print a random {rex2} (or whichever way it was
> expressed) when one of these bits ends up not contributing to any operand?
> 

We have discussed this issue in other email.

> > @@ -8994,12 +9074,19 @@ get_valid_dis386 (const struct dis386 *dp,
> instr_info *ins)
> >  	case 0x3:
> >  	  vex_table_index = EVEX_0F3A;
> >  	  break;
> > +	case 0x4:
> > +	  vex_table_index = EVEX_MAP4;
> > +	  ins->evex_type = evex_from_legacy;
> > +	  break;
> >  	case 0x5:
> >  	  vex_table_index = EVEX_MAP5;
> >  	  break;
> >  	case 0x6:
> >  	  vex_table_index = EVEX_MAP6;
> >  	  break;
> > +	case 0x7:
> > +	  vex_table_index = EVEX_MAP7;
> > +	  break;
> >  	}
> 
> How is map7 coming into play here?
> 

Removed.

> > @@ -9042,12 +9128,31 @@ get_valid_dis386 (const struct dis386 *dp,
> > instr_info *ins)
> >
> >        if (ins->address_mode != mode_64bit)
> >  	{
> > +	  if (ins->evex_type != evex_default
> > +	      || (ins->rex2 & (REX_B | REX_X)))
> > +	    return &bad_opcode;
> >  	  /* In 16/32-bit mode silently ignore following bits.  */
> >  	  ins->rex &= ~REX_B;
> > -	  ins->vex.r = true;
> > +	  ins->rex2 &= ~REX_R;
> >  	}
> >
> >        ins->need_vex = 4;
> > +
> > +      /* EVEX from legacy instructions require that EVEX.L'L, EVEX.z and the
> > +	 lower 2 bits of EVEX.aaa must be 0.
> > +	 EVEX from evex instrucions require that EVEX.L'L and the lower 2 bits
> of
> > +	 EVEX.aaa must be 0.  */
> 
> EVEX from VEX you mean? Also, what about EVEX.z for those? Really the sole
> difference between the two forms is EVEX.nd. The doc mentions EVEX.l for
> the from-VEX case, but afaics there's no insn actually having that bit set
> (which also matches what you say above).
> 

EVEX.z  is "ins->vex.zeroing = *ins->codep & 0x80;" The old code was wrong , changed it to:

     case USE_X86_64_EVEX_FROM_VEX_TABLE:
       ins->evex_type = evex_from_vex;
+      /* EVEX from evex instrucions require that EVEX.z, EVEX.L’L, EVEX.b and
+        the lower 2 bits of EVEX.aaa must be 0.  */
+      if ((ins->vex.mask_register_specifier & 0x3) != 0
+         || ins->vex.ll != 0
+         || ins->vex.zeroing != 0
+         || ins->vex.b)
+       return &bad_opcode;

     case USE_EVEX_TABLE:
+      /* EVEX from legacy instructions require that EVEX.z, EVEX.L’L and the
+        lower 2 bits of EVEX.aaa must be 0.  */
+      if (ins->evex_type == evex_from_legacy
+         && ((ins->vex.mask_register_specifier & 0x3) != 0
+             || ins->vex.ll != 0
+             || ins->vex.zeroing != 0))
+       return &bad_opcode;


> > +      if (ins->evex_type == evex_from_legacy || ins->evex_type ==
> evex_from_vex)
> > +	{
> > +	  if ((*ins->codep & 0x3) != 0
> > +	      || (*ins->codep >> 6 & 0x3) != 0
> > +	      || (ins->evex_type == evex_from_legacy
> > +		  && (*ins->codep >> 5 & 0x1) != 0)
> 
> Please can the shifts be parenthesized agaist the &-s? Albeit - this is perhaps
> easier to read as just &-s anyway.
> 

 Code changed.

> > +	      || (ins->evex_type == evex_from_vex
> > +		  && !ins->vex.b))
> 
> This doesn't look to match any part of the comment.
> 

Code changed and added a test case for it.

> > @@ -9640,6 +9752,19 @@ print_insn (bfd_vma pc, disassemble_info *info,
> int intel_syntax)
> >        if (ins.last_repnz_prefix >= 0)
> >  	ins.all_prefixes[ins.last_repnz_prefix] = 0xf2;
> >        break;
> > +
> > +    case PREFIX_NP_OR_DATA:
> > +      if (ins.vex.prefix & ~DATA_PREFIX_OPCODE)
> > +	{
> > +	  i386_dis_printf (info, dis_style_text, "(bad)");
> > +	  ret = ins.end_codep - priv.the_buffer;
> > +	  goto out;
> > +	}
> > +      break;
> > +
> > +    default:
> > +      break;
> > +
> >      }
> 
> Why suddenly a default case? And why an extra blank line below it?
> 

Removed.

> > @@ -11242,7 +11367,7 @@ print_register (instr_info *ins, unsigned int reg,
> unsigned int rexmask,
           case b_mode:
> >      case b_swap_mode:
> >        if (reg & 4)
> >  	USED_REX (0);
> > -      if (ins->rex)
> > +      if (ins->rex || ins->rex2)
> >  	names = att_names8rex;
> >        else
> >  	names = att_names8;
> 
> Isn't this already needed in the REX2 patch?
> 

CRC32  --> Eb ---> b_mode

> > @@ -11460,7 +11585,7 @@ OP_E_memory (instr_info *ins, int bytemode,
> > int sizeflag)
> >
> >    add += (ins->rex2 & REX_B) ? 16 : 0;
> >
> > -  if (ins->vex.evex)
> > +  if (ins->vex.evex && ins->evex_type == evex_default)
> >      {
> >
> >        /* Zeroing-masking is invalid for memory destinations. Set the
> > flag @@ -11608,6 +11733,13 @@ OP_E_memory (instr_info *ins, int
> bytemode, int sizeflag)
> >  		abort ();
> >  	      if (ins->vex.evex)
> >  		{
> > +		  /* S/G EVEX insns require REX_X not to be set.  */
> > +		  if (ins->rex2 & REX_X)
> 
> REX_X in a comment can only mean REX.X. You mean EVEX.X4 though, I think
> (which internally is latched into the REX_X bit of ->rex2), and that also needs
> to be set, not clear.
> 
Done.

Thanks,
Lili.

  parent reply	other threads:[~2023-11-15  6:04 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-03 16:50 Cui, Lili
2023-11-06 17:07 ` Jan Beulich
2023-11-13  5:53   ` Cui, Lili
2023-11-13  8:34     ` Jan Beulich
2023-11-14  3:12       ` Cui, Lili
2023-11-14 10:29         ` Jan Beulich
2023-11-15  8:39           ` Cui, Lili
2023-11-07 13:29 ` Jan Beulich
2023-11-09  8:38   ` Cui, Lili
2023-11-09 11:07     ` Jan Beulich
2023-11-09 11:12     ` Jan Beulich
2023-11-07 14:53 ` Jan Beulich
2023-11-09 12:31   ` Cui, Lili
2023-11-09 13:05     ` Jan Beulich
2023-11-09 14:57       ` Cui, Lili
2023-11-09 15:39         ` Jan Beulich
2023-11-14  7:42   ` Cui, Lili
2023-11-14 10:40     ` Jan Beulich
2023-11-14 14:46       ` Cui, Lili
2023-11-15  6:03   ` Cui, Lili [this message]
2023-11-15  9:11     ` Jan Beulich
2023-11-15 11:43       ` Cui, Lili
2023-11-16 13:57         ` Jan Beulich
2023-11-16 15:10           ` Cui, Lili
2023-11-16 15:15             ` Jan Beulich
2023-11-16 16:12           ` Cui, Lili

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=SJ0PR11MB56004596A199CCE5E6E7768E9EB1A@SJ0PR11MB5600.namprd11.prod.outlook.com \
    --to=lili.cui@intel.com \
    --cc=JBeulich@suse.com \
    --cc=binutils@sourceware.org \
    --cc=hongjiu.lu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).