aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog14
-rw-r--r--gas/config/tc-i386.c100
-rw-r--r--opcodes/ChangeLog18
-rw-r--r--opcodes/i386-gen.c55
-rw-r--r--opcodes/i386-init.h4
-rw-r--r--opcodes/i386-opc.h17
-rw-r--r--opcodes/i386-opc.tbl10
-rw-r--r--opcodes/i386-reg.tbl166
8 files changed, 238 insertions, 146 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 6376ce1..a2937f8 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,17 @@
+2019-11-08 Jan Beulich <jbeulich@suse.com>
+
+ * config/tc-i386.c (operand_type_set, operand_type_and,
+ operand_type_and_not, operand_type_or, operand_type_xor): Handle
+ "class" field specially.
+ (anyimm): New.
+ (operand_type_check, operand_size_match,
+ operand_type_register_match, pi, md_assemble, is_short_form,
+ process_suffix, check_byte_reg, check_long_reg, check_qword_reg,
+ check_word_reg, process_operands, build_modrm_byte): Use "class"
+ instead of "reg" field.
+ (optimize_imm): Likewise. Reduce redundancy. Adjust calculation
+ of "allowed".
+
2019-11-07 Mihail Ionescu <mihail.ionescu@arm.com>
* testsuite/gas/aarch64/dgh.s: New test.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index ad51daf..32f8550 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -1611,6 +1611,8 @@ operand_type_set (union i386_operand_type *x, unsigned int v)
default:
abort ();
}
+
+ x->bitfield.class = ClassNone;
}
static INLINE int
@@ -1825,6 +1827,9 @@ cpu_flags_match (const insn_template *t)
static INLINE i386_operand_type
operand_type_and (i386_operand_type x, i386_operand_type y)
{
+ if (x.bitfield.class != y.bitfield.class)
+ x.bitfield.class = ClassNone;
+
switch (ARRAY_SIZE (x.array))
{
case 3:
@@ -1845,6 +1850,8 @@ operand_type_and (i386_operand_type x, i386_operand_type y)
static INLINE i386_operand_type
operand_type_and_not (i386_operand_type x, i386_operand_type y)
{
+ gas_assert (y.bitfield.class == ClassNone);
+
switch (ARRAY_SIZE (x.array))
{
case 3:
@@ -1865,6 +1872,10 @@ operand_type_and_not (i386_operand_type x, i386_operand_type y)
static INLINE i386_operand_type
operand_type_or (i386_operand_type x, i386_operand_type y)
{
+ gas_assert (x.bitfield.class == ClassNone ||
+ y.bitfield.class == ClassNone ||
+ x.bitfield.class == y.bitfield.class);
+
switch (ARRAY_SIZE (x.array))
{
case 3:
@@ -1885,6 +1896,8 @@ operand_type_or (i386_operand_type x, i386_operand_type y)
static INLINE i386_operand_type
operand_type_xor (i386_operand_type x, i386_operand_type y)
{
+ gas_assert (y.bitfield.class == ClassNone);
+
switch (ARRAY_SIZE (x.array))
{
case 3:
@@ -1906,8 +1919,8 @@ static const i386_operand_type disp16 = OPERAND_TYPE_DISP16;
static const i386_operand_type disp32 = OPERAND_TYPE_DISP32;
static const i386_operand_type disp32s = OPERAND_TYPE_DISP32S;
static const i386_operand_type disp16_32 = OPERAND_TYPE_DISP16_32;
-static const i386_operand_type anydisp
- = OPERAND_TYPE_ANYDISP;
+static const i386_operand_type anydisp = OPERAND_TYPE_ANYDISP;
+static const i386_operand_type anyimm = OPERAND_TYPE_ANYIMM;
static const i386_operand_type regxmm = OPERAND_TYPE_REGXMM;
static const i386_operand_type regmask = OPERAND_TYPE_REGMASK;
static const i386_operand_type imm8 = OPERAND_TYPE_IMM8;
@@ -1934,7 +1947,7 @@ operand_type_check (i386_operand_type t, enum operand_type c)
switch (c)
{
case reg:
- return t.bitfield.reg;
+ return t.bitfield.class == Reg;
case imm:
return (t.bitfield.imm8
@@ -2052,11 +2065,11 @@ operand_size_match (const insn_template *t)
/* Check memory and accumulator operand size. */
for (j = 0; j < i.operands; j++)
{
- if (!i.types[j].bitfield.reg && !i.types[j].bitfield.regsimd
+ if (i.types[j].bitfield.class != Reg && !i.types[j].bitfield.regsimd
&& t->operand_types[j].bitfield.anysize)
continue;
- if (t->operand_types[j].bitfield.reg
+ if (t->operand_types[j].bitfield.class == Reg
&& !match_operand_size (t, j, j))
{
match = 0;
@@ -2099,7 +2112,7 @@ mismatch:
{
unsigned int given = i.operands - j - 1;
- if (t->operand_types[j].bitfield.reg
+ if (t->operand_types[j].bitfield.class == Reg
&& !match_operand_size (t, j, given))
goto mismatch;
@@ -2159,14 +2172,14 @@ operand_type_register_match (i386_operand_type g0,
i386_operand_type g1,
i386_operand_type t1)
{
- if (!g0.bitfield.reg
+ if (g0.bitfield.class != Reg
&& !g0.bitfield.regsimd
&& (!operand_type_check (g0, anymem)
|| g0.bitfield.unspecified
|| !t0.bitfield.regsimd))
return 1;
- if (!g1.bitfield.reg
+ if (g1.bitfield.class != Reg
&& !g1.bitfield.regsimd
&& (!operand_type_check (g1, anymem)
|| g1.bitfield.unspecified
@@ -3032,7 +3045,7 @@ pi (const char *line, i386_insn *x)
fprintf (stdout, " #%d: ", j + 1);
pt (x->types[j]);
fprintf (stdout, "\n");
- if (x->types[j].bitfield.reg
+ if (x->types[j].bitfield.class == Reg
|| x->types[j].bitfield.regmmx
|| x->types[j].bitfield.regsimd
|| x->types[j].bitfield.sreg
@@ -4506,12 +4519,12 @@ md_assemble (char *line)
instruction already has a prefix, we need to convert old
registers to new ones. */
- if ((i.types[0].bitfield.reg && i.types[0].bitfield.byte
+ if ((i.types[0].bitfield.class == Reg && i.types[0].bitfield.byte
&& (i.op[0].regs->reg_flags & RegRex64) != 0)
- || (i.types[1].bitfield.reg && i.types[1].bitfield.byte
+ || (i.types[1].bitfield.class == Reg && i.types[1].bitfield.byte
&& (i.op[1].regs->reg_flags & RegRex64) != 0)
- || (((i.types[0].bitfield.reg && i.types[0].bitfield.byte)
- || (i.types[1].bitfield.reg && i.types[1].bitfield.byte))
+ || (((i.types[0].bitfield.class == Reg && i.types[0].bitfield.byte)
+ || (i.types[1].bitfield.class == Reg && i.types[1].bitfield.byte))
&& i.rex != 0))
{
int x;
@@ -4520,7 +4533,7 @@ md_assemble (char *line)
for (x = 0; x < 2; x++)
{
/* Look for 8 bit operand that uses old registers. */
- if (i.types[x].bitfield.reg && i.types[x].bitfield.byte
+ if (i.types[x].bitfield.class == Reg && i.types[x].bitfield.byte
&& (i.op[x].regs->reg_flags & RegRex64) == 0)
{
/* In case it is "hi" register, give up. */
@@ -4545,7 +4558,7 @@ md_assemble (char *line)
the REX_OPCODE byte. */
int x;
for (x = 0; x < 2; x++)
- if (i.types[x].bitfield.reg
+ if (i.types[x].bitfield.class == Reg
&& i.types[x].bitfield.byte
&& (i.op[x].regs->reg_flags & RegRex64) == 0
&& i.op[x].regs->reg_num > 3)
@@ -5066,22 +5079,24 @@ optimize_imm (void)
but the following works for instructions with immediates.
In any case, we can't set i.suffix yet. */
for (op = i.operands; --op >= 0;)
- if (i.types[op].bitfield.reg && i.types[op].bitfield.byte)
+ if (i.types[op].bitfield.class != Reg)
+ continue;
+ else if (i.types[op].bitfield.byte)
{
guess_suffix = BYTE_MNEM_SUFFIX;
break;
}
- else if (i.types[op].bitfield.reg && i.types[op].bitfield.word)
+ else if (i.types[op].bitfield.word)
{
guess_suffix = WORD_MNEM_SUFFIX;
break;
}
- else if (i.types[op].bitfield.reg && i.types[op].bitfield.dword)
+ else if (i.types[op].bitfield.dword)
{
guess_suffix = LONG_MNEM_SUFFIX;
break;
}
- else if (i.types[op].bitfield.reg && i.types[op].bitfield.qword)
+ else if (i.types[op].bitfield.qword)
{
guess_suffix = QWORD_MNEM_SUFFIX;
break;
@@ -5170,8 +5185,10 @@ optimize_imm (void)
for (t = current_templates->start;
t < current_templates->end;
++t)
- allowed = operand_type_or (allowed,
- t->operand_types[op]);
+ {
+ allowed = operand_type_or (allowed, t->operand_types[op]);
+ allowed = operand_type_and (allowed, anyimm);
+ }
switch (guess_suffix)
{
case QWORD_MNEM_SUFFIX:
@@ -6248,7 +6265,8 @@ process_suffix (void)
Destination register type is more significant than source
register type. crc32 in SSE4.2 prefers source register
type. */
- if (i.tm.base_opcode == 0xf20f38f0 && i.types[0].bitfield.reg)
+ if (i.tm.base_opcode == 0xf20f38f0
+ && i.types[0].bitfield.class == Reg)
{
if (i.types[0].bitfield.byte)
i.suffix = BYTE_MNEM_SUFFIX;
@@ -6276,7 +6294,7 @@ process_suffix (void)
if (!i.tm.operand_types[op].bitfield.inoutportreg
&& !i.tm.operand_types[op].bitfield.shiftcount)
{
- if (!i.types[op].bitfield.reg)
+ if (i.types[op].bitfield.class != Reg)
continue;
if (i.types[op].bitfield.byte)
i.suffix = BYTE_MNEM_SUFFIX;
@@ -6451,7 +6469,7 @@ process_suffix (void)
size prefix, except for instructions that will ignore this
prefix anyway. */
if (i.reg_operands > 0
- && i.types[0].bitfield.reg
+ && i.types[0].bitfield.class == Reg
&& i.tm.opcode_modifier.addrprefixopreg
&& (i.tm.opcode_modifier.immext
|| i.operands == 1))
@@ -6519,7 +6537,7 @@ process_suffix (void)
}
for (op = 0; op < i.operands; op++)
- if (i.types[op].bitfield.reg
+ if (i.types[op].bitfield.class == Reg
&& ((need == need_word
&& !i.op[op].regs->reg_type.bitfield.word)
|| (need == need_dword
@@ -6544,7 +6562,7 @@ check_byte_reg (void)
for (op = i.operands; --op >= 0;)
{
/* Skip non-register operands. */
- if (!i.types[op].bitfield.reg)
+ if (i.types[op].bitfield.class != Reg)
continue;
/* If this is an eight bit register, it's OK. If it's the 16 or
@@ -6583,7 +6601,7 @@ check_byte_reg (void)
continue;
}
/* Any other register is bad. */
- if (i.types[op].bitfield.reg
+ if (i.types[op].bitfield.class == Reg
|| i.types[op].bitfield.regmmx
|| i.types[op].bitfield.regsimd
|| i.types[op].bitfield.sreg
@@ -6609,12 +6627,12 @@ check_long_reg (void)
for (op = i.operands; --op >= 0;)
/* Skip non-register operands. */
- if (!i.types[op].bitfield.reg)
+ if (i.types[op].bitfield.class != Reg)
continue;
/* Reject eight bit registers, except where the template requires
them. (eg. movzb) */
else if (i.types[op].bitfield.byte
- && (i.tm.operand_types[op].bitfield.reg
+ && (i.tm.operand_types[op].bitfield.class == Reg
|| i.tm.operand_types[op].bitfield.acc)
&& (i.tm.operand_types[op].bitfield.word
|| i.tm.operand_types[op].bitfield.dword))
@@ -6629,7 +6647,7 @@ check_long_reg (void)
/* Warn if the e prefix on a general reg is missing. */
else if ((!quiet_warnings || flag_code == CODE_64BIT)
&& i.types[op].bitfield.word
- && (i.tm.operand_types[op].bitfield.reg
+ && (i.tm.operand_types[op].bitfield.class == Reg
|| i.tm.operand_types[op].bitfield.acc)
&& i.tm.operand_types[op].bitfield.dword)
{
@@ -6651,7 +6669,7 @@ check_long_reg (void)
}
/* Warn if the r prefix on a general reg is present. */
else if (i.types[op].bitfield.qword
- && (i.tm.operand_types[op].bitfield.reg
+ && (i.tm.operand_types[op].bitfield.class == Reg
|| i.tm.operand_types[op].bitfield.acc)
&& i.tm.operand_types[op].bitfield.dword)
{
@@ -6680,12 +6698,12 @@ check_qword_reg (void)
for (op = i.operands; --op >= 0; )
/* Skip non-register operands. */
- if (!i.types[op].bitfield.reg)
+ if (i.types[op].bitfield.class != Reg)
continue;
/* Reject eight bit registers, except where the template requires
them. (eg. movzb) */
else if (i.types[op].bitfield.byte
- && (i.tm.operand_types[op].bitfield.reg
+ && (i.tm.operand_types[op].bitfield.class == Reg
|| i.tm.operand_types[op].bitfield.acc)
&& (i.tm.operand_types[op].bitfield.word
|| i.tm.operand_types[op].bitfield.dword))
@@ -6700,7 +6718,7 @@ check_qword_reg (void)
/* Warn if the r prefix on a general reg is missing. */
else if ((i.types[op].bitfield.word
|| i.types[op].bitfield.dword)
- && (i.tm.operand_types[op].bitfield.reg
+ && (i.tm.operand_types[op].bitfield.class == Reg
|| i.tm.operand_types[op].bitfield.acc)
&& i.tm.operand_types[op].bitfield.qword)
{
@@ -6730,12 +6748,12 @@ check_word_reg (void)
int op;
for (op = i.operands; --op >= 0;)
/* Skip non-register operands. */
- if (!i.types[op].bitfield.reg)
+ if (i.types[op].bitfield.class != Reg)
continue;
/* Reject eight bit registers, except where the template requires
them. (eg. movzb) */
else if (i.types[op].bitfield.byte
- && (i.tm.operand_types[op].bitfield.reg
+ && (i.tm.operand_types[op].bitfield.class == Reg
|| i.tm.operand_types[op].bitfield.acc)
&& (i.tm.operand_types[op].bitfield.word
|| i.tm.operand_types[op].bitfield.dword))
@@ -6751,7 +6769,7 @@ check_word_reg (void)
else if ((!quiet_warnings || flag_code == CODE_64BIT)
&& (i.types[op].bitfield.dword
|| i.types[op].bitfield.qword)
- && (i.tm.operand_types[op].bitfield.reg
+ && (i.tm.operand_types[op].bitfield.class == Reg
|| i.tm.operand_types[op].bitfield.acc)
&& i.tm.operand_types[op].bitfield.word)
{
@@ -7049,7 +7067,7 @@ duplicate:
{
/* The register or float register operand is in operand
0 or 1. */
- unsigned int op = !i.tm.operand_types[0].bitfield.reg;
+ unsigned int op = i.tm.operand_types[0].bitfield.class != Reg;
/* Register goes in low 3 bits of opcode. */
i.tm.base_opcode |= i.op[op].regs->reg_num;
@@ -7284,7 +7302,7 @@ build_modrm_byte (void)
op = i.tm.operand_types[vvvv];
if ((dest + 1) >= i.operands
- || ((!op.bitfield.reg
+ || ((op.bitfield.class != Reg
|| (!op.bitfield.dword && !op.bitfield.qword))
&& !op.bitfield.regsimd
&& !operand_type_equal (&op, &regmask)))
@@ -7661,7 +7679,7 @@ build_modrm_byte (void)
for (op = 0; op < i.operands; op++)
{
- if (i.types[op].bitfield.reg
+ if (i.types[op].bitfield.class == Reg
|| i.types[op].bitfield.regbnd
|| i.types[op].bitfield.regmask
|| i.types[op].bitfield.sreg
@@ -7743,7 +7761,7 @@ build_modrm_byte (void)
{
i386_operand_type *type = &i.tm.operand_types[vex_reg];
- if ((!type->bitfield.reg
+ if ((type->bitfield.class != Reg
|| (!type->bitfield.dword && !type->bitfield.qword))
&& !type->bitfield.regsimd
&& !operand_type_equal (type, &regmask))
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 9bd41c0..fab75c4 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,21 @@
+2019-11-08 Jan Beulich <jbeulich@suse.com>
+
+ * i386-gen.c (operand_type_init): Add Class=. New
+ OPERAND_TYPE_ANYIMM entry.
+ (operand_classes): New.
+ (operand_types): Drop Reg entry.
+ (output_operand_type): New parameter "class". Process it.
+ (process_i386_operand_type): New local variable "class".
+ (main): Adjust static assertions.
+ * i386-opc.h (CLASS_WIDTH): Define.
+ (enum operand_class): New.
+ (Reg): Replace by Class. Adjust comment.
+ (union i386_operand_type): Replace reg by class.
+ * i386-opc.tbl (Reg8, Reg16, Reg32, Reg64, FloatReg): Add
+ Class=.
+ * i386-reg.tbl: Replace Reg by Class=Reg.
+ * i386-init.h: Re-generate.
+
2019-11-07 Mihail Ionescu <mihail.ionescu@arm.com>
* opcodes/aarch64-tbl.h (V8_6_INSN): New macro for v8.6 instructions.
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index d33e665..a15be80 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -388,13 +388,13 @@ static initializer operand_type_init[] =
{ "OPERAND_TYPE_NONE",
"0" },
{ "OPERAND_TYPE_REG8",
- "Reg|Byte" },
+ "Class=Reg|Byte" },
{ "OPERAND_TYPE_REG16",
- "Reg|Word" },
+ "Class=Reg|Word" },
{ "OPERAND_TYPE_REG32",
- "Reg|Dword" },
+ "Class=Reg|Dword" },
{ "OPERAND_TYPE_REG64",
- "Reg|Qword" },
+ "Class=Reg|Qword" },
{ "OPERAND_TYPE_IMM1",
"Imm1" },
{ "OPERAND_TYPE_IMM8",
@@ -432,7 +432,7 @@ static initializer operand_type_init[] =
{ "OPERAND_TYPE_DEBUG",
"Debug" },
{ "OPERAND_TYPE_FLOATREG",
- "Reg|Tbyte" },
+ "Class=Reg|Tbyte" },
{ "OPERAND_TYPE_FLOATACC",
"Acc|Tbyte" },
{ "OPERAND_TYPE_SREG",
@@ -479,6 +479,8 @@ static initializer operand_type_init[] =
"Imm32|Imm32S|Imm64|Disp32" },
{ "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
"Imm32|Imm32S|Imm64|Disp32|Disp64" },
+ { "OPERAND_TYPE_ANYIMM",
+ "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
{ "OPERAND_TYPE_REGBND",
"RegBND" },
};
@@ -674,9 +676,19 @@ static bitfield opcode_modifiers[] =
BITFIELD (Intel64),
};
+#define CLASS(n) #n, n
+
+static const struct {
+ const char *name;
+ enum operand_class value;
+} operand_classes[] = {
+ CLASS (Reg),
+};
+
+#undef CLASS
+
static bitfield operand_types[] =
{
- BITFIELD (Reg),
BITFIELD (RegMMX),
BITFIELD (RegSIMD),
BITFIELD (RegMask),
@@ -1134,20 +1146,21 @@ enum stage {
};
static void
-output_operand_type (FILE *table, bitfield *types, unsigned int size,
+output_operand_type (FILE *table, enum operand_class class,
+ const bitfield *types, unsigned int size,
enum stage stage, const char *indent)
{
unsigned int i;
- fprintf (table, "{ { ");
+ fprintf (table, "{ { %d, ", class);
for (i = 0; i < size - 1; i++)
{
- if (((i + 1) % 20) != 0)
+ if (((i + 2) % 20) != 0)
fprintf (table, "%d, ", types[i].value);
else
fprintf (table, "%d,", types[i].value);
- if (((i + 1) % 20) == 0)
+ if (((i + 2) % 20) == 0)
{
/* We need \\ for macro. */
if (stage == stage_macros)
@@ -1165,6 +1178,7 @@ process_i386_operand_type (FILE *table, char *op, enum stage stage,
const char *indent, int lineno)
{
char *str, *next, *last;
+ enum operand_class class = ClassNone;
bitfield types [ARRAY_SIZE (operand_types)];
/* Copy the default operand type. */
@@ -1180,6 +1194,21 @@ process_i386_operand_type (FILE *table, char *op, enum stage stage,
str = next_field (next, '|', &next, last);
if (str)
{
+ unsigned int i;
+
+ if (!strncmp(str, "Class=", 6))
+ {
+ for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
+ if (!strcmp(str + 6, operand_classes[i].name))
+ {
+ class = operand_classes[i].value;
+ str = NULL;
+ break;
+ }
+ }
+ }
+ if (str)
+ {
set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
if (strcasecmp(str, "BaseIndex") == 0)
baseindex = 1;
@@ -1197,7 +1226,7 @@ process_i386_operand_type (FILE *table, char *op, enum stage stage,
set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
}
}
- output_operand_type (table, types, ARRAY_SIZE (types), stage,
+ output_operand_type (table, class, types, ARRAY_SIZE (types), stage,
indent);
}
@@ -1688,9 +1717,9 @@ main (int argc, char **argv)
/* Check the unused bitfield in i386_operand_type. */
#ifdef OTUnused
- static_assert (ARRAY_SIZE (operand_types) == OTNum + 1);
+ static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH == OTNum + 1);
#else
- static_assert (ARRAY_SIZE (operand_types) == OTNum);
+ static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH == OTNum);
c = OTNumOfBits - OTMax - 1;
if (c)
diff --git a/opcodes/i386-init.h b/opcodes/i386-init.h
index f67e534..66e5f11 100644
--- a/opcodes/i386-init.h
+++ b/opcodes/i386-init.h
@@ -1551,6 +1551,10 @@
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
+#define OPERAND_TYPE_ANYIMM \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
+
#define OPERAND_TYPE_REGBND \
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } }
diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h
index e9b1f92..5c49ac1 100644
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -702,12 +702,21 @@ typedef struct i386_opcode_modifier
unsigned int intel64:1;
} i386_opcode_modifier;
+/* Operand classes. */
+
+#define CLASS_WIDTH 4
+enum operand_class
+{
+ ClassNone,
+ Reg, /* GPRs and FP regs, distinguished by operand size */
+};
+
/* Position of operand_type bits. */
enum
{
- /* Register (qualified by Byte, Word, etc) */
- Reg = 0,
+ /* Class */
+ Class = CLASS_WIDTH - 1,
/* MMX register */
RegMMX,
/* Vector registers */
@@ -791,7 +800,7 @@ enum
/* Bound register. */
RegBND,
- /* The number of bitfields in i386_operand_type. */
+ /* The number of bits in i386_operand_type. */
OTNum
};
@@ -808,7 +817,7 @@ typedef union i386_operand_type
{
struct
{
- unsigned int reg:1;
+ unsigned int class:CLASS_WIDTH;
unsigned int regmmx:1;
unsigned int regsimd:1;
unsigned int regmask:1;
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
index 115c6f1..e4a3d7c 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -22,13 +22,13 @@
#include "i386-opc.h"
#undef None
-#define Reg8 Reg|Byte
-#define Reg16 Reg|Word
-#define Reg32 Reg|Dword
-#define Reg64 Reg|Qword
+#define Reg8 Class=Reg|Byte
+#define Reg16 Class=Reg|Word
+#define Reg32 Class=Reg|Dword
+#define Reg64 Class=Reg|Qword
#define FloatAcc Acc|Tbyte
-#define FloatReg Reg|Tbyte
+#define FloatReg Class=Reg|Tbyte
#define RegXMM RegSIMD|Xmmword
#define RegYMM RegSIMD|Ymmword
diff --git a/opcodes/i386-reg.tbl b/opcodes/i386-reg.tbl
index 61e9fe0..8e6a2df 100644
--- a/opcodes/i386-reg.tbl
+++ b/opcodes/i386-reg.tbl
@@ -19,82 +19,82 @@
// 02110-1301, USA.
// Make %st first as we test for it.
-st, Reg|Acc|Tbyte, 0, 0, 11, 33
+st, Class=Reg|Acc|Tbyte, 0, 0, 11, 33
// 8 bit regs
-al, Reg|Acc|Byte, 0, 0, Dw2Inval, Dw2Inval
-cl, Reg|Byte|ShiftCount, 0, 1, Dw2Inval, Dw2Inval
-dl, Reg|Byte, 0, 2, Dw2Inval, Dw2Inval
-bl, Reg|Byte, 0, 3, Dw2Inval, Dw2Inval
-ah, Reg|Byte, 0, 4, Dw2Inval, Dw2Inval
-ch, Reg|Byte, 0, 5, Dw2Inval, Dw2Inval
-dh, Reg|Byte, 0, 6, Dw2Inval, Dw2Inval
-bh, Reg|Byte, 0, 7, Dw2Inval, Dw2Inval
-axl, Reg|Byte, RegRex64, 0, Dw2Inval, Dw2Inval
-cxl, Reg|Byte, RegRex64, 1, Dw2Inval, Dw2Inval
-dxl, Reg|Byte, RegRex64, 2, Dw2Inval, Dw2Inval
-bxl, Reg|Byte, RegRex64, 3, Dw2Inval, Dw2Inval
-spl, Reg|Byte, RegRex64, 4, Dw2Inval, Dw2Inval
-bpl, Reg|Byte, RegRex64, 5, Dw2Inval, Dw2Inval
-sil, Reg|Byte, RegRex64, 6, Dw2Inval, Dw2Inval
-dil, Reg|Byte, RegRex64, 7, Dw2Inval, Dw2Inval
-r8b, Reg|Byte, RegRex|RegRex64, 0, Dw2Inval, Dw2Inval
-r9b, Reg|Byte, RegRex|RegRex64, 1, Dw2Inval, Dw2Inval
-r10b, Reg|Byte, RegRex|RegRex64, 2, Dw2Inval, Dw2Inval
-r11b, Reg|Byte, RegRex|RegRex64, 3, Dw2Inval, Dw2Inval
-r12b, Reg|Byte, RegRex|RegRex64, 4, Dw2Inval, Dw2Inval
-r13b, Reg|Byte, RegRex|RegRex64, 5, Dw2Inval, Dw2Inval
-r14b, Reg|Byte, RegRex|RegRex64, 6, Dw2Inval, Dw2Inval
-r15b, Reg|Byte, RegRex|RegRex64, 7, Dw2Inval, Dw2Inval
+al, Class=Reg|Acc|Byte, 0, 0, Dw2Inval, Dw2Inval
+cl, Class=Reg|Byte|ShiftCount, 0, 1, Dw2Inval, Dw2Inval
+dl, Class=Reg|Byte, 0, 2, Dw2Inval, Dw2Inval
+bl, Class=Reg|Byte, 0, 3, Dw2Inval, Dw2Inval
+ah, Class=Reg|Byte, 0, 4, Dw2Inval, Dw2Inval
+ch, Class=Reg|Byte, 0, 5, Dw2Inval, Dw2Inval
+dh, Class=Reg|Byte, 0, 6, Dw2Inval, Dw2Inval
+bh, Class=Reg|Byte, 0, 7, Dw2Inval, Dw2Inval
+axl, Class=Reg|Byte, RegRex64, 0, Dw2Inval, Dw2Inval
+cxl, Class=Reg|Byte, RegRex64, 1, Dw2Inval, Dw2Inval
+dxl, Class=Reg|Byte, RegRex64, 2, Dw2Inval, Dw2Inval
+bxl, Class=Reg|Byte, RegRex64, 3, Dw2Inval, Dw2Inval
+spl, Class=Reg|Byte, RegRex64, 4, Dw2Inval, Dw2Inval
+bpl, Class=Reg|Byte, RegRex64, 5, Dw2Inval, Dw2Inval
+sil, Class=Reg|Byte, RegRex64, 6, Dw2Inval, Dw2Inval
+dil, Class=Reg|Byte, RegRex64, 7, Dw2Inval, Dw2Inval
+r8b, Class=Reg|Byte, RegRex|RegRex64, 0, Dw2Inval, Dw2Inval
+r9b, Class=Reg|Byte, RegRex|RegRex64, 1, Dw2Inval, Dw2Inval
+r10b, Class=Reg|Byte, RegRex|RegRex64, 2, Dw2Inval, Dw2Inval
+r11b, Class=Reg|Byte, RegRex|RegRex64, 3, Dw2Inval, Dw2Inval
+r12b, Class=Reg|Byte, RegRex|RegRex64, 4, Dw2Inval, Dw2Inval
+r13b, Class=Reg|Byte, RegRex|RegRex64, 5, Dw2Inval, Dw2Inval
+r14b, Class=Reg|Byte, RegRex|RegRex64, 6, Dw2Inval, Dw2Inval
+r15b, Class=Reg|Byte, RegRex|RegRex64, 7, Dw2Inval, Dw2Inval
// 16 bit regs
-ax, Reg|Acc|Word, 0, 0, Dw2Inval, Dw2Inval
-cx, Reg|Word, 0, 1, Dw2Inval, Dw2Inval
-dx, Reg|Word|InOutPortReg, 0, 2, Dw2Inval, Dw2Inval
-bx, Reg|Word|BaseIndex, 0, 3, Dw2Inval, Dw2Inval
-sp, Reg|Word, 0, 4, Dw2Inval, Dw2Inval
-bp, Reg|Word|BaseIndex, 0, 5, Dw2Inval, Dw2Inval
-si, Reg|Word|BaseIndex, 0, 6, Dw2Inval, Dw2Inval
-di, Reg|Word|BaseIndex, 0, 7, Dw2Inval, Dw2Inval
-r8w, Reg|Word, RegRex, 0, Dw2Inval, Dw2Inval
-r9w, Reg|Word, RegRex, 1, Dw2Inval, Dw2Inval
-r10w, Reg|Word, RegRex, 2, Dw2Inval, Dw2Inval
-r11w, Reg|Word, RegRex, 3, Dw2Inval, Dw2Inval
-r12w, Reg|Word, RegRex, 4, Dw2Inval, Dw2Inval
-r13w, Reg|Word, RegRex, 5, Dw2Inval, Dw2Inval
-r14w, Reg|Word, RegRex, 6, Dw2Inval, Dw2Inval
-r15w, Reg|Word, RegRex, 7, Dw2Inval, Dw2Inval
+ax, Class=Reg|Acc|Word, 0, 0, Dw2Inval, Dw2Inval
+cx, Class=Reg|Word, 0, 1, Dw2Inval, Dw2Inval
+dx, Class=Reg|Word|InOutPortReg, 0, 2, Dw2Inval, Dw2Inval
+bx, Class=Reg|Word|BaseIndex, 0, 3, Dw2Inval, Dw2Inval
+sp, Class=Reg|Word, 0, 4, Dw2Inval, Dw2Inval
+bp, Class=Reg|Word|BaseIndex, 0, 5, Dw2Inval, Dw2Inval
+si, Class=Reg|Word|BaseIndex, 0, 6, Dw2Inval, Dw2Inval
+di, Class=Reg|Word|BaseIndex, 0, 7, Dw2Inval, Dw2Inval
+r8w, Class=Reg|Word, RegRex, 0, Dw2Inval, Dw2Inval
+r9w, Class=Reg|Word, RegRex, 1, Dw2Inval, Dw2Inval
+r10w, Class=Reg|Word, RegRex, 2, Dw2Inval, Dw2Inval
+r11w, Class=Reg|Word, RegRex, 3, Dw2Inval, Dw2Inval
+r12w, Class=Reg|Word, RegRex, 4, Dw2Inval, Dw2Inval
+r13w, Class=Reg|Word, RegRex, 5, Dw2Inval, Dw2Inval
+r14w, Class=Reg|Word, RegRex, 6, Dw2Inval, Dw2Inval
+r15w, Class=Reg|Word, RegRex, 7, Dw2Inval, Dw2Inval
// 32 bit regs
-eax, Reg|Acc|Dword|BaseIndex, 0, 0, 0, Dw2Inval
-ecx, Reg|Dword|BaseIndex, 0, 1, 1, Dw2Inval
-edx, Reg|Dword|BaseIndex, 0, 2, 2, Dw2Inval
-ebx, Reg|Dword|BaseIndex, 0, 3, 3, Dw2Inval
-esp, Reg|Dword, 0, 4, 4, Dw2Inval
-ebp, Reg|Dword|BaseIndex, 0, 5, 5, Dw2Inval
-esi, Reg|Dword|BaseIndex, 0, 6, 6, Dw2Inval
-edi, Reg|Dword|BaseIndex, 0, 7, 7, Dw2Inval
-r8d, Reg|Dword|BaseIndex, RegRex, 0, Dw2Inval, Dw2Inval
-r9d, Reg|Dword|BaseIndex, RegRex, 1, Dw2Inval, Dw2Inval
-r10d, Reg|Dword|BaseIndex, RegRex, 2, Dw2Inval, Dw2Inval
-r11d, Reg|Dword|BaseIndex, RegRex, 3, Dw2Inval, Dw2Inval
-r12d, Reg|Dword|BaseIndex, RegRex, 4, Dw2Inval, Dw2Inval
-r13d, Reg|Dword|BaseIndex, RegRex, 5, Dw2Inval, Dw2Inval
-r14d, Reg|Dword|BaseIndex, RegRex, 6, Dw2Inval, Dw2Inval
-r15d, Reg|Dword|BaseIndex, RegRex, 7, Dw2Inval, Dw2Inval
-rax, Reg|Acc|Qword|BaseIndex, 0, 0, Dw2Inval, 0
-rcx, Reg|Qword|BaseIndex, 0, 1, Dw2Inval, 2
-rdx, Reg|Qword|BaseIndex, 0, 2, Dw2Inval, 1
-rbx, Reg|Qword|BaseIndex, 0, 3, Dw2Inval, 3
-rsp, Reg|Qword, 0, 4, Dw2Inval, 7
-rbp, Reg|Qword|BaseIndex, 0, 5, Dw2Inval, 6
-rsi, Reg|Qword|BaseIndex, 0, 6, Dw2Inval, 4
-rdi, Reg|Qword|BaseIndex, 0, 7, Dw2Inval, 5
-r8, Reg|Qword|BaseIndex, RegRex, 0, Dw2Inval, 8
-r9, Reg|Qword|BaseIndex, RegRex, 1, Dw2Inval, 9
-r10, Reg|Qword|BaseIndex, RegRex, 2, Dw2Inval, 10
-r11, Reg|Qword|BaseIndex, RegRex, 3, Dw2Inval, 11
-r12, Reg|Qword|BaseIndex, RegRex, 4, Dw2Inval, 12
-r13, Reg|Qword|BaseIndex, RegRex, 5, Dw2Inval, 13
-r14, Reg|Qword|BaseIndex, RegRex, 6, Dw2Inval, 14
-r15, Reg|Qword|BaseIndex, RegRex, 7, Dw2Inval, 15
+eax, Class=Reg|Acc|Dword|BaseIndex, 0, 0, 0, Dw2Inval
+ecx, Class=Reg|Dword|BaseIndex, 0, 1, 1, Dw2Inval
+edx, Class=Reg|Dword|BaseIndex, 0, 2, 2, Dw2Inval
+ebx, Class=Reg|Dword|BaseIndex, 0, 3, 3, Dw2Inval
+esp, Class=Reg|Dword, 0, 4, 4, Dw2Inval
+ebp, Class=Reg|Dword|BaseIndex, 0, 5, 5, Dw2Inval
+esi, Class=Reg|Dword|BaseIndex, 0, 6, 6, Dw2Inval
+edi, Class=Reg|Dword|BaseIndex, 0, 7, 7, Dw2Inval
+r8d, Class=Reg|Dword|BaseIndex, RegRex, 0, Dw2Inval, Dw2Inval
+r9d, Class=Reg|Dword|BaseIndex, RegRex, 1, Dw2Inval, Dw2Inval
+r10d, Class=Reg|Dword|BaseIndex, RegRex, 2, Dw2Inval, Dw2Inval
+r11d, Class=Reg|Dword|BaseIndex, RegRex, 3, Dw2Inval, Dw2Inval
+r12d, Class=Reg|Dword|BaseIndex, RegRex, 4, Dw2Inval, Dw2Inval
+r13d, Class=Reg|Dword|BaseIndex, RegRex, 5, Dw2Inval, Dw2Inval
+r14d, Class=Reg|Dword|BaseIndex, RegRex, 6, Dw2Inval, Dw2Inval
+r15d, Class=Reg|Dword|BaseIndex, RegRex, 7, Dw2Inval, Dw2Inval
+rax, Class=Reg|Acc|Qword|BaseIndex, 0, 0, Dw2Inval, 0
+rcx, Class=Reg|Qword|BaseIndex, 0, 1, Dw2Inval, 2
+rdx, Class=Reg|Qword|BaseIndex, 0, 2, Dw2Inval, 1
+rbx, Class=Reg|Qword|BaseIndex, 0, 3, Dw2Inval, 3
+rsp, Class=Reg|Qword, 0, 4, Dw2Inval, 7
+rbp, Class=Reg|Qword|BaseIndex, 0, 5, Dw2Inval, 6
+rsi, Class=Reg|Qword|BaseIndex, 0, 6, Dw2Inval, 4
+rdi, Class=Reg|Qword|BaseIndex, 0, 7, Dw2Inval, 5
+r8, Class=Reg|Qword|BaseIndex, RegRex, 0, Dw2Inval, 8
+r9, Class=Reg|Qword|BaseIndex, RegRex, 1, Dw2Inval, 9
+r10, Class=Reg|Qword|BaseIndex, RegRex, 2, Dw2Inval, 10
+r11, Class=Reg|Qword|BaseIndex, RegRex, 3, Dw2Inval, 11
+r12, Class=Reg|Qword|BaseIndex, RegRex, 4, Dw2Inval, 12
+r13, Class=Reg|Qword|BaseIndex, RegRex, 5, Dw2Inval, 13
+r14, Class=Reg|Qword|BaseIndex, RegRex, 6, Dw2Inval, 14
+r15, Class=Reg|Qword|BaseIndex, RegRex, 7, Dw2Inval, 15
// Vector mask registers.
k0, RegMask, 0, 0, 93, 118
k1, RegMask, 0, 1, 94, 119
@@ -283,23 +283,23 @@ bnd0, RegBND, 0, 0, Dw2Inval, Dw2Inval
bnd1, RegBND, 0, 1, Dw2Inval, Dw2Inval
bnd2, RegBND, 0, 2, Dw2Inval, Dw2Inval
bnd3, RegBND, 0, 3, Dw2Inval, Dw2Inval
-// No Reg will make these registers rejected for all purposes except
+// No Class=Reg will make these registers rejected for all purposes except
// for addressing. This saves creating one extra type for RIP/EIP.
rip, Qword, RegRex64, RegIP, Dw2Inval, 16
eip, Dword, RegRex64, RegIP, 8, Dw2Inval
-// No Reg will make these registers rejected for all purposes except
+// No Class=Reg will make these registers rejected for all purposes except
// for addressing.
riz, Qword|BaseIndex, RegRex64, RegIZ, Dw2Inval, Dw2Inval
eiz, Dword|BaseIndex, 0, RegIZ, Dw2Inval, Dw2Inval
// fp regs.
-st(0), Reg|Acc|Tbyte, 0, 0, 11, 33
-st(1), Reg|Tbyte, 0, 1, 12, 34
-st(2), Reg|Tbyte, 0, 2, 13, 35
-st(3), Reg|Tbyte, 0, 3, 14, 36
-st(4), Reg|Tbyte, 0, 4, 15, 37
-st(5), Reg|Tbyte, 0, 5, 16, 38
-st(6), Reg|Tbyte, 0, 6, 17, 39
-st(7), Reg|Tbyte, 0, 7, 18, 40
+st(0), Class=Reg|Acc|Tbyte, 0, 0, 11, 33
+st(1), Class=Reg|Tbyte, 0, 1, 12, 34
+st(2), Class=Reg|Tbyte, 0, 2, 13, 35
+st(3), Class=Reg|Tbyte, 0, 3, 14, 36
+st(4), Class=Reg|Tbyte, 0, 4, 15, 37
+st(5), Class=Reg|Tbyte, 0, 5, 16, 38
+st(6), Class=Reg|Tbyte, 0, 6, 17, 39
+st(7), Class=Reg|Tbyte, 0, 7, 18, 40
// Pseudo-register names only used in .cfi_* directives
eflags, 0, 0, 0, 9, 49
rflags, 0, 0, 0, Dw2Inval, 49