aboutsummaryrefslogtreecommitdiff
path: root/opcodes/i386-gen.c
diff options
context:
space:
mode:
Diffstat (limited to 'opcodes/i386-gen.c')
-rw-r--r--opcodes/i386-gen.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index 1595f89..f514135 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -1176,8 +1176,8 @@ adjust_broadcast_modifier (char **opnd)
}
static void
-process_i386_opcode_modifier (FILE *table, char *mod, unsigned int prefix,
- char **opnd, int lineno)
+process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
+ unsigned int prefix, char **opnd, int lineno)
{
char *str, *next, *last;
bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
@@ -1220,6 +1220,19 @@ process_i386_opcode_modifier (FILE *table, char *mod, unsigned int prefix,
}
}
+ if (space)
+ {
+ if (!modifiers[OpcodeSpace].value)
+ modifiers[OpcodeSpace].value = space;
+ else if (modifiers[OpcodeSpace].value != space)
+ fail (_("%s:%d: Conflicting opcode space specifications\n"),
+ filename, lineno);
+ else
+ fprintf (stderr,
+ _("%s:%d: Warning: redundant opcode space specification\n"),
+ filename, lineno);
+ }
+
if (prefix)
{
if (!modifiers[OpcodePrefix].value)
@@ -1355,7 +1368,7 @@ static void
output_i386_opcode (FILE *table, const char *name, char *str,
char *last, int lineno)
{
- unsigned int i, length, prefix = 0;
+ unsigned int i, length, prefix = 0, space = 0;
char *base_opcode, *extension_opcode, *end;
char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
unsigned long int opcode;
@@ -1427,10 +1440,27 @@ output_i386_opcode (FILE *table, const char *name, char *str,
opcode &= (1UL << (8 * --length)) - 1;
}
+ /* Transform opcode space encoded in the opcode into opcode modifier
+ representation. */
+ if (length > 1 && (opcode >> (8 * length - 8)) == 0xf)
+ {
+ switch ((opcode >> (8 * length - 16)) & 0xff)
+ {
+ default: space = SPACE_0F; break;
+ case 0x38: space = SPACE_0F38; break;
+ case 0x3A: space = SPACE_0F3A; break;
+ }
+
+ if (space != SPACE_0F && --length == 1)
+ fail (_("%s:%d: %s: unrecognized opcode encoding space\n"),
+ filename, lineno, name);
+ opcode &= (1UL << (8 * --length)) - 1;
+ }
+
fprintf (table, " { \"%s\", 0x%0*lx%s, %s, %lu,\n",
name, 2 * (int)length, opcode, end, extension_opcode, i);
- process_i386_opcode_modifier (table, opcode_modifier, prefix,
+ process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
operand_types, lineno);
process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
@@ -1822,7 +1852,7 @@ process_i386_opcodes (FILE *table)
fprintf (table, " { NULL, 0, 0, 0,\n");
- process_i386_opcode_modifier (table, "0", 0, NULL, -1);
+ process_i386_opcode_modifier (table, "0", 0, 0, NULL, -1);
process_i386_cpu_flag (table, "0", 0, ",", " ", -1);