This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 2/2] x86: derive DispN from BaseIndex


x86: derive DispN from BaseIndex

BaseIndex implies - with the exception of string instructions the
optional presence of a displacement. This is almost completely uniform
for all instructions (the sole exception being MPX ones, which don't
allow 16-bit addressing and hence Disp16), so there's no point in
explicitly stating this in the main opcode table. Drop those explict
specifications in favor of adding logic to i386-gen, shrinking the
table size quite a bit and hence making it more readable.

The opcodes/i386-tbl.h changes are due to a few cases where pointless
Disp* still hadn't been removed from their insns.

opcodes/
2017-11-29  Jan Beulich  <jbeulich@suse.com>

	* i386-gen.c (active_cpu_flags, active_isstring, enum stage):
	New.
	(output_cpu_flags): Update active_cpu_flags.
	(process_i386_opcode_modifier): Update active_isstring.
	(output_operand_type): Rename "macro" 	parameter to "stage",
	changing its type.
	(process_i386_operand_type): Likewise. Track presence of
	BaseIndex and emit DispN accordingly.
	(output_i386_opcode, process_i386_registers,
	process_i386_initializers): Adjust calls to
	process_i386_operand_type() for its changed parameter type.
	* i386-opc.tbl: Drop Disp8, Disp16, Disp32, and Disp32S from
	all insns operands having BaseIndex set.
	* i386-tbl.h: Re-generate.
---
For readability and to meet size constraints I've removed not only the
re-generated bits, but also the purely mechanical i386-opc.tbl changes
from the inline patch. The compressed attachment contains them, though.

--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -686,6 +686,8 @@ static bitfield operand_types[] =
 };
 
 static const char *filename;
+static i386_cpu_flags active_cpu_flags;
+static int active_isstring;
 
 static int
 compare (const void *x, const void *y)
@@ -876,6 +878,8 @@ output_cpu_flags (FILE *table, bitfield
 {
   unsigned int i;
 
+  memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
+
   fprintf (table, "%s{ { ", indent);
 
   for (i = 0; i < size - 1; i++)
@@ -892,6 +896,8 @@ output_cpu_flags (FILE *table, bitfield
 	  else
 	    fprintf (table, "\n    %s", indent);
 	}
+      if (flags[i].value)
+	active_cpu_flags.array[i / 32] |= 1U << (i % 32);
     }
 
   fprintf (table, "%d } }%s\n", flags[i].value, comma);
@@ -988,6 +994,8 @@ process_i386_opcode_modifier (FILE *tabl
   char *str, *next, *last;
   bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
 
+  active_isstring = 0;
+
   /* Copy the default opcode modifier.  */
   memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
 
@@ -998,16 +1006,26 @@ process_i386_opcode_modifier (FILE *tabl
 	{
 	  str = next_field (next, '|', &next, last);
 	  if (str)
-	    set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
+	    {
+	      set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
 			  lineno);
+	      if (strcasecmp(str, "IsString") == 0)
+		active_isstring = 1;
+	    }
 	}
     }
   output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
 }
 
+enum stage {
+  stage_macros,
+  stage_opcodes,
+  stage_registers,
+};
+
 static void
 output_operand_type (FILE *table, bitfield *types, unsigned int size,
-		     int macro, const char *indent)
+		     enum stage stage, const char *indent)
 {
   unsigned int i;
 
@@ -1022,7 +1040,7 @@ output_operand_type (FILE *table, bitfie
       if (((i + 1) % 20) == 0)
 	{
 	  /* We need \\ for macro.  */
-	  if (macro)
+	  if (stage == stage_macros)
 	    fprintf (table, " \\\n%s", indent);
 	  else
 	    fprintf (table, "\n%s", indent);
@@ -1033,7 +1051,7 @@ output_operand_type (FILE *table, bitfie
 }
 
 static void
-process_i386_operand_type (FILE *table, char *op, int macro,
+process_i386_operand_type (FILE *table, char *op, enum stage stage,
 			   const char *indent, int lineno)
 {
   char *str, *next, *last;
@@ -1044,15 +1062,32 @@ process_i386_operand_type (FILE *table,
 
   if (strcmp (op, "0"))
     {
+      int baseindex = 0;
+
       last = op + strlen (op);
       for (next = op; next && next < last; )
 	{
 	  str = next_field (next, '|', &next, last);
 	  if (str)
-	    set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
+	    {
+	      set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
+	      if (strcasecmp(str, "BaseIndex") == 0)
+		baseindex = 1;
+	    }
+	}
+
+      if (stage == stage_opcodes && baseindex && !active_isstring)
+	{
+	  set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
+	  if (!active_cpu_flags.bitfield.cpu64
+	      && !active_cpu_flags.bitfield.cpumpx)
+	    set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
+	  set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
+	  if (!active_cpu_flags.bitfield.cpuno64)
+	    set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
 	}
     }
-  output_operand_type (table, types, ARRAY_SIZE (types), macro,
+  output_operand_type (table, types, ARRAY_SIZE (types), stage,
 		       indent);
 }
 
@@ -1140,14 +1175,15 @@ output_i386_opcode (FILE *table, const c
       if (operand_types[i] == NULL || *operand_types[i] == '0')
 	{
 	  if (i == 0)
-	    process_i386_operand_type (table, "0", 0, "\t  ", lineno);
+	    process_i386_operand_type (table, "0", stage_opcodes, "\t  ",
+				       lineno);
 	  break;
 	}
 
       if (i != 0)
 	fprintf (table, ",\n      ");
 
-      process_i386_operand_type (table, operand_types[i], 0,
+      process_i386_operand_type (table, operand_types[i], stage_opcodes,
 				 "\t  ", lineno);
     }
   fprintf (table, " } },\n");
@@ -1309,7 +1345,7 @@ process_i386_opcodes (FILE *table)
   process_i386_opcode_modifier (table, "0", -1);
 
   fprintf (table, "    { ");
-  process_i386_operand_type (table, "0", 0, "\t  ", -1);
+  process_i386_operand_type (table, "0", stage_opcodes, "\t  ", -1);
   fprintf (table, " } }\n");
 
   fprintf (table, "};\n");
@@ -1378,7 +1414,8 @@ process_i386_registers (FILE *table)
 
       fprintf (table, "  { \"%s\",\n    ", reg_name);
 
-      process_i386_operand_type (table, reg_type, 0, "\t", lineno);
+      process_i386_operand_type (table, reg_type, stage_registers, "\t",
+				 lineno);
 
       /* Find 32-bit Dwarf2 register number.  */
       dw2_32_num = next_field (str, ',', &str, last);
@@ -1422,7 +1459,7 @@ process_i386_initializers (void)
     {
       fprintf (fp, "\n\n#define %s \\\n  ", operand_type_init[i].name);
       init = xstrdup (operand_type_init[i].init);
-      process_i386_operand_type (fp, init, 1, "      ", -1);
+      process_i386_operand_type (fp, init, stage_macros, "      ", -1);
       free (init);
     }
   fprintf (fp, "\n");


Attachment: binutils-master-x86-derive-DispN-from-BaseIndex.patch.bz2
Description: Binary data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]