[PATCH 3/3] x86/APX: convert ZU to operand constraint

Jan Beulich jbeulich@suse.com
Wed May 29 08:09:28 GMT 2024


Extremely rarely used attributes are inefficient when represented by a
separate attribute. Convert it to an operand constraint, as already
suggested during review. The collision with RegKludge is pretty simple
to resolve.

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -4287,7 +4287,7 @@ build_apx_evex_prefix (void)
   /* Encode the NDD bit of the instruction promoted from the legacy
      space. ZU shares the same bit with NDD.  */
   if ((i.vex.register_specifier && i.tm.opcode_space == SPACE_EVEXMAP4)
-      || i.tm.opcode_modifier.zu)
+      || i.tm.opcode_modifier.operandconstraint == ZERO_UPPER)
     i.vex.bytes[3] |= 0x10;
 
   /* Encode the NF bit.  */
@@ -10301,6 +10301,10 @@ process_operands (void)
       i.types[first_reg_op + 1] = i.types[first_reg_op];
       i.operands++;
       i.reg_operands++;
+
+      /* For IMULZU switch around the constraint.  */
+      if (i.tm.mnem_off == MN_imulzu)
+	i.tm.opcode_modifier.operandconstraint = ZERO_UPPER;
     }
 
   if (i.tm.opcode_modifier.modrm)
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -492,7 +492,6 @@ static bitfield opcode_modifiers[] =
   BITFIELD (NoEgpr),
   BITFIELD (NF),
   BITFIELD (Rex2),
-  BITFIELD (ZU),
 };
 
 #define CLASS(n) #n, n
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -579,6 +579,8 @@ enum
 #define DISTINCT_DEST 8
   /* Instruction updates stack pointer implicitly.  */
 #define IMPLICIT_STACK_OP 9
+  /* Instruction zeroes upper part of register.  */
+#define ZERO_UPPER 10
   OperandConstraint,
   /* instruction ignores operand size prefix and in Intel mode ignores
      mnemonic size suffix check.  */
@@ -757,9 +759,6 @@ enum
   /* Instrucion requires REX2 prefix.  */
   Rex2,
 
-  /* Support zero upper */
-  ZU,
-
   /* The last bitfield in i386_opcode_modifier.  */
   Opcode_Modifier_Num
 };
@@ -808,7 +807,6 @@ typedef struct i386_opcode_modifier
   unsigned int noegpr:1;
   unsigned int nf:1;
   unsigned int rex2:1;
-  unsigned int zu:1;
 } i386_opcode_modifier;
 
 /* Operand classes.  */
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -85,6 +85,7 @@
 #define RegKludge         OperandConstraint=REG_KLUDGE
 #define Ugh               OperandConstraint=UGH
 #define ImplicitStackOp   OperandConstraint=IMPLICIT_STACK_OP
+#define ZU                OperandConstraint=ZERO_UPPER
 
 #define ATTSyntax         Dialect=ATT_SYNTAX
 #define ATTMnemonic       Dialect=ATT_MNEMONIC
@@ -409,10 +410,12 @@ imulzu, 0x69, APX_F, Modrm|No_bSuf|No_sS
 // transformation.
 imul, 0x6b, i186, Modrm|No_bSuf|No_sSuf|RegKludge, { Imm8S, Reg16|Reg32|Reg64 }
 imul, 0x6b, APX_F, Modrm|No_bSuf|No_sSuf|RegKludge|EVexMap4|NF, { Imm8S, Reg16|Reg32|Reg64 }
-imulzu, 0x6b, APX_F, Modrm|No_bSuf|No_sSuf|RegKludge|EVexMap4|NF|ZU, { Imm8S, Reg16 }
 imul, 0x69, i186, Modrm|No_bSuf|No_sSuf|RegKludge, { Imm16|Imm32|Imm32S, Reg16|Reg32|Reg64 }
 imul, 0x69, APX_F, Modrm|No_bSuf|No_sSuf|RegKludge|EVexMap4|NF, { Imm16|Imm32|Imm32S, Reg16|Reg32|Reg64 }
-imulzu, 0x69, APX_F, Modrm|No_bSuf|No_sSuf|RegKludge|EVexMap4|NF|ZU, { Imm16, Reg16 }
+// ZU is omitted here, for colliding with RegKludge.  process_operands() will
+// replace the constraint value after processing RegKludge.
+imulzu, 0x6b, APX_F, Modrm|No_bSuf|No_sSuf|RegKludge|EVexMap4|NF/*|ZU*/, { Imm8S, Reg16 }
+imulzu, 0x69, APX_F, Modrm|No_bSuf|No_sSuf|RegKludge|EVexMap4|NF/*|ZU*/, { Imm16, Reg16 }
 
 <mul>
 



More information about the Binutils mailing list