summaryrefslogtreecommitdiff
path: root/opcodes/i386-gen.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2020-10-14 04:17:54 -0700
committerH.J. Lu <hjl.tools@gmail.com>2020-10-14 04:20:55 -0700
commit8b65b8953af2d49ae1d2d7fcc5b49c5308febbc1 (patch)
tree6787d9d057850f28f7fd940774843b80871ab90b /opcodes/i386-gen.c
parent8c8bd0babc6039a4cef7d60d57b1b68e7a7f2e70 (diff)
downloadbinutils-gdb-8b65b8953af2d49ae1d2d7fcc5b49c5308febbc1.tar.gz
x86: Remove the prefix byte from non-VEX/EVEX base_opcode
Replace the prefix byte in non-VEX/EVEX base_opcode with PREFIX_0X66, PREFIX_0XF2 or PREFIX_0XF3. gas/ * config/tc-i386.c (load_insn_p): Check opcodeprefix == 0 for base_opcode == 0xfc7. (match_template): Likewise. (process_suffix): Check opcodeprefix == PREFIX_0XF2 for CRC32. (check_byte_reg): Likewise. (output_insn): Don't add the 0xf3 prefix twice for PadLock instructions. Don't add prefix from non-VEX/EVEX base_opcode. opcodes/ * i386-gen.c (process_i386_opcode_modifier): Return 1 for non-VEX/EVEX/prefix encoding. (output_i386_opcode): Fail if non-VEX/EVEX/prefix base_opcode has a prefix byte. * i386-opc.tbl: Replace the prefix byte in non-VEX/EVEX base_opcode with PREFIX_0X66, PREFIX_0XF2 or PREFIX_0XF3. * i386-tbl.h: Regenerated.
Diffstat (limited to 'opcodes/i386-gen.c')
-rw-r--r--opcodes/i386-gen.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index 81c68cdf433..8a42eb93efe 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -1161,11 +1161,12 @@ adjust_broadcast_modifier (char **opnd)
return bcst_type;
}
-static void
+static int
process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
{
char *str, *next, *last;
bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
+ unsigned int regular_encoding = 1;
active_isstring = 0;
@@ -1184,9 +1185,22 @@ 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
+ || strcasecmp(str, "IsPrefix") == 0)
+ regular_encoding = 0;
+
set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
- lineno);
+ lineno);
if (strcasecmp(str, "IsString") == 0)
active_isstring = 1;
@@ -1215,6 +1229,8 @@ 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 {
@@ -1396,7 +1412,40 @@ output_i386_opcode (FILE *table, const char *name, char *str,
process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
- process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
+ if (process_i386_opcode_modifier (table, opcode_modifier,
+ operand_types, lineno))
+ {
+ char *end;
+ unsigned long int length = strtoul (opcode_length, &end, 0);
+ unsigned long int opcode = strtoul (base_opcode, &end, 0);
+ switch (length)
+ {
+ 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;
+ default:
+ fail (_("%s: %s: invalid opcode length: %s\n"),
+ filename, name, opcode_length);
+ break;
+ }
+ }
fprintf (table, " { ");