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>
Subject: [PATCH] x86: fold special-operand insn attributes into a single enum
Date: Thu, 10 Nov 2022 14:45:30 +0100	[thread overview]
Message-ID: <21665493-a9f9-3429-c9ae-ea69bc7751e2@suse.com> (raw)

Attributes which aren't used together in any single insn template can be
converted from individual booleans to a single enum, as was done for a few
other attributes before. This is more space efficient. Collect together
all attributes which express special operand constraints (and which fit
the criteria for folding).

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -2071,7 +2071,7 @@ operand_size_match (const insn_template
     {
       if (i.types[j].bitfield.class != Reg
 	  && i.types[j].bitfield.class != RegSIMD
-	  && t->opcode_modifier.anysize)
+	  && t->opcode_modifier.operandconstraint == ANY_SIZE)
 	continue;
 
       if (t->operand_types[j].bitfield.class == Reg
@@ -4518,7 +4518,7 @@ load_insn_p (void)
     {
       /* Anysize insns: lea, invlpg, clflush, prefetch*, bndmk, bndcl, bndcu,
 	 bndcn, bndstx, bndldx, clflushopt, clwb, cldemote.  */
-      if (i.tm.opcode_modifier.anysize)
+      if (i.tm.opcode_modifier.operandconstraint == ANY_SIZE)
 	return 0;
 
       /* pop.   */
@@ -5107,7 +5107,7 @@ md_assemble (char *line)
       if (!process_operands ())
 	return;
     }
-  else if (!quiet_warnings && i.tm.opcode_modifier.ugh)
+  else if (!quiet_warnings && i.tm.opcode_modifier.operandconstraint == UGH)
     {
       /* UnixWare fsub no args is alias for fsubp, fadd -> faddp, etc.  */
       as_warn (_("translating to `%sp'"), i.tm.name);
@@ -6020,7 +6020,7 @@ check_VecOperands (const insn_template *
     }
 
   /* Check if default mask is allowed.  */
-  if (t->opcode_modifier.nodefmask
+  if (t->opcode_modifier.operandconstraint == NO_DEFAULT_MASK
       && (!i.mask.reg || i.mask.reg->reg_num == 0))
     {
       i.error = no_default_mask;
@@ -6102,7 +6102,7 @@ check_VecOperands (const insn_template *
 
   /* For some special instructions require that destination must be distinct
      from source registers.  */
-  if (t->opcode_modifier.distinctdest)
+  if (t->opcode_modifier.operandconstraint == DISTINCT_DEST)
     {
       unsigned int dest_reg = i.operands - 1;
 
@@ -7047,7 +7047,7 @@ process_suffix (void)
     i.suffix = QWORD_MNEM_SUFFIX;
   else if (i.reg_operands
 	   && (i.operands > 1 || i.types[0].bitfield.class == Reg)
-	   && !i.tm.opcode_modifier.addrprefixopreg)
+	   && i.tm.opcode_modifier.operandconstraint != ADDR_PREFIX_OP_REG)
     {
       unsigned int numop = i.operands;
 
@@ -7414,7 +7414,7 @@ process_suffix (void)
       break;
     }
 
-  if (i.tm.opcode_modifier.addrprefixopreg)
+  if (i.tm.opcode_modifier.operandconstraint == ADDR_PREFIX_OP_REG)
     {
       gas_assert (!i.suffix);
       gas_assert (i.reg_operands);
@@ -7808,7 +7808,7 @@ process_operands (void)
 		}
 	    }
 	}
-      else if (i.tm.opcode_modifier.implicit1stxmm0)
+      else if (i.tm.opcode_modifier.operandconstraint == IMPLICIT_1ST_XMM0)
 	{
 	  gas_assert ((MAX_OPERANDS - 1) > dupl
 		      && (i.tm.opcode_modifier.vexsources
@@ -7876,7 +7876,7 @@ process_operands (void)
       i.reg_operands--;
       i.tm.operands--;
     }
-  else if (i.tm.opcode_modifier.implicitquadgroup)
+  else if (i.tm.opcode_modifier.operandconstraint == IMPLICIT_QUAD_GROUP)
     {
       unsigned int regnum, first_reg_in_group, last_reg_in_group;
 
@@ -7893,7 +7893,7 @@ process_operands (void)
 		 register_prefix, i.op[1].regs->reg_name, last_reg_in_group,
 		 i.tm.name);
     }
-  else if (i.tm.opcode_modifier.regkludge)
+  else if (i.tm.opcode_modifier.operandconstraint == REG_KLUDGE)
     {
       /* The imul $imm, %reg instruction is converted into
 	 imul $imm, %reg, %reg, and the clr %reg instruction
@@ -7963,7 +7963,7 @@ process_operands (void)
       i.tm.base_opcode |= i.op[op].regs->reg_num;
       if ((i.op[op].regs->reg_flags & RegRex) != 0)
 	i.rex |= REX_B;
-      if (!quiet_warnings && i.tm.opcode_modifier.ugh)
+      if (!quiet_warnings && i.tm.opcode_modifier.operandconstraint == UGH)
 	{
 	  /* Warn about some common errors, but press on regardless.
 	     The first case can be generated by gcc (<= 2.8.1).  */
@@ -8190,7 +8190,7 @@ build_modrm_byte (void)
 	      unsigned int vvvv;
 
 	      /* Swap two source operands if needed.  */
-	      if (i.tm.opcode_modifier.swapsources)
+	      if (i.tm.opcode_modifier.operandconstraint == SWAP_SOURCES)
 		{
 		  vvvv = source;
 		  source = dest;
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -729,9 +729,8 @@ static bitfield opcode_modifiers[] =
   BITFIELD (FloatR),
   BITFIELD (Size),
   BITFIELD (CheckRegSize),
-  BITFIELD (DistinctDest),
+  BITFIELD (OperandConstraint),
   BITFIELD (MnemonicSize),
-  BITFIELD (Anysize),
   BITFIELD (No_bSuf),
   BITFIELD (No_wSuf),
   BITFIELD (No_lSuf),
@@ -742,14 +741,10 @@ static bitfield opcode_modifiers[] =
   BITFIELD (IsString),
   BITFIELD (RegMem),
   BITFIELD (BNDPrefixOk),
-  BITFIELD (RegKludge),
-  BITFIELD (Implicit1stXmm0),
   BITFIELD (PrefixOk),
-  BITFIELD (AddrPrefixOpReg),
   BITFIELD (IsPrefix),
   BITFIELD (ImmExt),
   BITFIELD (NoRex64),
-  BITFIELD (Ugh),
   BITFIELD (Vex),
   BITFIELD (VexVVVV),
   BITFIELD (VexW),
@@ -764,9 +759,6 @@ static bitfield opcode_modifiers[] =
   BITFIELD (StaticRounding),
   BITFIELD (SAE),
   BITFIELD (Disp8MemShift),
-  BITFIELD (NoDefMask),
-  BITFIELD (ImplicitQuadGroup),
-  BITFIELD (SwapSources),
   BITFIELD (Optimize),
   BITFIELD (ATTMnemonic),
   BITFIELD (ATTSyntax),
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -495,17 +495,35 @@ enum
   Size,
   /* check register size.  */
   CheckRegSize,
+  /* any memory size */
+#define ANY_SIZE 1
+  /* fake an extra reg operand for clr, imul and special register
+     processing for some instructions.  */
+#define REG_KLUDGE 2
+  /* deprecated fp insn, gets a warning */
+#define UGH 3
+  /* An implicit xmm0 as the first operand */
+#define IMPLICIT_1ST_XMM0 4
+  /* The second operand must be a vector register, {x,y,z}mmN, where N is a multiple of 4.
+     It implicitly denotes the register group of {x,y,z}mmN - {x,y,z}mm(N + 3).
+   */
+#define IMPLICIT_QUAD_GROUP 5
+  /* Two source operands are swapped.  */
+#define SWAP_SOURCES 6
+  /* Default mask isn't allowed.  */
+#define NO_DEFAULT_MASK 7
+  /* Address prefix changes register operand */
+#define ADDR_PREFIX_OP_REG 8
   /* Instrucion requires that destination must be distinct from source
      registers.  */
-  DistinctDest,
+#define DISTINCT_DEST 9
+  OperandConstraint,
   /* instruction ignores operand size prefix and in Intel mode ignores
      mnemonic size suffix check.  */
 #define IGNORESIZE	1
   /* default insn size depends on mode */
 #define DEFAULTSIZE	2
   MnemonicSize,
-  /* any memory size */
-  Anysize,
   /* b suffix on instruction illegal */
   No_bSuf,
   /* w suffix on instruction illegal */
@@ -533,11 +551,6 @@ enum
   RegMem,
   /* quick test if branch instruction is MPX supported */
   BNDPrefixOk,
-  /* fake an extra reg operand for clr, imul and special register
-     processing for some instructions.  */
-  RegKludge,
-  /* An implicit xmm0 as the first operand */
-  Implicit1stXmm0,
 #define PrefixNone		0
 #define PrefixRep		1
 #define PrefixHLERelease	2 /* Okay with an XRELEASE (0xf3) prefix. */
@@ -548,16 +561,12 @@ enum
 #define PrefixHLELock		5 /* Okay with a LOCK prefix.  */
 #define PrefixHLEAny		6 /* Okay with or without a LOCK prefix.  */
   PrefixOk,
-  /* Address prefix changes register operand */
-  AddrPrefixOpReg,
   /* opcode is a prefix */
   IsPrefix,
   /* instruction has extension in 8 bit imm */
   ImmExt,
   /* instruction don't need Rex64 prefix.  */
   NoRex64,
-  /* deprecated fp insn, gets a warning */
-  Ugh,
   /* insn has VEX prefix:
 	1: 128bit VEX prefix (or operand dependent).
 	2: 256bit VEX prefix.
@@ -700,17 +709,6 @@ enum
 #define DISP8_SHIFT_VL 7
   Disp8MemShift,
 
-  /* Default mask isn't allowed.  */
-  NoDefMask,
-
-  /* The second operand must be a vector register, {x,y,z}mmN, where N is a multiple of 4.
-     It implicitly denotes the register group of {x,y,z}mmN - {x,y,z}mm(N + 3).
-   */
-  ImplicitQuadGroup,
-
-  /* Two source operands are swapped.  */
-  SwapSources,
-
   /* Support encoding optimization.  */
   Optimize,
 
@@ -745,9 +743,8 @@ typedef struct i386_opcode_modifier
   unsigned int floatr:1;
   unsigned int size:2;
   unsigned int checkregsize:1;
-  unsigned int distinctdest:1;
+  unsigned int operandconstraint:4;
   unsigned int mnemonicsize:2;
-  unsigned int anysize:1;
   unsigned int no_bsuf:1;
   unsigned int no_wsuf:1;
   unsigned int no_lsuf:1;
@@ -758,14 +755,10 @@ typedef struct i386_opcode_modifier
   unsigned int isstring:2;
   unsigned int regmem:1;
   unsigned int bndprefixok:1;
-  unsigned int regkludge:1;
-  unsigned int implicit1stxmm0:1;
   unsigned int prefixok:3;
-  unsigned int addrprefixopreg:1;
   unsigned int isprefix:1;
   unsigned int immext:1;
   unsigned int norex64:1;
-  unsigned int ugh:1;
   unsigned int vex:2;
   unsigned int vexvvvv:2;
   unsigned int vexw:2;
@@ -780,9 +773,6 @@ typedef struct i386_opcode_modifier
   unsigned int staticrounding:1;
   unsigned int sae:1;
   unsigned int disp8memshift:3;
-  unsigned int nodefmask:1;
-  unsigned int implicitquadgroup:1;
-  unsigned int swapsources:1;
   unsigned int optimize:1;
   unsigned int attmnemonic:1;
   unsigned int attsyntax:1;
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -75,6 +75,17 @@
 #define Size32 Size=SIZE32
 #define Size64 Size=SIZE64
 
+#define AddrPrefixOpReg   OperandConstraint=ADDR_PREFIX_OP_REG | \
+                          No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf
+#define Anysize           OperandConstraint=ANY_SIZE
+#define DistinctDest      OperandConstraint=DISTINCT_DEST
+#define Implicit1stXmm0   OperandConstraint=IMPLICIT_1ST_XMM0
+#define ImplicitQuadGroup OperandConstraint=IMPLICIT_QUAD_GROUP
+#define NoDefMask         OperandConstraint=NO_DEFAULT_MASK
+#define RegKludge         OperandConstraint=REG_KLUDGE
+#define SwapSources       OperandConstraint=SWAP_SOURCES
+#define Ugh               OperandConstraint=UGH
+
 #define IgnoreSize	MnemonicSize=IGNORESIZE
 #define DefaultSize	MnemonicSize=DEFAULTSIZE
 
@@ -91,8 +102,6 @@
 #define HLEPrefixRelease PrefixOk=PrefixHLERelease
 #define NoTrackPrefixOk  PrefixOk=PrefixNoTrack
 
-#define AddrPrefixOpReg AddrPrefixOpReg|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf
-
 #define Space0F    OpcodeSpace=SPACE_0F
 #define Space0F38  OpcodeSpace=SPACE_0F38
 #define Space0F3A  OpcodeSpace=SPACE_0F3A

             reply	other threads:[~2022-11-10 13:45 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-10 13:45 Jan Beulich [this message]
2022-11-10 17:38 ` H.J. Lu
2022-11-11  8:00   ` Jan Beulich
2022-11-11  8:22     ` Jan Beulich
2022-11-11 19:48       ` H.J. Lu
2022-11-14  1:38         ` Jiang, Haochen
2022-11-14 15:58 ` H.J. Lu

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=21665493-a9f9-3429-c9ae-ea69bc7751e2@suse.com \
    --to=jbeulich@suse.com \
    --cc=binutils@sourceware.org \
    --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).