diff options
author | Jan Beulich <jbeulich@novell.com> | 2017-11-30 11:48:13 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2017-11-30 11:48:13 +0100 |
commit | 7ac20022477c163983de77e5b16c016d518ca7bc (patch) | |
tree | a8aaf1aa967b6f7892353eb67cf2029e46622d92 /opcodes/i386-gen.c | |
parent | b5014f7af26ff0fbc1128b5fabdaf3bd5918dd94 (diff) | |
download | gdb-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.c | 59 |
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"); |