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.c94
1 files changed, 41 insertions, 53 deletions
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index 2f4caba..6530a54 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -1175,12 +1175,12 @@ adjust_broadcast_modifier (char **opnd)
return bcst_type;
}
-static int
-process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
+static void
+process_i386_opcode_modifier (FILE *table, char *mod, unsigned int prefix,
+ char **opnd, int lineno)
{
char *str, *next, *last;
bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
- unsigned int regular_encoding = 1;
active_isstring = 0;
@@ -1199,18 +1199,7 @@ process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
{
int val = 1;
if (strcasecmp(str, "Broadcast") == 0)
- {
- val = adjust_broadcast_modifier (opnd);
- regular_encoding = 0;
- }
- else if (strcasecmp(str, "Vex") == 0
- || strncasecmp(str, "Vex=", 4) == 0
- || strcasecmp(str, "EVex") == 0
- || strncasecmp(str, "EVex=", 5) == 0
- || strncasecmp(str, "Disp8MemShift=", 14) == 0
- || strncasecmp(str, "Masking=", 8) == 0
- || strcasecmp(str, "SAE") == 0)
- regular_encoding = 0;
+ val = adjust_broadcast_modifier (opnd);
set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
lineno);
@@ -1231,6 +1220,19 @@ process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
}
}
+ if (prefix)
+ {
+ if (!modifiers[OpcodePrefix].value)
+ modifiers[OpcodePrefix].value = prefix;
+ else if (modifiers[OpcodePrefix].value != prefix)
+ fail (_("%s:%d: Conflicting prefix specifications\n"),
+ filename, lineno);
+ else
+ fprintf (stderr,
+ _("%s:%d: Warning: redundant prefix specification\n"),
+ filename, lineno);
+ }
+
if (have_w && !bwlq_suf)
fail ("%s: %d: stray W modifier\n", filename, lineno);
if (have_w && !(bwlq_suf & 1))
@@ -1242,8 +1244,6 @@ process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
filename, lineno);
}
output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
-
- return regular_encoding;
}
enum stage {
@@ -1355,9 +1355,10 @@ static void
output_i386_opcode (FILE *table, const char *name, char *str,
char *last, int lineno)
{
- unsigned int i;
- char *base_opcode, *extension_opcode, *opcode_length;
+ unsigned int i, prefix = 0;
+ char *base_opcode, *extension_opcode, *opcode_length, *end;
char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
+ unsigned long int opcode, length;
/* Find base_opcode. */
base_opcode = next_field (str, ',', &str, last);
@@ -1407,46 +1408,33 @@ output_i386_opcode (FILE *table, const char *name, char *str,
}
}
- fprintf (table, " { \"%s\", %s, %s, %s, %u,\n",
- name, base_opcode, extension_opcode, opcode_length, i);
+ length = strtoul (opcode_length, &end, 0);
+ opcode = strtoul (base_opcode, &end, 0);
- if (process_i386_opcode_modifier (table, opcode_modifier,
- operand_types, lineno))
+ /* Transform prefixes encoded in the opcode into opcode modifier
+ representation. */
+ if (length < 4)
{
- char *end;
- unsigned long int length = strtoul (opcode_length, &end, 0);
- unsigned long int opcode = strtoul (base_opcode, &end, 0);
- switch (length)
+ switch (opcode >> (8 * length))
{
- case 4:
- break;
- case 3:
- if ((opcode >> 24) != 0)
- fail (_("%s: %s: (base_opcode >> 24) != 0: %s\n"),
- filename, name, base_opcode);
- break;
- case 2:
- if ((opcode >> 16) != 0)
- fail (_("%s: %s: (base_opcode >> 16) != 0: %s\n"),
- filename, name, base_opcode);
- break;
- case 1:
- if ((opcode >> 8) != 0)
- fail (_("%s: %s: (base_opcode >> 8) != 0: %s\n"),
- filename, name, base_opcode);
- break;
- case 0:
- if (opcode != 0)
- fail (_("%s: %s: base_opcode != 0: %s\n"),
- filename, name, base_opcode);
- break;
+ case 0: break;
+ case 0x66: prefix = PREFIX_0X66; break;
+ case 0xF3: prefix = PREFIX_0XF3; break;
+ case 0xF2: prefix = PREFIX_0XF2; break;
default:
- fail (_("%s: %s: invalid opcode length: %s\n"),
- filename, name, opcode_length);
- break;
+ fail (_("%s:%d: %s: Unexpected opcode prefix %02lx\n"),
+ filename, lineno, name, opcode >> (8 * length));
}
+
+ opcode &= (1UL << (8 * length)) - 1;
}
+ fprintf (table, " { \"%s\", 0x%0*lx%s, %s, %lu, %u,\n",
+ name, 2 * (int)length, opcode, end, extension_opcode, length, i);
+
+ process_i386_opcode_modifier (table, opcode_modifier, prefix,
+ operand_types, lineno);
+
process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
fprintf (table, " { ");
@@ -1836,7 +1824,7 @@ process_i386_opcodes (FILE *table)
fprintf (table, " { NULL, 0, 0, 0, 0,\n");
- process_i386_opcode_modifier (table, "0", NULL, -1);
+ process_i386_opcode_modifier (table, "0", 0, NULL, -1);
process_i386_cpu_flag (table, "0", 0, ",", " ", -1);