[PATCH] x86: drop Vec_Imm4

Jan Beulich JBeulich@suse.com
Fri Jun 28 15:56:00 GMT 2019


It is pretty wasteful to have a per-operand flag which is used in
exactly 4 cases. It can be relatively easily replaced, and by doing so
I've actually found some dead code to remove at the same time (there's
no case of ImmExt set at the same time as Vec_Imm4).


gas/
2019-06-28  Jan Beulich  <jbeulich@suse.com>

	* config/tc-i386.c (vec_imm4): Delete.
	(VEX_check_operands): Replace Vec_Imm4 check by CpuXOP with five
	operands one.  Clear Imm<N> by different means.
	(build_modrm_byte): Adjust comment.  Remove dead code.  Add and
	adjust assertions.

opcodes/
2019-06-28  Jan Beulich  <jbeulich@suse.com>

	* opcodes/i386-gen.c (operand_type_init): Remove
	OPERAND_TYPE_VEC_IMM4 entry.
	(operand_types): Remove Vec_Imm4.
	* opcodes/i386-opc.h (Vec_Imm4): Delete.
	(union i386_operand_type): Remove vec_imm4.
	* i386-opc.tbl (vpermil2pd, vpermil2ps): Remove Vec_Imm4.
	* opcodes/i386-init.h, i386-tbl.h: Re-generate.
---
Obviously (I think) this goes on top of everything still pending
approval.

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -1915,7 +1915,6 @@ static const i386_operand_type imm64 = O
  static const i386_operand_type imm16_32 = OPERAND_TYPE_IMM16_32;
  static const i386_operand_type imm16_32s = OPERAND_TYPE_IMM16_32S;
  static const i386_operand_type imm16_32_32s = OPERAND_TYPE_IMM16_32_32S;
-static const i386_operand_type vec_imm4 = OPERAND_TYPE_VEC_IMM4;
  
  enum operand_type
  {
@@ -5649,8 +5648,8 @@ VEX_check_operands (const insn_template
        return 0;
      }
  
-  /* Only check VEX_Imm4, which must be the first operand.  */
-  if (t->operand_types[0].bitfield.vec_imm4)
+  /* Check the special Imm4 cases; must be the first operand.  */
+  if (t->cpu_flags.bitfield.cpuxop && t->operands == 5)
      {
        if (i.op[0].imms->X_op != O_constant
  	  || !fits_in_imm4 (i.op[0].imms->X_add_number))
@@ -5659,8 +5658,8 @@ VEX_check_operands (const insn_template
  	  return 1;
  	}
  
-      /* Turn off Imm8 so that update_imm won't complain.  */
-      i.types[0] = vec_imm4;
+      /* Turn off Imm<N> so that update_imm won't complain.  */
+      operand_type_set (&i.types[0], 0);
      }
  
    return 0;
@@ -7098,7 +7097,7 @@ build_modrm_byte (void)
  
        /* There are 2 kinds of instructions:
  	 1. 5 operands: 4 register operands or 3 register operands
-	 plus 1 memory operand plus one Vec_Imm4 operand, VexXDS, and
+	 plus 1 memory operand plus one Imm4 operand, VexXDS, and
  	 VexW0 or VexW1.  The destination must be either XMM, YMM or
  	 ZMM register.
  	 2. 4 operands: 4 register operands or 3 register operands
@@ -7138,28 +7137,15 @@ build_modrm_byte (void)
  	}
        else
  	{
-	  unsigned int imm_slot;
+	  gas_assert (i.imm_operands == 1);
+	  gas_assert (fits_in_imm4 (i.op[0].imms->X_add_number));
+	  gas_assert (!i.tm.opcode_modifier.immext);
  
-	  gas_assert (i.imm_operands == 1 && i.types[0].bitfield.vec_imm4);
-
-	  if (i.tm.opcode_modifier.immext)
-	    {
-	      /* When ImmExt is set, the immediate byte is the last
-		 operand.  */
-	      imm_slot = i.operands - 1;
-	      source--;
-	      reg_slot--;
-	    }
-	  else
-	    {
-	      imm_slot = 0;
-
-	      /* Turn on Imm8 so that output_imm will generate it.  */
-	      i.types[imm_slot].bitfield.imm8 = 1;
-	    }
+	  /* 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.regsimd);
-	  i.op[imm_slot].imms->X_add_number
+	  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);
  	}
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -486,8 +486,6 @@ static initializer operand_type_init[] =
      "Imm32|Imm32S|Imm64|Disp32" },
    { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
      "Imm32|Imm32S|Imm64|Disp32|Disp64" },
-  { "OPERAND_TYPE_VEC_IMM4",
-    "Vec_Imm4" },
    { "OPERAND_TYPE_REGBND",
      "RegBND" },
  };
@@ -721,7 +719,6 @@ static bitfield operand_types[] =
    BITFIELD (Zmmword),
    BITFIELD (Unspecified),
    BITFIELD (Anysize),
-  BITFIELD (Vec_Imm4),
    BITFIELD (RegBND),
  #ifdef OTUnused
    BITFIELD (OTUnused),
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -784,9 +784,6 @@ enum
    /* Any memory size.  */
    Anysize,
  
-  /* Vector 4 bit immediate.  */
-  Vec_Imm4,
-
    /* Bound register.  */
    RegBND,
  
@@ -846,7 +843,6 @@ typedef union i386_operand_type
        unsigned int zmmword:1;
        unsigned int unspecified:1;
        unsigned int anysize:1;
-      unsigned int vec_imm4:1;
        unsigned int regbnd:1;
  #ifdef OTUnused
        unsigned int unused:(OTNumOfBits - OTUnused);
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -2587,10 +2587,10 @@ vpcomud,    4, 0xee, None, 1, CpuXOP, Mo
  vpcomuq,    4, 0xef, None, 1, CpuXOP, Modrm|VexOpcode=3|VexVVVV=1|VexW=1|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Vex, { Imm8, RegXMM|Unspecified|BaseIndex, RegXMM, RegXMM }
  vpcomuw,    4, 0xed, None, 1, CpuXOP, Modrm|VexOpcode=3|VexVVVV=1|VexW=1|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Vex, { Imm8, RegXMM|Unspecified|BaseIndex, RegXMM, RegXMM }
  vpcomw,     4, 0xcd, None, 1, CpuXOP, Modrm|VexOpcode=3|VexVVVV=1|VexW=1|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Vex, { Imm8, RegXMM|Unspecified|BaseIndex, RegXMM, RegXMM }
-vpermil2pd, 5, 0x6649, None, 1, CpuXOP, Modrm|VexOpcode=2|VexVVVV=1|VexW=1|Vex|VexSources=2|CheckRegSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm8|Vec_Imm4, RegXMM|RegYMM, Unspecified|BaseIndex|RegXMM|RegYMM, RegXMM|RegYMM, RegXMM|RegYMM }
-vpermil2pd, 5, 0x6649, None, 1, CpuXOP, Modrm|VexOpcode=2|VexVVVV=1|VexW=2|Vex|VexSources=2|CheckRegSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm8|Vec_Imm4, Unspecified|BaseIndex|RegXMM|RegYMM, RegXMM|RegYMM, RegXMM|RegYMM, RegXMM|RegYMM }
-vpermil2ps, 5, 0x6648, None, 1, CpuXOP, Modrm|VexOpcode=2|VexVVVV=1|VexW=1|Vex|VexSources=2|CheckRegSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm8|Vec_Imm4, RegXMM|RegYMM, Unspecified|BaseIndex|RegXMM|RegYMM, RegXMM|RegYMM, RegXMM|RegYMM }
-vpermil2ps, 5, 0x6648, None, 1, CpuXOP, Modrm|VexOpcode=2|VexVVVV=1|VexW=2|Vex|VexSources=2|CheckRegSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm8|Vec_Imm4, Unspecified|BaseIndex|RegXMM|RegYMM, RegXMM|RegYMM, RegXMM|RegYMM, RegXMM|RegYMM }
+vpermil2pd, 5, 0x6649, None, 1, CpuXOP, Modrm|VexOpcode=2|VexVVVV=1|VexW=1|Vex|VexSources=2|CheckRegSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm8, RegXMM|RegYMM, Unspecified|BaseIndex|RegXMM|RegYMM, RegXMM|RegYMM, RegXMM|RegYMM }
+vpermil2pd, 5, 0x6649, None, 1, CpuXOP, Modrm|VexOpcode=2|VexVVVV=1|VexW=2|Vex|VexSources=2|CheckRegSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm8, Unspecified|BaseIndex|RegXMM|RegYMM, RegXMM|RegYMM, RegXMM|RegYMM, RegXMM|RegYMM }
+vpermil2ps, 5, 0x6648, None, 1, CpuXOP, Modrm|VexOpcode=2|VexVVVV=1|VexW=1|Vex|VexSources=2|CheckRegSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm8, RegXMM|RegYMM, Unspecified|BaseIndex|RegXMM|RegYMM, RegXMM|RegYMM, RegXMM|RegYMM }
+vpermil2ps, 5, 0x6648, None, 1, CpuXOP, Modrm|VexOpcode=2|VexVVVV=1|VexW=2|Vex|VexSources=2|CheckRegSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm8, Unspecified|BaseIndex|RegXMM|RegYMM, RegXMM|RegYMM, RegXMM|RegYMM, RegXMM|RegYMM }
  vpcomltb,   3, 0xcc, 0x0, 1, CpuXOP, Modrm|VexOpcode=3|VexVVVV=1|VexW=1|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Vex|ImmExt, { RegXMM|Unspecified|BaseIndex, RegXMM, RegXMM }
  vpcomltd,   3, 0xce, 0x0, 1, CpuXOP, Modrm|VexOpcode=3|VexVVVV=1|VexW=1|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Vex|ImmExt, { RegXMM|Unspecified|BaseIndex, RegXMM, RegXMM }
  vpcomltq,   3, 0xcf, 0x0, 1, CpuXOP, Modrm|VexOpcode=3|VexVVVV=1|VexW=1|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Vex|ImmExt, { RegXMM|Unspecified|BaseIndex, RegXMM, RegXMM }


More information about the Binutils mailing list