public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] x86: shrink opcode sets table
@ 2023-11-20  8:06 Jan Beulich
  0 siblings, 0 replies; only message in thread
From: Jan Beulich @ 2023-11-20  8:06 UTC (permalink / raw)
  To: Binutils; +Cc: H.J. Lu

Have i386-gen produce merely the offsets into i386_optab[]. Besides
allowing to shrink the table even on 32-bit builds, this results in
removing a level of indirection from the frequently accessed
current_templates, in return for adding a level of indirection when
looking up mnemonics (commonly happening just once per insn). Plus for
PIE builds of gas it also reduces the number of relocations by about two
thousand. Finally a somewhat ugly static variable can also be eliminated
from i386_displacement().
---
This is assumed to go on top of "x86: also prefer VEX encoding over EVEX
one for VCVTNEPS2BF16 when possible" sent a few minutes earlier.

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -569,7 +569,7 @@ static char *save_stack_p;
 static i386_insn i;
 
 /* Possible templates for current insn.  */
-static const templates *current_templates;
+static templates current_templates;
 
 /* Per instruction expressionS buffers: max displacements & immediates.  */
 static expressionS disp_expressions[MAX_MEMORY_OPERANDS];
@@ -3101,6 +3101,20 @@ i386_mach (void)
 \f
 #include "opcodes/i386-tbl.h"
 
+static void
+op_lookup (const char *mnemonic)
+{
+   i386_op_off_t *pos = str_hash_find (op_hash, mnemonic);
+
+   if (pos != NULL)
+     {
+       current_templates.start = &i386_optab[pos[0]];
+       current_templates.end = &i386_optab[pos[1]];
+     }
+   else
+     current_templates.end = current_templates.start = NULL;
+}
+
 void
 md_begin (void)
 {
@@ -3111,16 +3125,12 @@ md_begin (void)
   op_hash = str_htab_create ();
 
   {
-    const insn_template *const *sets = i386_op_sets;
-    const insn_template *const *end = sets + ARRAY_SIZE (i386_op_sets) - 1;
+    const i386_op_off_t *cur = i386_op_sets;
+    const i386_op_off_t *end = cur + ARRAY_SIZE (i386_op_sets) - 1;
 
-    /* Type checks to compensate for the conversion through void * which
-       occurs during hash table insertion / lookup.  */
-    (void) sizeof (sets == &current_templates->start);
-    (void) sizeof (end == &current_templates->end);
-    for (; sets < end; ++sets)
-      if (str_hash_insert (op_hash, insn_name (*sets), sets, 0))
-	as_fatal (_("duplicate %s"), insn_name (*sets));
+    for (; cur < end; ++cur)
+      if (str_hash_insert (op_hash, insn_name (&i386_optab[*cur]), cur, 0))
+	as_fatal (_("duplicate %s"), insn_name (&i386_optab[*cur]));
   }
 
   /* Initialize reg_hash hash table.  */
@@ -5121,7 +5131,7 @@ md_assemble (char *line)
   const insn_template *t;
 
   /* Initialize globals.  */
-  current_templates = NULL;
+  current_templates.end = current_templates.start = NULL;
  retry:
   init_globals ();
 
@@ -5136,8 +5146,8 @@ md_assemble (char *line)
 	goto match_error;
       if (i.error != no_error)
 	{
-	  gas_assert (current_templates != NULL);
-	  if (may_need_pass2 (current_templates->start) && !i.suffix)
+	  gas_assert (current_templates.start != NULL);
+	  if (may_need_pass2 (current_templates.start) && !i.suffix)
 	    goto no_match;
 	  /* No point in trying a 2nd pass - it'll only find the same suffix
 	     again.  */
@@ -5146,7 +5156,7 @@ md_assemble (char *line)
 	}
       return;
     }
-  t = current_templates->start;
+  t = current_templates.start;
   if (may_need_pass2 (t))
     {
       /* Make a copy of the full line in case we need to retry.  */
@@ -5204,7 +5214,7 @@ md_assemble (char *line)
 	 32-bit immediate and 64-bit operand size use sign-extended
 	 immediates (imm32s). Therefore these insns are special-cased, bypassing
 	 the normal handling of immediates here.  */
-      if (is_cpu(current_templates->start, CpuUSER_MSR))
+      if (is_cpu(current_templates.start, CpuUSER_MSR))
 	{
 	  for (j = 0; j < i.operands; j++)
 	    {
@@ -5233,7 +5243,7 @@ md_assemble (char *line)
 	  copy = NULL;
   no_match:
 	  pass1_err = i.error;
-	  pass1_mnem = insn_name (current_templates->start);
+	  pass1_mnem = insn_name (current_templates.start);
 	  goto retry;
 	}
 
@@ -5276,11 +5286,11 @@ md_assemble (char *line)
 	  break;
 	case unsupported:
 	  as_bad (_("unsupported instruction `%s'"),
-		  pass1_mnem ? pass1_mnem : insn_name (current_templates->start));
+		  pass1_mnem ? pass1_mnem : insn_name (current_templates.start));
 	  return;
 	case unsupported_on_arch:
 	  as_bad (_("`%s' is not supported on `%s%s'"),
-		  pass1_mnem ? pass1_mnem : insn_name (current_templates->start),
+		  pass1_mnem ? pass1_mnem : insn_name (current_templates.start),
 		  cpu_arch_name ? cpu_arch_name : default_arch,
 		  cpu_sub_arch_name ? cpu_sub_arch_name : "");
 	  return;
@@ -5289,21 +5299,21 @@ md_assemble (char *line)
 	    {
 	      if (flag_code == CODE_64BIT)
 		as_bad (_("`%s%c' is not supported in 64-bit mode"),
-			pass1_mnem ? pass1_mnem : insn_name (current_templates->start),
+			pass1_mnem ? pass1_mnem : insn_name (current_templates.start),
 			mnem_suffix);
 	      else
 		as_bad (_("`%s%c' is only supported in 64-bit mode"),
-			pass1_mnem ? pass1_mnem : insn_name (current_templates->start),
+			pass1_mnem ? pass1_mnem : insn_name (current_templates.start),
 			mnem_suffix);
 	    }
 	  else
 	    {
 	      if (flag_code == CODE_64BIT)
 		as_bad (_("`%s' is not supported in 64-bit mode"),
-			pass1_mnem ? pass1_mnem : insn_name (current_templates->start));
+			pass1_mnem ? pass1_mnem : insn_name (current_templates.start));
 	      else
 		as_bad (_("`%s' is only supported in 64-bit mode"),
-			pass1_mnem ? pass1_mnem : insn_name (current_templates->start));
+			pass1_mnem ? pass1_mnem : insn_name (current_templates.start));
 	    }
 	  return;
 	case no_vex_encoding:
@@ -5350,14 +5360,14 @@ md_assemble (char *line)
 	  break;
 	case unsupported_vector_size:
 	  as_bad (_("vector size above %u required for `%s'"), 128u << vector_size,
-		  pass1_mnem ? pass1_mnem : insn_name (current_templates->start));
+		  pass1_mnem ? pass1_mnem : insn_name (current_templates.start));
 	  return;
 	case internal_error:
 	  err_msg = _("internal error");
 	  break;
 	}
       as_bad (_("%s for `%s'"), err_msg,
-	      pass1_mnem ? pass1_mnem : insn_name (current_templates->start));
+	      pass1_mnem ? pass1_mnem : insn_name (current_templates.start));
       return;
     }
 
@@ -5710,7 +5720,7 @@ parse_insn (const char *line, char *mnem
 {
   const char *l = line, *token_start = l;
   char *mnem_p;
-  bool pass1 = !current_templates;
+  bool pass1 = !current_templates.start;
   int supported;
   const insn_template *t;
   char *dot_p = NULL;
@@ -5771,47 +5781,47 @@ parse_insn (const char *line, char *mnem
 	}
 
       /* Look up instruction (or prefix) via hash table.  */
-      current_templates = (const templates *) str_hash_find (op_hash, mnemonic);
+      op_lookup (mnemonic);
 
       if (*l != END_OF_INSN
 	  && (!is_space_char (*l) || l[1] != END_OF_INSN)
-	  && current_templates
-	  && current_templates->start->opcode_modifier.isprefix)
+	  && current_templates.start
+	  && current_templates.start->opcode_modifier.isprefix)
 	{
-	  supported = cpu_flags_match (current_templates->start);
+	  supported = cpu_flags_match (current_templates.start);
 	  if (!(supported & CPU_FLAGS_64BIT_MATCH))
 	    {
 	      as_bad ((flag_code != CODE_64BIT
 		       ? _("`%s' is only supported in 64-bit mode")
 		       : _("`%s' is not supported in 64-bit mode")),
-		      insn_name (current_templates->start));
+		      insn_name (current_templates.start));
 	      return NULL;
 	    }
 	  if (supported != CPU_FLAGS_PERFECT_MATCH)
 	    {
 	      as_bad (_("`%s' is not supported on `%s%s'"),
-		      insn_name (current_templates->start),
+		      insn_name (current_templates.start),
 		      cpu_arch_name ? cpu_arch_name : default_arch,
 		      cpu_sub_arch_name ? cpu_sub_arch_name : "");
 	      return NULL;
 	    }
 	  /* If we are in 16-bit mode, do not allow addr16 or data16.
 	     Similarly, in 32-bit mode, do not allow addr32 or data32.  */
-	  if ((current_templates->start->opcode_modifier.size == SIZE16
-	       || current_templates->start->opcode_modifier.size == SIZE32)
+	  if ((current_templates.start->opcode_modifier.size == SIZE16
+	       || current_templates.start->opcode_modifier.size == SIZE32)
 	      && flag_code != CODE_64BIT
-	      && ((current_templates->start->opcode_modifier.size == SIZE32)
+	      && ((current_templates.start->opcode_modifier.size == SIZE32)
 		  ^ (flag_code == CODE_16BIT)))
 	    {
 	      as_bad (_("redundant %s prefix"),
-		      insn_name (current_templates->start));
+		      insn_name (current_templates.start));
 	      return NULL;
 	    }
 
-	  if (current_templates->start->base_opcode == PSEUDO_PREFIX)
+	  if (current_templates.start->base_opcode == PSEUDO_PREFIX)
 	    {
 	      /* Handle pseudo prefixes.  */
-	      switch (current_templates->start->extension_opcode)
+	      switch (current_templates.start->extension_opcode)
 		{
 		case Prefix_Disp8:
 		  /* {disp8} */
@@ -5860,21 +5870,21 @@ parse_insn (const char *line, char *mnem
 	  else
 	    {
 	      /* Add prefix, checking for repeated prefixes.  */
-	      switch (add_prefix (current_templates->start->base_opcode))
+	      switch (add_prefix (current_templates.start->base_opcode))
 		{
 		case PREFIX_EXIST:
 		  return NULL;
 		case PREFIX_DS:
-		  if (is_cpu (current_templates->start, CpuIBT))
-		    i.notrack_prefix = insn_name (current_templates->start);
+		  if (is_cpu (current_templates.start, CpuIBT))
+		    i.notrack_prefix = insn_name (current_templates.start);
 		  break;
 		case PREFIX_REP:
-		  if (is_cpu (current_templates->start, CpuHLE))
-		    i.hle_prefix = insn_name (current_templates->start);
-		  else if (is_cpu (current_templates->start, CpuMPX))
-		    i.bnd_prefix = insn_name (current_templates->start);
+		  if (is_cpu (current_templates.start, CpuHLE))
+		    i.hle_prefix = insn_name (current_templates.start);
+		  else if (is_cpu (current_templates.start, CpuMPX))
+		    i.bnd_prefix = insn_name (current_templates.start);
 		  else
-		    i.rep_prefix = insn_name (current_templates->start);
+		    i.rep_prefix = insn_name (current_templates.start);
 		  break;
 		default:
 		  break;
@@ -5890,7 +5900,7 @@ parse_insn (const char *line, char *mnem
   if (prefix_only)
     return token_start;
 
-  if (!current_templates)
+  if (!current_templates.start)
     {
       /* Deprecated functionality (new code should use pseudo-prefixes instead):
 	 Check if we should swap operand or force 32bit displacement in
@@ -5926,12 +5936,12 @@ parse_insn (const char *line, char *mnem
 	goto check_suffix;
       mnem_p = dot_p;
       *dot_p = '\0';
-      current_templates = (const templates *) str_hash_find (op_hash, mnemonic);
+      op_lookup (mnemonic);
     }
 
-  if (!current_templates || !pass1)
+  if (!current_templates.start || !pass1)
     {
-      current_templates = NULL;
+      current_templates.start = NULL;
 
     check_suffix:
       if (mnem_p > mnemonic)
@@ -5948,8 +5958,7 @@ parse_insn (const char *line, char *mnem
 	      case QWORD_MNEM_SUFFIX:
 		i.suffix = mnem_p[-1];
 	      mnem_p[-1] = '\0';
-	      current_templates
-		= (const templates *) str_hash_find (op_hash, mnemonic);
+	      op_lookup (mnemonic);
 	      break;
 	    case SHORT_MNEM_SUFFIX:
 	    case LONG_MNEM_SUFFIX:
@@ -5957,8 +5966,7 @@ parse_insn (const char *line, char *mnem
 		{
 		  i.suffix = mnem_p[-1];
 		  mnem_p[-1] = '\0';
-		  current_templates
-		    = (const templates *) str_hash_find (op_hash, mnemonic);
+		  op_lookup (mnemonic);
 		}
 	      break;
 
@@ -5971,8 +5979,7 @@ parse_insn (const char *line, char *mnem
 		  else
 		    i.suffix = LONG_MNEM_SUFFIX;
 		  mnem_p[-1] = '\0';
-		  current_templates
-		    = (const templates *) str_hash_find (op_hash, mnemonic);
+		  op_lookup (mnemonic);
 		}
 	      /* For compatibility reasons accept MOVSD and CMPSD without
 	         operands even in AT&T mode.  */
@@ -5980,12 +5987,11 @@ parse_insn (const char *line, char *mnem
 		       || (is_space_char (*l) && l[1] == END_OF_INSN))
 		{
 		  mnem_p[-1] = '\0';
-		  current_templates
-		    = (const templates *) str_hash_find (op_hash, mnemonic);
-		  if (current_templates != NULL
+		  op_lookup (mnemonic);
+		  if (current_templates.start != NULL
 		      /* MOVS or CMPS */
-		      && (current_templates->start->base_opcode | 2) == 0xa6
-		      && current_templates->start->opcode_space
+		      && (current_templates.start->base_opcode | 2) == 0xa6
+		      && current_templates.start->opcode_space
 			 == SPACE_BASE
 		      && mnem_p[-2] == 's')
 		    {
@@ -5995,7 +6001,7 @@ parse_insn (const char *line, char *mnem
 		    }
 		  else
 		    {
-		      current_templates = NULL;
+		      current_templates.start = NULL;
 		      mnem_p[-1] = 'd';
 		    }
 		}
@@ -6003,7 +6009,7 @@ parse_insn (const char *line, char *mnem
 	    }
 	}
 
-      if (!current_templates)
+      if (!current_templates.start)
 	{
 	  if (pass1)
 	    as_bad (_("no such instruction: `%s'"), token_start);
@@ -6011,8 +6017,8 @@ parse_insn (const char *line, char *mnem
 	}
     }
 
-  if (current_templates->start->opcode_modifier.jump == JUMP
-      || current_templates->start->opcode_modifier.jump == JUMP_BYTE)
+  if (current_templates.start->opcode_modifier.jump == JUMP
+      || current_templates.start->opcode_modifier.jump == JUMP_BYTE)
     {
       /* Check for a branch hint.  We allow ",pt" and ",pn" for
 	 predict taken and predict not taken respectively.
@@ -6046,7 +6052,7 @@ parse_insn (const char *line, char *mnem
 
   /* Check if instruction is supported on specified architecture.  */
   supported = 0;
-  for (t = current_templates->start; t < current_templates->end; ++t)
+  for (t = current_templates.start; t < current_templates.end; ++t)
     {
       supported |= cpu_flags_match (t);
 
@@ -6313,7 +6319,7 @@ optimize_imm (void)
 	       /* A more generic (but also more involved) way of dealing
 		  with the special case(s) would be to go look for
 		  DefaultSize attributes on any of the templates.  */
-	       && current_templates->start->mnem_off != MN_push))
+	       && current_templates.start->mnem_off != MN_push))
     guess_suffix = LONG_MNEM_SUFFIX;
 
   for (op = i.operands; --op >= 0;)
@@ -6387,7 +6393,7 @@ optimize_imm (void)
 	       than those matching the insn suffix.  */
 	    {
 	      i386_operand_type mask, allowed;
-	      const insn_template *t = current_templates->start;
+	      const insn_template *t = current_templates.start;
 
 	      operand_type_set (&mask, 0);
 	      switch (guess_suffix)
@@ -6410,7 +6416,7 @@ optimize_imm (void)
 		}
 
 	      allowed = operand_type_and (t->operand_types[op], mask);
-	      while (++t < current_templates->end)
+	      while (++t < current_templates.end)
 		{
 		  allowed = operand_type_or (allowed, t->operand_types[op]);
 		  allowed = operand_type_and (allowed, mask);
@@ -7034,7 +7040,7 @@ match_template (char mnem_suffix)
   found_reverse_match = 0;
   addr_prefix_disp = -1;
 
-  for (t = current_templates->start; t < current_templates->end; t++)
+  for (t = current_templates.start; t < current_templates.end; t++)
     {
       addr_prefix_disp = -1;
       found_reverse_match = 0;
@@ -7483,11 +7489,11 @@ match_template (char mnem_suffix)
 	 Vxy / Exy constructs: There are 3 suffix-less EVEX forms, the latter
 	 two of which may fall back to their two corresponding VEX forms.  */
       j = t->mnem_off != MN_vcvtneps2bf16 ? 1 : 2;
-      if ((t == current_templates->start || j > 1)
+      if ((t == current_templates.start || j > 1)
 	  && t->opcode_modifier.disp8memshift
 	  && !t->opcode_modifier.vex
 	  && !need_evex_encoding ()
-	  && t + j < current_templates->end
+	  && t + j < current_templates.end
 	  && t[j].opcode_modifier.vex)
 	{
 	  i386_cpu_flags cpu;
@@ -7515,7 +7521,7 @@ match_template (char mnem_suffix)
 
 #undef progress
 
-  if (t == current_templates->end)
+  if (t == current_templates.end)
     {
       /* We found no match.  */
       i.error = specific_error;
@@ -10942,7 +10948,6 @@ s_insn (int dummy ATTRIBUTE_UNUSED)
   unsigned int j;
   valueT val;
   bool vex = false, xop = false, evex = false;
-  static const templates tt = { &i.tm, &i.tm + 1 };
 
   init_globals ();
 
@@ -10960,7 +10965,8 @@ s_insn (int dummy ATTRIBUTE_UNUSED)
     }
   line += end - line;
 
-  current_templates = &tt;
+  current_templates.start = &i.tm;
+  current_templates.end = &i.tm + 1;
   i.tm.mnem_off = MN__insn;
   i.tm.extension_opcode = None;
 
@@ -12177,8 +12183,8 @@ i386_displacement (char *disp_start, cha
   operand_type_set (&bigdisp, 0);
   if (i.jumpabsolute
       || i.types[this_operand].bitfield.baseindex
-      || (current_templates->start->opcode_modifier.jump != JUMP
-	  && current_templates->start->opcode_modifier.jump != JUMP_DWORD))
+      || (current_templates.start->opcode_modifier.jump != JUMP
+	  && current_templates.start->opcode_modifier.jump != JUMP_DWORD))
     {
       i386_addressing_mode ();
       override = (i.prefix[ADDR_PREFIX] != 0);
@@ -12199,24 +12205,18 @@ i386_displacement (char *disp_start, cha
 	 dependent upon data size, but is never dependent upon address size.
 	 Also make sure to not unintentionally match against a non-PC-relative
 	 branch template.  */
-      static templates aux_templates;
-      const insn_template *t = current_templates->start;
+      const insn_template *t = current_templates.start;
       bool has_intel64 = false;
 
-      aux_templates.start = t;
-      while (++t < current_templates->end)
+      while (++t < current_templates.end)
 	{
 	  if (t->opcode_modifier.jump
-	      != current_templates->start->opcode_modifier.jump)
+	      != current_templates.start->opcode_modifier.jump)
 	    break;
 	  if ((t->opcode_modifier.isa64 >= INTEL64))
 	    has_intel64 = true;
 	}
-      if (t < current_templates->end)
-	{
-	  aux_templates.end = t;
-	  current_templates = &aux_templates;
-	}
+      current_templates.end = t;
 
       override = (i.prefix[DATA_PREFIX] != 0);
       if (flag_code == CODE_64BIT)
@@ -12389,7 +12389,7 @@ i386_finalize_displacement (segT exp_seg
     }
 #endif
 
-  else if (current_templates->start->opcode_modifier.jump == JUMP_BYTE)
+  else if (current_templates.start->opcode_modifier.jump == JUMP_BYTE)
     i.types[this_operand].bitfield.disp8 = 1;
 
   /* Check if this is a displacement only operand.  */
@@ -12413,7 +12413,7 @@ i386_addressing_mode (void)
   if (i.prefix[ADDR_PREFIX])
     addr_mode = flag_code == CODE_32BIT ? CODE_16BIT : CODE_32BIT;
   else if (flag_code == CODE_16BIT
-	   && is_cpu (current_templates->start, CpuMPX)
+	   && is_cpu (current_templates.start, CpuMPX)
 	   /* Avoid replacing the "16-bit addressing not allowed" diagnostic
 	      from md_assemble() by "is not a valid base/index expression"
 	      when there is a base and/or index.  */
@@ -12486,7 +12486,7 @@ i386_index_check (const char *operand_st
 {
   const char *kind = "base/index";
   enum flag_code addr_mode = i386_addressing_mode ();
-  const insn_template *t = current_templates->end - 1;
+  const insn_template *t = current_templates.end - 1;
 
   if (t->opcode_modifier.isstring)
     {
@@ -12553,7 +12553,7 @@ i386_index_check (const char *operand_st
     }
   else
     {
-      t = current_templates->start;
+      t = current_templates.start;
 
       if (addr_mode != CODE_16BIT)
 	{
@@ -12678,7 +12678,7 @@ i386_att_operand (char *operand_string)
   /* We check for an absolute prefix (differentiating,
      for example, 'jmp pc_relative_label' from 'jmp *absolute_label'.  */
   if (*op_string == ABSOLUTE_PREFIX
-      && current_templates->start->opcode_modifier.jump)
+      && current_templates.start->opcode_modifier.jump)
     {
       ++op_string;
       if (is_space_char (*op_string))
@@ -12710,7 +12710,7 @@ i386_att_operand (char *operand_string)
 
 	  /* Handle case of %es:*foo.  */
 	  if (!i.jumpabsolute && *op_string == ABSOLUTE_PREFIX
-	      && current_templates->start->opcode_modifier.jump)
+	      && current_templates.start->opcode_modifier.jump)
 	    {
 	      ++op_string;
 	      if (is_space_char (*op_string))
@@ -12767,7 +12767,7 @@ i386_att_operand (char *operand_string)
 	    if (i.rounding.type == RC_NamesTable[j].type)
 	      break;
 	  as_bad (_("`%s': misplaced `{%s}'"),
-		  insn_name (current_templates->start), RC_NamesTable[j].name);
+		  insn_name (current_templates.start), RC_NamesTable[j].name);
 	  return 0;
 	}
     }
@@ -12789,7 +12789,7 @@ i386_att_operand (char *operand_string)
       if (i.rounding.type != rc_none)
 	{
 	  as_bad (_("`%s': RC/SAE operand must follow immediate operands"),
-		  insn_name (current_templates->start));
+		  insn_name (current_templates.start));
 	  return 0;
 	}
     }
@@ -12802,7 +12802,7 @@ i386_att_operand (char *operand_string)
 	      && i.op[0].regs->reg_type.bitfield.class != Reg))
 	{
 	  as_bad (_("`%s': misplaced `%s'"),
-		  insn_name (current_templates->start), operand_string);
+		  insn_name (current_templates.start), operand_string);
 	  return 0;
 	}
     }
--- a/gas/config/tc-i386-intel.c
+++ b/gas/config/tc-i386-intel.c
@@ -345,7 +345,7 @@ i386_intel_simplify_register (expression
     intel_state.base = i386_regtab + reg_num;
   else if (!intel_state.index)
     {
-      const insn_template *t = current_templates->start;
+      const insn_template *t = current_templates.start;
 
       if (intel_state.in_scale
 	  || i386_regtab[reg_num].reg_type.bitfield.baseindex
@@ -614,7 +614,7 @@ i386_intel_operand (char *operand_string
       if (i.imm_operands)
 	{
 	  as_bad (_("`%s': RC/SAE operand must precede immediate operands"),
-		  insn_name (current_templates->start));
+		  insn_name (current_templates.start));
 	  return 0;
 	}
 
@@ -687,7 +687,7 @@ i386_intel_operand (char *operand_string
     return 0;
 
   if (intel_state.op_modifier != O_absent
-      && current_templates->start->mnem_off != MN_lea)
+      && current_templates.start->mnem_off != MN_lea)
     {
       i.types[this_operand].bitfield.unspecified = 0;
 
@@ -702,22 +702,22 @@ i386_intel_operand (char *operand_string
 	  i.types[this_operand].bitfield.word = 1;
 	  if (got_a_float == 2)	/* "fi..." */
 	    suffix = SHORT_MNEM_SUFFIX;
-	  else if (current_templates->start->mnem_off != MN_lar
-		   && current_templates->start->mnem_off != MN_lsl
-		   && current_templates->start->mnem_off != MN_arpl)
+	  else if (current_templates.start->mnem_off != MN_lar
+		   && current_templates.start->mnem_off != MN_lsl
+		   && current_templates.start->mnem_off != MN_arpl)
 	    suffix = WORD_MNEM_SUFFIX;
 	  break;
 
 	case O_dword_ptr:
 	  i.types[this_operand].bitfield.dword = 1;
-	  if ((insn_name (current_templates->start)[0] == 'l'
-	       && insn_name (current_templates->start)[2] == 's'
-	       && insn_name (current_templates->start)[3] == 0)
-	      || current_templates->start->mnem_off == MN_bound)
+	  if ((insn_name (current_templates.start)[0] == 'l'
+	       && insn_name (current_templates.start)[2] == 's'
+	       && insn_name (current_templates.start)[3] == 0)
+	      || current_templates.start->mnem_off == MN_bound)
 	    suffix = WORD_MNEM_SUFFIX;
 	  else if (flag_code != CODE_32BIT
-		   && (current_templates->start->opcode_modifier.jump == JUMP
-		       || current_templates->start->opcode_modifier.jump
+		   && (current_templates.start->opcode_modifier.jump == JUMP
+		       || current_templates.start->opcode_modifier.jump
 			  == JUMP_DWORD))
 	    {
 	      i.far_branch = true;
@@ -731,11 +731,11 @@ i386_intel_operand (char *operand_string
 
 	case O_fword_ptr:
 	  i.types[this_operand].bitfield.fword = 1;
-	  if (current_templates->start->mnem_off == MN_les
-	      || current_templates->start->mnem_off == MN_lds
-	      || current_templates->start->mnem_off == MN_lss
-	      || current_templates->start->mnem_off == MN_lfs
-	      || current_templates->start->mnem_off == MN_lgs)
+	  if (current_templates.start->mnem_off == MN_les
+	      || current_templates.start->mnem_off == MN_lds
+	      || current_templates.start->mnem_off == MN_lss
+	      || current_templates.start->mnem_off == MN_lfs
+	      || current_templates.start->mnem_off == MN_lgs)
 	    suffix = LONG_MNEM_SUFFIX;
 	  else if (!got_a_float)
 	    {
@@ -747,7 +747,7 @@ i386_intel_operand (char *operand_string
 
 	case O_qword_ptr: /* O_mmword_ptr */
 	  i.types[this_operand].bitfield.qword = 1;
-	  if (current_templates->start->mnem_off == MN_bound
+	  if (current_templates.start->mnem_off == MN_bound
 	      || got_a_float == 1)	/* "f..." */
 	    suffix = LONG_MNEM_SUFFIX;
 	  else
@@ -759,10 +759,10 @@ i386_intel_operand (char *operand_string
 	  if (got_a_float)
 	    break;
 	  if (flag_code == CODE_64BIT
-	      && (current_templates->start->operand_types[0].bitfield.fword
-		  || current_templates->start->operand_types[0].bitfield.tbyte
-		  || current_templates->start->opcode_modifier.jump == JUMP_DWORD
-		  || current_templates->start->opcode_modifier.jump == JUMP))
+	      && (current_templates.start->operand_types[0].bitfield.fword
+		  || current_templates.start->operand_types[0].bitfield.tbyte
+		  || current_templates.start->opcode_modifier.jump == JUMP_DWORD
+		  || current_templates.start->opcode_modifier.jump == JUMP))
 	    suffix = QWORD_MNEM_SUFFIX; /* l[fgs]s, [ls][gi]dt, call, jmp */
 	  else
 	    i.types[this_operand].bitfield.byte = 1; /* cause an error */
@@ -794,8 +794,8 @@ i386_intel_operand (char *operand_string
 	  i.far_branch = true;
 	  /* FALLTHROUGH */
 	case O_near_ptr:
-	  if (current_templates->start->opcode_modifier.jump != JUMP
-	      && current_templates->start->opcode_modifier.jump != JUMP_DWORD)
+	  if (current_templates.start->opcode_modifier.jump != JUMP
+	      && current_templates.start->opcode_modifier.jump != JUMP_DWORD)
 	    {
 	      /* cause an error */
 	      i.types[this_operand].bitfield.byte = 1;
@@ -814,11 +814,11 @@ i386_intel_operand (char *operand_string
 	 REX.W) is going to be derived from it.  For this we check whether the
 	 given suffix is valid for any of the candidate templates.  */
       if (suffix && suffix != i.suffix
-	  && current_templates->start->mnem_off != MN_bound)
+	  && current_templates.start->mnem_off != MN_bound)
 	{
 	  const insn_template *t;
 
-	  for (t = current_templates->start; t < current_templates->end; ++t)
+	  for (t = current_templates.start; t < current_templates.end; ++t)
 	    {
 	      /* Operands haven't been swapped yet.  */
 	      unsigned int op = t->operands - 1 - this_operand;
@@ -879,7 +879,7 @@ i386_intel_operand (char *operand_string
 	      break;
 	    }
 
-	  if (t == current_templates->end)
+	  if (t == current_templates.end)
 	    suffix = 0;
 	}
 
@@ -893,9 +893,9 @@ i386_intel_operand (char *operand_string
     }
 
   /* Operands for jump/call need special consideration.  */
-  if (current_templates->start->opcode_modifier.jump == JUMP
-      || current_templates->start->opcode_modifier.jump == JUMP_DWORD
-      || current_templates->start->opcode_modifier.jump == JUMP_INTERSEGMENT)
+  if (current_templates.start->opcode_modifier.jump == JUMP
+      || current_templates.start->opcode_modifier.jump == JUMP_DWORD
+      || current_templates.start->opcode_modifier.jump == JUMP_INTERSEGMENT)
     {
       bool jumpabsolute = false;
 
@@ -1005,7 +1005,7 @@ i386_intel_operand (char *operand_string
 	    if (i.rounding.type == RC_NamesTable[j].type)
 	      break;
 	  as_bad (_("`%s': misplaced `{%s}'"),
-		  insn_name (current_templates->start), RC_NamesTable[j].name);
+		  insn_name (current_templates.start), RC_NamesTable[j].name);
 	  return 0;
 	}
     }
@@ -1031,9 +1031,9 @@ i386_intel_operand (char *operand_string
 	     ljmp	0x9090,0x90909090
 	   */
 
-	  if ((current_templates->start->opcode_modifier.jump == JUMP_INTERSEGMENT
-	       || current_templates->start->opcode_modifier.jump == JUMP_DWORD
-	       || current_templates->start->opcode_modifier.jump == JUMP)
+	  if ((current_templates.start->opcode_modifier.jump == JUMP_INTERSEGMENT
+	       || current_templates.start->opcode_modifier.jump == JUMP_DWORD
+	       || current_templates.start->opcode_modifier.jump == JUMP)
 	      && this_operand == 1
 	      && intel_state.seg == NULL
 	      && i.mem_operands == 1
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -1883,23 +1883,26 @@ process_i386_opcodes (FILE *table)
 
   /* Generate opcode sets array.  */
   fprintf (table, "\n/* i386 opcode sets table.  */\n\n");
-  fprintf (table, "static const insn_template *const i386_op_sets[] =\n{\n");
-  fprintf (table, "  i386_optab,\n");
+  fprintf (table, "typedef unsigned short i386_op_off_t;\n");
+  fprintf (table, "static const i386_op_off_t i386_op_sets[] =\n{\n ");
 
   for (nr = j = 0; j < i; j++)
     {
       struct opcode_entry *next = &opcode_array[j]->entry;
 
+      if ((j + 1) % 8 != 0)
+	fprintf (table, "%5u,", nr);
+      else
+	fprintf (table, "%5u,\n ", nr);
       do
 	{
 	  ++nr;
 	  next = next->next;
 	}
       while (next);
-      fprintf (table, "  i386_optab + %u,\n", nr);
     }
 
-  fprintf (table, "};\n");
+  fprintf (table, "%5u\n};\n", nr);
 
   /* Emit mnemonics and associated #define-s.  */
   qsort (opcode_array, i, sizeof (*opcode_array), mnemonic_cmp);

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-11-20  8:06 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-20  8:06 [PATCH] x86: shrink opcode sets table Jan Beulich

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).