aboutsummaryrefslogtreecommitdiff
path: root/opcodes/i386-gen.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2017-11-30 11:48:13 +0100
committerJan Beulich <jbeulich@suse.com>2017-11-30 11:48:13 +0100
commit7ac20022477c163983de77e5b16c016d518ca7bc (patch)
treea8aaf1aa967b6f7892353eb67cf2029e46622d92 /opcodes/i386-gen.c
parentb5014f7af26ff0fbc1128b5fabdaf3bd5918dd94 (diff)
downloadgdb-7ac20022477c163983de77e5b16c016d518ca7bc.zip
gdb-7ac20022477c163983de77e5b16c016d518ca7bc.tar.gz
gdb-7ac20022477c163983de77e5b16c016d518ca7bc.tar.bz2
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.
Diffstat (limited to 'opcodes/i386-gen.c')
-rw-r--r--opcodes/i386-gen.c59
1 files changed, 48 insertions, 11 deletions
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index c5e8670..dba076c 100644
--- 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 *flags, unsigned int size,
{
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 *flags, unsigned int size,
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 *table, char *mod, int lineno)
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 *table, char *mod, int lineno)
{
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, bitfield *types, unsigned int size,
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, bitfield *types, unsigned int size,
}
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, char *op, int macro,
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 char *name, char *str,
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");