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

Cui, Lili lili.cui@intel.com
Fri Jun 7 07:22:24 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>
> 

LGTM, thanks!

Lili.


More information about the Binutils mailing list