public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Jan Beulich <jbeulich@suse.com>
To: Binutils <binutils@sourceware.org>
Cc: "H.J. Lu" <hjl.tools@gmail.com>,
	"Jiang, Haochen" <haochen.jiang@intel.com>
Subject: [PATCH v2 08/14] x86: process instruction operands for .insn
Date: Fri, 10 Mar 2023 11:23:40 +0100	[thread overview]
Message-ID: <8d917f97-af55-11f3-a9f8-d5a209725336@suse.com> (raw)
In-Reply-To: <b3625235-faf6-00ad-69c2-82583531fe43@suse.com>

Deal with register and memory operands; immediate operands will follow
later, as will the handling of EVEX embedded broadcast and EVEX Disp8
scaling.

Note that because we can't really know how to encode their use, %cr8 and
up cannot be used with .insn outside of 64-bit mode. Users would need to
specify an explicit LOCK prefix in combination with %cr0 etc.
---
I'm not convinced the assertions early in build_modrm_byte() are useful
to retain.
---
v2: Re-base over patch which was pulled ahead.

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -2356,7 +2356,8 @@ fits_in_disp8 (offsetT num)
 static INLINE int
 fits_in_imm4 (offsetT num)
 {
-  return (num & 0xf) == num;
+  /* Despite the name, check for imm3 if we're dealing with EVEX.  */
+  return (num & (i.vec_encoding != vex_encoding_evex ? 0xf : 7)) == num;
 }
 
 static i386_operand_type
@@ -8228,7 +8229,7 @@ process_operands (void)
 	    }
 	}
     }
-  else if (i.types[0].bitfield.class == SReg)
+  else if (i.types[0].bitfield.class == SReg && !dot_insn ())
     {
       if (flag_code != CODE_64BIT
 	  ? i.tm.base_opcode == POP_SEG_SHORT
@@ -8261,15 +8262,32 @@ process_operands (void)
     }
   else if (i.short_form)
     {
-      /* The register operand is in operand 0 or 1.  */
-      const reg_entry *r = i.op[0].regs;
+      /* The register operand is in the 1st or 2nd non-immediate operand.  */
+      const reg_entry *r = i.op[i.imm_operands].regs;
 
-      if (i.imm_operands
-	  || (r->reg_type.bitfield.instance == Accum && i.op[1].regs))
-	r = i.op[1].regs;
+      if (!dot_insn ()
+	  && r->reg_type.bitfield.instance == Accum
+	  && i.op[i.imm_operands + 1].regs)
+	r = i.op[i.imm_operands + 1].regs;
       /* Register goes in low 3 bits of opcode.  */
       i.tm.base_opcode |= r->reg_num;
       set_rex_vrex (r, REX_B, false);
+
+      if (dot_insn () && i.reg_operands == 2)
+	{
+	  gas_assert (is_any_vex_encoding (&i.tm)
+		      || i.vec_encoding != vex_encoding_default);
+	  i.vex.register_specifier = i.op[i.operands - 1].regs;
+	}
+    }
+  else if (i.reg_operands == 1
+	   && !i.flags[i.operands - 1]
+	   && i.tm.operand_types[i.operands - 1].bitfield.instance
+	      == InstanceNone)
+    {
+      gas_assert (is_any_vex_encoding (&i.tm)
+		  || i.vec_encoding != vex_encoding_default);
+      i.vex.register_specifier = i.op[i.operands - 1].regs;
     }
 
   if ((i.seg[0] || i.prefix[SEG_PREFIX])
@@ -8330,10 +8348,12 @@ build_modrm_byte (void)
 	 VexW0 or VexW1.  The destination must be either XMM, YMM or
 	 ZMM register.
 	 2. 4 operands: 4 register operands or 3 register operands
-	 plus 1 memory operand, with VexXDS.  */
+	 plus 1 memory operand, with VexXDS.
+	 3. Other equivalent combinations when coming from s_insn().  */
       gas_assert (i.tm.opcode_modifier.vexvvvv
-		  && i.tm.opcode_modifier.vexw
-		  && i.tm.operand_types[dest].bitfield.class == RegSIMD);
+		  && i.tm.opcode_modifier.vexw);
+      gas_assert (dot_insn ()
+		  || i.tm.operand_types[dest].bitfield.class == RegSIMD);
 
       /* Of the first two non-immediate operands the one with the template
 	 not allowing for a memory one is encoded in the immediate operand.  */
@@ -8342,6 +8362,14 @@ build_modrm_byte (void)
       else
 	reg_slot = source++;
 
+      if (!dot_insn ())
+	{
+	  gas_assert (i.tm.operand_types[reg_slot].bitfield.class == RegSIMD);
+	  gas_assert (!(i.op[reg_slot].regs->reg_flags & RegVRex));
+	}
+      else
+	gas_assert (i.tm.operand_types[reg_slot].bitfield.class != ClassNone);
+
       if (i.imm_operands == 0)
 	{
 	  /* When there is no immediate operand, generate an 8bit
@@ -8351,10 +8379,7 @@ build_modrm_byte (void)
 	  i.types[i.operands].bitfield.imm8 = 1;
 	  i.operands++;
 
-	  gas_assert (i.tm.operand_types[reg_slot].bitfield.class == RegSIMD);
 	  exp->X_op = O_constant;
-	  exp->X_add_number = register_number (i.op[reg_slot].regs) << 4;
-	  gas_assert ((i.op[reg_slot].regs->reg_flags & RegVRex) == 0);
 	}
       else
 	{
@@ -8365,11 +8390,11 @@ build_modrm_byte (void)
 	  /* Turn on Imm8 again so that output_imm will generate it.  */
 	  i.types[0].bitfield.imm8 = 1;
 
-	  gas_assert (i.tm.operand_types[reg_slot].bitfield.class == RegSIMD);
-	  i.op[0].imms->X_add_number
-	      |= register_number (i.op[reg_slot].regs) << 4;
-	  gas_assert ((i.op[reg_slot].regs->reg_flags & RegVRex) == 0);
+	  exp = i.op[0].imms;
 	}
+      exp->X_add_number |= register_number (i.op[reg_slot].regs)
+			   << (3 + !(is_evex_encoding (&i.tm)
+				     || i.vec_encoding == vex_encoding_evex));
     }
 
   for (v = source + 1; v < dest; ++v)
@@ -10634,6 +10659,9 @@ s_insn (int dummy ATTRIBUTE_UNUSED)
       goto bad;
     }
 
+  if (line > end && i.vec_encoding == vex_encoding_default)
+    i.vec_encoding = evex ? vex_encoding_evex : vex_encoding_vex;
+
   if (line > end && *line == '.')
     {
       /* Length specifier (VEX.L, XOP.L, EVEX.L'L).  */
@@ -10913,7 +10941,244 @@ s_insn (int dummy ATTRIBUTE_UNUSED)
       goto bad;
     }
   i.opcode_length = j;
-  i.tm.base_opcode = val;
+
+  /* Handle operands, if any.  */
+  if (*line == ',')
+    {
+      i386_operand_type combined;
+      bool changed;
+
+      ptr = parse_operands (line + 1, &i386_mnemonics[MN__insn]);
+      this_operand = -1;
+      if (!ptr)
+	goto bad;
+      line = ptr;
+
+      if (!i.operands)
+	{
+	  as_bad (_("expecting operand after ','; got nothing"));
+	  goto done;
+	}
+
+      if (i.mem_operands > 1)
+	{
+	  as_bad (_("too many memory references for `%s'"),
+		  &i386_mnemonics[MN__insn]);
+	  goto done;
+	}
+
+      /* Are we to emit ModR/M encoding?  */
+      if (!i.short_form
+	  && (i.mem_operands
+	      || i.reg_operands > (i.vec_encoding != vex_encoding_default)
+	      || i.tm.extension_opcode != None))
+	i.tm.opcode_modifier.modrm = 1;
+
+      if (!i.tm.opcode_modifier.modrm
+	  && (i.reg_operands
+	      > i.short_form + 0U + (i.vec_encoding != vex_encoding_default)
+	      || i.mem_operands))
+	{
+	  as_bad (_("too many register/memory operands"));
+	  goto done;
+	}
+
+      /* Enforce certain constraints on operands.  */
+      switch (i.reg_operands + i.mem_operands
+	      + (i.tm.extension_opcode != None))
+	{
+	case 0:
+	  if (i.short_form)
+	    {
+	      as_bad (_("too few register/memory operands"));
+	      goto done;
+	    }
+	  /* Fall through.  */
+	case 1:
+	  if (i.tm.opcode_modifier.modrm)
+	    {
+	      as_bad (_("too few register/memory operands"));
+	      goto done;
+	    }
+	  break;
+
+	case 2:
+	  break;
+
+	case 4:
+	  if (i.imm_operands
+	      && (i.op[0].imms->X_op != O_constant
+		  || !fits_in_imm4 (i.op[0].imms->X_add_number)))
+	    {
+	      as_bad (_("constant doesn't fit in %d bits"), evex ? 3 : 4);
+	      goto done;
+	    }
+	  /* Fall through.  */
+	case 3:
+	  if (i.vec_encoding != vex_encoding_default)
+	    {
+	      i.tm.opcode_modifier.vexvvvv = 1;
+	      break;
+	    }
+	  /* Fall through.  */
+	default:
+	  as_bad (_("too many register/memory operands"));
+	  goto done;
+	}
+
+      /* Bring operands into canonical order (imm, mem, reg).  */
+      do
+	{
+	  changed = false;
+
+	  for (j = 1; j < i.operands; ++j)
+	    {
+	      if ((!operand_type_check (i.types[j - 1], imm)
+		   && operand_type_check (i.types[j], imm))
+		  || (i.types[j - 1].bitfield.class != ClassNone
+		      && i.types[j].bitfield.class == ClassNone))
+		{
+		  swap_2_operands (j - 1, j);
+		  changed = true;
+		}
+	    }
+	}
+      while (changed);
+
+      /* For Intel syntax swap the order of register operands.  */
+      if (intel_syntax)
+	switch (i.reg_operands)
+	  {
+	  case 0:
+	  case 1:
+	    break;
+
+	  case 4:
+	    swap_2_operands (i.imm_operands + i.mem_operands + 1, i.operands - 2);
+	    /* Fall through.  */
+	  case 3:
+	  case 2:
+	    swap_2_operands (i.imm_operands + i.mem_operands, i.operands - 1);
+	    break;
+
+	  default:
+	    abort ();
+	  }
+
+      /* Enforce constraints when using VSIB.  */
+      if (i.index_reg
+	  && (i.index_reg->reg_type.bitfield.xmmword
+	      || i.index_reg->reg_type.bitfield.ymmword
+	      || i.index_reg->reg_type.bitfield.zmmword))
+	{
+	  if (i.vec_encoding == vex_encoding_default)
+	    {
+	      as_bad (_("VSIB unavailable with legacy encoding"));
+	      goto done;
+	    }
+
+	  if (i.vec_encoding == vex_encoding_evex
+	      && i.reg_operands > 1)
+	    {
+	      /* We could allow two register operands, encoding the 2nd one in
+		 an 8-bit immediate like for 4-register-operand insns, but that
+		 would require ugly fiddling with process_operands() and/or
+		 build_modrm_byte().  */
+	      as_bad (_("too many register operands with VSIB"));
+	      goto done;
+	    }
+
+	  i.tm.opcode_modifier.sib = 1;
+	}
+
+      /* Establish operand size encoding.  */
+      operand_type_set (&combined, 0);
+      for (j = i.imm_operands; j < i.operands; ++j)
+	{
+	  i.types[j].bitfield.instance = InstanceNone;
+
+	  if (operand_type_check (i.types[j], disp))
+	    i.types[j].bitfield.baseindex = 1;
+
+	  if ((i.broadcast.type || i.broadcast.bytes)
+	      && j == i.broadcast.operand)
+	    continue;
+
+	  combined = operand_type_or (combined, i.types[j]);
+	  combined.bitfield.class = ClassNone;
+	}
+
+      if (i.vec_encoding == vex_encoding_default)
+	{
+	  if (flag_code == CODE_64BIT && combined.bitfield.qword)
+	    i.rex |= REX_W;
+	  else if ((flag_code == CODE_16BIT ? combined.bitfield.dword
+					    : combined.bitfield.word)
+	           && !add_prefix (DATA_PREFIX_OPCODE))
+	    goto done;
+	}
+      else if (!i.tm.opcode_modifier.vexw)
+	{
+	  if (flag_code == CODE_64BIT)
+	    {
+	      if (combined.bitfield.qword)
+	        i.tm.opcode_modifier.vexw = VEXW1;
+	      else if (combined.bitfield.dword)
+	        i.tm.opcode_modifier.vexw = VEXW0;
+	    }
+
+	  if (!i.tm.opcode_modifier.vexw)
+	    i.tm.opcode_modifier.vexw = VEXWIG;
+	}
+
+      if (vex || xop)
+	{
+	  if (!i.tm.opcode_modifier.vex)
+	    {
+	      if (combined.bitfield.ymmword)
+	        i.tm.opcode_modifier.vex = VEX256;
+	      else if (combined.bitfield.xmmword)
+	        i.tm.opcode_modifier.vex = VEX128;
+	    }
+	}
+      else if (evex)
+	{
+	  if (!i.tm.opcode_modifier.evex)
+	    {
+	      /* Do _not_ consider AVX512VL here.  */
+	      if (i.rounding.type != rc_none || combined.bitfield.zmmword)
+	        i.tm.opcode_modifier.evex = EVEX512;
+	      else if (combined.bitfield.ymmword)
+	        i.tm.opcode_modifier.evex = EVEX256;
+	      else if (combined.bitfield.xmmword)
+	        i.tm.opcode_modifier.evex = EVEX128;
+	    }
+	}
+
+      if (i.disp_operands && !optimize_disp (&i.tm))
+	goto done;
+
+      for (j = 0; j < i.operands; ++j)
+	i.tm.operand_types[j] = i.types[j];
+
+      process_operands ();
+    }
+
+  /* Don't set opcode until after processing operands, to avoid any
+     potential special casing there.  */
+  i.tm.base_opcode |= val;
+
+  if (i.vec_encoding == vex_encoding_error
+      || (i.vec_encoding != vex_encoding_evex
+	  ? i.broadcast.type || i.broadcast.bytes
+	    || i.rounding.type != rc_none
+	    || i.mask.reg
+	  : (i.broadcast.type || i.broadcast.bytes)
+	    && i.rounding.type != rc_none))
+    {
+      as_bad (_("conflicting .insn operands"));
+      goto done;
+    }
 
   if (vex || xop)
     {
@@ -10931,6 +11196,8 @@ s_insn (int dummy ATTRIBUTE_UNUSED)
       build_evex_prefix ();
       i.rex &= REX_OPCODE;
     }
+  else if (i.rex != 0)
+    add_prefix (REX_OPCODE | i.rex);
 
   output_insn ();
 
@@ -11899,6 +12166,15 @@ i386_att_operand (char *operand_string)
 	  as_bad (_("junk `%s' after register"), op_string);
 	  return 0;
 	}
+
+       /* Reject pseudo registers for .insn.  */
+      if (dot_insn () && r->reg_type.bitfield.class == ClassNone)
+	{
+	  as_bad (_("`%s%s' cannot be used here"),
+		  register_prefix, r->reg_name);
+	  return 0;
+	}
+
       temp = r->reg_type;
       temp.bitfield.baseindex = 0;
       i.types[this_operand] = operand_type_or (i.types[this_operand],
@@ -13274,7 +13550,9 @@ static bool check_register (const reg_en
     }
 
   if (((r->reg_flags & (RegRex64 | RegRex)) || r->reg_type.bitfield.qword)
-      && (!cpu_arch_flags.bitfield.cpulm || r->reg_type.bitfield.class != RegCR)
+      && (!cpu_arch_flags.bitfield.cpulm
+	  || r->reg_type.bitfield.class != RegCR
+	  || dot_insn ())
       && flag_code != CODE_64BIT)
     return false;
 
--- a/gas/config/tc-i386-intel.c
+++ b/gas/config/tc-i386-intel.c
@@ -320,8 +320,10 @@ i386_intel_simplify_register (expression
 	  as_bad (_("invalid use of register"));
 	  return 0;
 	}
-      if (i386_regtab[reg_num].reg_type.bitfield.class == SReg
-	  && i386_regtab[reg_num].reg_num == RegFlat)
+      if ((i386_regtab[reg_num].reg_type.bitfield.class == SReg
+	   && i386_regtab[reg_num].reg_num == RegFlat)
+	  || (dot_insn ()
+	      && i386_regtab[reg_num].reg_type.bitfield.class == ClassNone))
 	{
 	  as_bad (_("invalid use of pseudo-register"));
 	  return 0;
@@ -342,6 +344,7 @@ i386_intel_simplify_register (expression
 
       if (intel_state.in_scale
 	  || i386_regtab[reg_num].reg_type.bitfield.baseindex
+	  || dot_insn ()
 	  || t->mnem_off == MN_bndmk
 	  || t->mnem_off == MN_bndldx
 	  || t->mnem_off == MN_bndstx)
--- a/gas/testsuite/gas/i386/insn-32.d
+++ b/gas/testsuite/gas/i386/insn-32.d
@@ -11,6 +11,24 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	f3 90[ 	]+pause
 [ 	]*[a-f0-9]+:	d9 ee[ 	]+fldz
 [ 	]*[a-f0-9]+:	f3 0f 01 e8[ 	]+setssbsy
+[ 	]*[a-f0-9]+:	8b c1[ 	]+mov    %ecx,%eax
+[ 	]*[a-f0-9]+:	66 8b c8[ 	]+mov    %ax,%cx
+[ 	]*[a-f0-9]+:	89 48 04[ 	]+mov    %ecx,0x4\(%eax\)
+[ 	]*[a-f0-9]+:	8b 0c 05 44 44 00 00[ 	]+mov    0x4444\(,%eax,1\),%ecx
+[ 	]*[a-f0-9]+:	66 0f b6 cc[ 	]+movzbw %ah,%cx
+[ 	]*[a-f0-9]+:	0f b7 c8[ 	]+movzwl %ax,%ecx
+[ 	]*[a-f0-9]+:	0f ca[ 	]+bswap  %edx
 [ 	]*[a-f0-9]+:	c5 fc 77[ 	]+vzeroall
 [ 	]*[a-f0-9]+:	c4 e1 7c 77[ 	]+vzeroall
+[ 	]*[a-f0-9]+:	c5 f1 58 d0[ 	]+vaddpd %xmm0,%xmm1,%xmm2
+[ 	]*[a-f0-9]+:	c5 f5 58 d0[ 	]+vaddpd %ymm0,%ymm1,%ymm2
+[ 	]*[a-f0-9]+:	c5 f2 58 d0[ 	]+vaddss %xmm0,%xmm1,%xmm2
+[ 	]*[a-f0-9]+:	c4 e3 69 68 19 00[ 	]+vfmaddps %xmm0,\(%ecx\),%xmm2,%xmm3
+[ 	]*[a-f0-9]+:	c4 e3 e9 68 19 00[ 	]+vfmaddps \(%ecx\),%xmm0,%xmm2,%xmm3
+[ 	]*[a-f0-9]+:	c4 e3 e9 68 18 10[ 	]+vfmaddps \(%eax\),%xmm1,%xmm2,%xmm3
+[ 	]*[a-f0-9]+:	c5 f8 92 c8[ 	]+kmovw  %eax,%k1
+[ 	]*[a-f0-9]+:	c5 f8 93 c1[ 	]+kmovw  %k1,%eax
+[ 	]*[a-f0-9]+:	62 f1 74 18 58 d0[ 	]+vaddps \{rn-sae\},%zmm0,%zmm1,%zmm2
+[ 	]*[a-f0-9]+:	c4 e2 79 92 1c 48[ 	]+vgatherdps %xmm0,\(%eax,%xmm1,2\),%xmm3
+[ 	]*[a-f0-9]+:	62 f2 fd 0c 93 1c 48[ 	]+vgatherqpd \(%eax,%xmm1,2\),%xmm3\{%k4\}
 #pass
--- a/gas/testsuite/gas/i386/insn-32.s
+++ b/gas/testsuite/gas/i386/insn-32.s
@@ -13,6 +13,42 @@ insn:
 	# setssbsy
 	.insn 0xf30f01e8
 
+	# mov
+	.insn 0x8b, %ecx, %eax
+	.insn 0x8b, %ax, %cx
+	.insn 0x89, %ecx, 4(%eax)
+	.insn 0x8b, 0x4444(,%eax), %ecx
+
+	# movzx
+	.insn 0x0fb6, %ah, %cx
+	.insn 0x0fb7, %eax, %ecx
+
+	# bswap
+	.insn 0x0fc8+r, %edx
+
 	# vzeroall
 	.insn VEX.256.0F.WIG 0x77
 	.insn {vex3} VEX.L1 0x0f77
+
+	# vaddpd
+	.insn VEX.66.0F 0x58, %xmm0, %xmm1, %xmm2
+	.insn VEX.66 0x0f58, %ymm0, %ymm1, %ymm2
+
+	# vaddss
+	.insn VEX.LIG.F3.0F 0x58, %xmm0, %xmm1, %xmm2
+
+	# vfmaddps
+	.insn VEX.66.0F3A.W0 0x68, %xmm0, (%ecx), %xmm2, %xmm3
+	.insn VEX.66.0F3A.W1 0x68, %xmm0, (%ecx), %xmm2, %xmm3
+	.insn VEX.66.0F3A.W1 0x68, (%eax), %xmm1, %xmm2, %xmm3
+
+	# kmovw
+	.insn VEX.L0.0F.W0 0x92, %eax, %k1
+	.insn VEX.L0.0F.W0 0x93, %k1, %eax
+
+	# vaddps
+	.insn EVEX.NP.0F.W0 0x58, {rn-sae}, %zmm0, %zmm1, %zmm2
+
+	# vgather...
+	.insn VEX.66.0f38.W0 0x92, %xmm0, (%eax, %xmm1, 2), %xmm3
+	.insn EVEX.66.0f38.W1 0x93, (%eax, %xmm1, 2), %xmm3{%k4}
--- a/gas/testsuite/gas/i386/insn-64.d
+++ b/gas/testsuite/gas/i386/insn-64.d
@@ -11,6 +11,35 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	f3 90[ 	]+pause
 [ 	]*[a-f0-9]+:	d9 ee[ 	]+fldz
 [ 	]*[a-f0-9]+:	f3 0f 01 e8[ 	]+setssbsy
+[ 	]*[a-f0-9]+:	44 8b c1[ 	]+mov    %ecx,%r8d
+[ 	]*[a-f0-9]+:	48 8b c8[ 	]+mov    %rax,%rcx
+[ 	]*[a-f0-9]+:	41 89 48 08[ 	]+mov    %ecx,0x8\(%r8\)
+[ 	]*[a-f0-9]+:	42 8b 0c 05 80 80 00 00[ 	]+mov    0x8080\(,%r8,1\),%ecx
+[ 	]*[a-f0-9]+:	66 0f be cc[ 	]+movsbw %ah,%cx
+[ 	]*[a-f0-9]+:	0f bf c8[ 	]+movswl %ax,%ecx
+[ 	]*[a-f0-9]+:	48 63 c8[ 	]+movslq %eax,%rcx
+[ 	]*[a-f0-9]+:	48 0f ca[ 	]+bswap  %rdx
+[ 	]*[a-f0-9]+:	41 0f c8[ 	]+bswap  %r8d
 [ 	]*[a-f0-9]+:	c5 fc 77[ 	]+vzeroall
 [ 	]*[a-f0-9]+:	c4 e1 7c 77[ 	]+vzeroall
+[ 	]*[a-f0-9]+:	c4 c1 71 58 d0[ 	]+vaddpd %xmm8,%xmm1,%xmm2
+[ 	]*[a-f0-9]+:	c5 b5 58 d0[ 	]+vaddpd %ymm0,%ymm9,%ymm2
+[ 	]*[a-f0-9]+:	c5 72 58 d0[ 	]+vaddss %xmm0,%xmm1,%xmm10
+[ 	]*[a-f0-9]+:	c4 e3 69 68 19 80[ 	]+vfmaddps %xmm8,\(%rcx\),%xmm2,%xmm3
+[ 	]*[a-f0-9]+:	67 c4 e3 e9 68 19 00[ 	]+vfmaddps \(%ecx\),%xmm0,%xmm2,%xmm3
+[ 	]*[a-f0-9]+:	c4 c3 e9 68 18 10[ 	]+vfmaddps \(%r8\),%xmm1,%xmm2,%xmm3
+[ 	]*[a-f0-9]+:	c4 c1 78 92 c8[ 	]+kmovw  %r8d,%k1
+[ 	]*[a-f0-9]+:	c5 78 93 c1[ 	]+kmovw  %k1,%r8d
+[ 	]*[a-f0-9]+:	62 b1 74 38 58 d0[ 	]+vaddps \{rd-sae\},%zmm16,%zmm1,%zmm2
+[ 	]*[a-f0-9]+:	62 f1 74 10 58 d0[ 	]+vaddps \{rn-sae\},%zmm0,%zmm17,%zmm2
+[ 	]*[a-f0-9]+:	62 e1 74 58 58 d0[ 	]+vaddps \{ru-sae\},%zmm0,%zmm1,%zmm18
+[ 	]*[a-f0-9]+:	c4 e2 39 92 1c 48[ 	]+vgatherdps %xmm8,\(%rax,%xmm1,2\),%xmm3
+[ 	]*[a-f0-9]+:	c4 c2 79 92 1c 48[ 	]+vgatherdps %xmm0,\(%r8,%xmm1,2\),%xmm3
+[ 	]*[a-f0-9]+:	c4 a2 79 92 1c 48[ 	]+vgatherdps %xmm0,\(%rax,%xmm9,2\),%xmm3
+[ 	]*[a-f0-9]+:	c4 62 79 92 1c 48[ 	]+vgatherdps %xmm0,\(%rax,%xmm1,2\),%xmm11
+[ 	]*[a-f0-9]+:	62 d2 fd 0c 93 1c 48[ 	]+vgatherqpd \(%r8,%xmm1,2\),%xmm3\{%k4\}
+[ 	]*[a-f0-9]+:	62 b2 fd 0c 93 1c 48[ 	]+vgatherqpd \(%rax,%xmm9,2\),%xmm3\{%k4\}
+[ 	]*[a-f0-9]+:	62 f2 fd 04 93 1c 48[ 	]+vgatherqpd \(%rax,%xmm17,2\),%xmm3\{%k4\}
+[ 	]*[a-f0-9]+:	62 72 fd 0c 93 1c 48[ 	]+vgatherqpd \(%rax,%xmm1,2\),%xmm11\{%k4\}
+[ 	]*[a-f0-9]+:	62 e2 fd 0c 93 1c 48[ 	]+vgatherqpd \(%rax,%xmm1,2\),%xmm19\{%k4\}
 #pass
--- a/gas/testsuite/gas/i386/insn-64.s
+++ b/gas/testsuite/gas/i386/insn-64.s
@@ -13,6 +13,53 @@ insn:
 	# setssbsy
 	.insn 0xf30f01e8
 
+	# mov
+	.insn 0x8b, %ecx, %r8d
+	.insn 0x8b, %rax, %rcx
+	.insn 0x89, %ecx, 8(%r8)
+	.insn 0x8b, 0x8080(,%r8), %ecx
+
+	# movsx
+	.insn 0x0fbe, %ah, %cx
+	.insn 0x0fbf, %eax, %ecx
+	.insn 0x63, %rax, %rcx
+
+	# bswap
+	.insn 0x0fc8+r, %rdx
+	.insn 0x0fc8+r, %r8d
+
 	# vzeroall
 	.insn VEX.256.0F.WIG 0x77
 	.insn {vex3} VEX.L1 0x0f77
+
+	# vaddpd
+	.insn VEX.66.0F 0x58, %xmm8, %xmm1, %xmm2
+	.insn VEX.66 0x0f58, %ymm0, %ymm9, %ymm2
+
+	# vaddss
+	.insn VEX.LIG.F3.0F 0x58, %xmm0, %xmm1, %xmm10
+
+	# vfmaddps
+	.insn VEX.66.0F3A.W0 0x68, %xmm8, (%rcx), %xmm2, %xmm3
+	.insn VEX.66.0F3A.W1 0x68, %xmm0, (%ecx), %xmm2, %xmm3
+	.insn VEX.66.0F3A.W1 0x68, (%r8), %xmm1, %xmm2, %xmm3
+
+	# kmovw
+	.insn VEX.L0.0F.W0 0x92, %r8d, %k1
+	.insn VEX.L0.0F.W0 0x93, %k1, %r8d
+
+	# vaddps
+	.insn EVEX.NP.0F.W0 0x58, {rd-sae}, %zmm16, %zmm1, %zmm2
+	.insn EVEX.NP.0F.W0 0x58, {rn-sae}, %zmm0, %zmm17, %zmm2
+	.insn EVEX.NP.0F.W0 0x58, {ru-sae}, %zmm0, %zmm1, %zmm18
+
+	# vgather...
+	.insn VEX.66.0f38.W0 0x92, %xmm8, (%rax, %xmm1, 2), %xmm3
+	.insn VEX.66.0f38.W0 0x92, %xmm0, (%r8, %xmm1, 2), %xmm3
+	.insn VEX.66.0f38.W0 0x92, %xmm0, (%rax, %xmm9, 2), %xmm3
+	.insn VEX.66.0f38.W0 0x92, %xmm0, (%rax, %xmm1, 2), %xmm11
+	.insn EVEX.66.0f38.W1 0x93, (%r8, %xmm1, 2), %xmm3{%k4}
+	.insn EVEX.66.0f38.W1 0x93, (%rax, %xmm9, 2), %xmm3{%k4}
+	.insn EVEX.66.0f38.W1 0x93, (%rax, %xmm17, 2), %xmm3{%k4}
+	.insn EVEX.66.0f38.W1 0x93, (%rax, %xmm1, 2), %xmm11{%k4}
+	.insn EVEX.66.0f38.W1 0x93, (%rax, %xmm1, 2), %xmm19{%k4}


  parent reply	other threads:[~2023-03-10 10:23 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-10 10:17 [PATCH v2 00/14] x86: new .insn directive Jan Beulich
2023-03-10 10:19 ` [PATCH v2 01/14] x86: introduce " Jan Beulich
2023-03-10 10:19 ` [PATCH v2 02/14] x86: parse VEX and alike specifiers for .insn Jan Beulich
2023-03-10 10:20 ` [PATCH v2 03/14] x86: parse special opcode modifiers " Jan Beulich
2023-03-10 10:21 ` [PATCH v2 04/14] x86: re-work build_modrm_byte()'s register assignment Jan Beulich
2023-03-10 10:21 ` [PATCH v2 05/14] x86: VexVVVV is now merely a boolean Jan Beulich
2023-03-10 10:22 ` [PATCH v2 06/14] x86: drop "shimm" special case template expansions Jan Beulich
2023-03-10 10:22 ` [PATCH v2 07/14] x86/AT&T: restrict recognition of the "absolute branch" prefix character Jan Beulich
2023-03-10 10:23 ` Jan Beulich [this message]
2023-03-10 10:24 ` [PATCH v2 09/14] x86: handle EVEX Disp8 for .insn Jan Beulich
2023-03-10 10:24 ` [PATCH v2 10/14] x86: allow for multiple immediates in output_disp() Jan Beulich
2023-03-10 10:25 ` [PATCH v2 11/14] x86: handle immediate operands for .insn Jan Beulich
2023-03-10 10:26 ` [PATCH v2 12/14] x86: document .insn Jan Beulich
2023-03-10 10:26 ` [PATCH v2 13/14] x86: convert testcases to use .insn Jan Beulich
2023-04-20  8:56   ` Clément Chigot
2023-04-20  9:01     ` Jan Beulich
2023-04-20  9:09       ` Clément Chigot
2023-04-20  9:19         ` Jan Beulich
2023-04-20  9:22           ` Clément Chigot
2023-03-10 10:27 ` [PATCH RFC v2 14/14] x86: .insn example - VEX-encoded instructions of original Xeon Phi Jan Beulich
2023-03-24  9:51 ` [PATCH v2 00/14] x86: new .insn directive Jan Beulich

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=8d917f97-af55-11f3-a9f8-d5a209725336@suse.com \
    --to=jbeulich@suse.com \
    --cc=binutils@sourceware.org \
    --cc=haochen.jiang@intel.com \
    --cc=hjl.tools@gmail.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).