diff options
author | Jan Beulich <jbeulich@suse.com> | 2023-08-11 10:04:49 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2023-08-11 10:04:49 +0200 |
commit | 734dfd1cc966aff736eaeda68bfa4807ee4b50c1 (patch) | |
tree | 886eaf6a72d949950ce5aa63f17706f8297a2e19 /opcodes/i386-gen.c | |
parent | e416bd75c3fd471c1e0222a72b17f6c585b37e93 (diff) | |
download | fsf-binutils-gdb-734dfd1cc966aff736eaeda68bfa4807ee4b50c1.zip fsf-binutils-gdb-734dfd1cc966aff736eaeda68bfa4807ee4b50c1.tar.gz fsf-binutils-gdb-734dfd1cc966aff736eaeda68bfa4807ee4b50c1.tar.bz2 |
x86: pack CPU flags in opcode table
The table constantly growing in two dimensions (number of table entries
times number of ISA extension flags) doesn't scale very well. Use a more
compact representation: Only identifiers which need to combine with
other identifiers retain individual flag bits. All others are combined
into an enum, with a new helper added to transform the table entries
into the original i386_cpu_flags layout. This way the table in the final
binary shrinks by almost a third (the generated source code shrinks by
about half), and isn't likely to grow again in that dimension any time
soon.
While moving the 3DNow! fields, drop the stray inner 'a' from their
names.
Diffstat (limited to 'opcodes/i386-gen.c')
-rw-r--r-- | opcodes/i386-gen.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c index 91c22c9..30430a2 100644 --- a/opcodes/i386-gen.c +++ b/opcodes/i386-gen.c @@ -774,21 +774,41 @@ add_isa_dependencies (bitfield *flags, const char *f, int value, static void output_cpu_flags (FILE *table, bitfield *flags, unsigned int size, - int macro, const char *comma, const char *indent) + int macro, const char *comma, const char *indent, int lineno) { - unsigned int i; + unsigned int i = 0, j = 0; memset (&active_cpu_flags, 0, sizeof(active_cpu_flags)); fprintf (table, "%s{ { ", indent); - for (i = 0; i < size - 1; i++) + if (!macro) { - if (((i + 1) % 20) != 0) + for (j = ~0u; i < CpuAttrEnums; i++) + { + if (!flags[i].value) + continue; + + if (j < ~0u) + fail ("%s: %d: invalid combination of CPU identifiers\n", + filename, lineno); + j = i; + active_cpu_flags.array[i / 32] |= 1U << (i % 32); + } + + /* Write 0 to indicate "no associated flag". */ + fprintf (table, "%u, ", j + 1); + + j = 1; + } + + for (; i < size - 1; i++, j++) + { + if (((j + 1) % 20) != 0) fprintf (table, "%d, ", flags[i].value); else fprintf (table, "%d,", flags[i].value); - if (((i + 1) % 20) == 0) + if (((j + 1) % 20) == 0) { /* We need \\ for macro. */ if (macro) @@ -899,7 +919,7 @@ process_i386_cpu_flag (FILE *table, char *flag, } output_cpu_flags (table, flags, ARRAY_SIZE (flags), name != NULL, - comma, indent); + comma, indent, lineno); } static void @@ -2073,6 +2093,16 @@ main (int argc, char **argv) fail ("%d unused bits in i386_cpu_flags.\n", c); #endif + /* If this triggers, CpuIsaBits needs to be increased. */ + static_assert (CpuAttrEnums <= (1u << CpuIsaBits)); + + /* Check the unused bitfield in i386_cpu_attr. */ +#ifndef CpuAttrUnused + c = CpuAttrNumOfBits - (CpuIsaBits + CpuMax + 1 - CpuAttrEnums); + if (c) + fail ("%d unused bits in i386_cpu_attr.\n", c); +#endif + static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num); /* Check the unused bitfield in i386_operand_type. */ |