x86: split opcode prefix and opcode space representation
Commit 8b65b8953a
("x86: Remove the prefix byte from non-VEX/EVEX
base_opcode") used the opcodeprefix field for two distinct purposes. In
preparation of having VEX/XOP/EVEX and non-VEX templates become similar
in the representatioon of both encoding space and opcode prefixes, split
the field to have a separate one holding an insn's opcode space.
This commit is contained in:
parent
66848ebca8
commit
441f6aca39
@ -1,3 +1,10 @@
|
||||
2021-03-23 Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
* config/tc-i386.c (pte): Print prefix and encoding space.
|
||||
(build_vex_prefix): Check opcodespace instead of opcodeprefix.
|
||||
(build_evex_prefix): Likewise.
|
||||
(load_insn_p): Likewise.
|
||||
|
||||
2021-03-23 Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
* config/tc-i386.c (load_insn_p): Use PREFIX_NONE. Fold two
|
||||
|
@ -3239,8 +3239,18 @@ pi (const char *line, i386_insn *x)
|
||||
static void
|
||||
pte (insn_template *t)
|
||||
{
|
||||
static const unsigned char opc_pfx[] = { 0, 0x66, 0xf2, 0xf3 };
|
||||
static const char *const opc_spc[] = {
|
||||
NULL, "0f", "0f38", "0f3a", NULL, NULL, NULL, NULL,
|
||||
"XOP08", "XOP09", "XOP0A",
|
||||
};
|
||||
unsigned int j;
|
||||
|
||||
fprintf (stdout, " %d operands ", t->operands);
|
||||
if (opc_pfx[t->opcode_modifier.opcodeprefix])
|
||||
fprintf (stdout, "pfx %x ", opc_pfx[t->opcode_modifier.opcodeprefix]);
|
||||
if (opc_spc[t->opcode_modifier.opcodespace])
|
||||
fprintf (stdout, "space %s ", opc_spc[t->opcode_modifier.opcodespace]);
|
||||
fprintf (stdout, "opcode %x ", t->base_opcode);
|
||||
if (t->extension_opcode != None)
|
||||
fprintf (stdout, "ext %x ", t->extension_opcode);
|
||||
@ -3599,7 +3609,7 @@ build_vex_prefix (const insn_template *t)
|
||||
&& i.dir_encoding == dir_encoding_default
|
||||
&& i.operands == i.reg_operands
|
||||
&& operand_type_equal (&i.types[0], &i.types[i.operands - 1])
|
||||
&& i.tm.opcode_modifier.opcodeprefix == VEX0F
|
||||
&& i.tm.opcode_modifier.opcodespace == SPACE_0F
|
||||
&& (i.tm.opcode_modifier.load || i.tm.opcode_modifier.d)
|
||||
&& i.rex == REX_B)
|
||||
{
|
||||
@ -3644,7 +3654,7 @@ build_vex_prefix (const insn_template *t)
|
||||
union i386_op temp_op;
|
||||
i386_operand_type temp_type;
|
||||
|
||||
gas_assert (i.tm.opcode_modifier.opcodeprefix == VEX0F);
|
||||
gas_assert (i.tm.opcode_modifier.opcodespace == SPACE_0F);
|
||||
gas_assert (!i.tm.opcode_modifier.sae);
|
||||
gas_assert (operand_type_equal (&i.types[i.operands - 2],
|
||||
&i.types[i.operands - 3]));
|
||||
@ -3715,7 +3725,7 @@ build_vex_prefix (const insn_template *t)
|
||||
/* Use 2-byte VEX prefix if possible. */
|
||||
if (w == 0
|
||||
&& i.vec_encoding != vex_encoding_vex3
|
||||
&& i.tm.opcode_modifier.opcodeprefix == VEX0F
|
||||
&& i.tm.opcode_modifier.opcodespace == SPACE_0F
|
||||
&& (i.rex & (REX_W | REX_X | REX_B)) == 0)
|
||||
{
|
||||
/* 2-byte VEX prefix. */
|
||||
@ -3734,34 +3744,18 @@ build_vex_prefix (const insn_template *t)
|
||||
else
|
||||
{
|
||||
/* 3-byte VEX prefix. */
|
||||
unsigned int m;
|
||||
|
||||
i.vex.length = 3;
|
||||
|
||||
switch (i.tm.opcode_modifier.opcodeprefix)
|
||||
switch (i.tm.opcode_modifier.opcodespace)
|
||||
{
|
||||
case VEX0F:
|
||||
m = 0x1;
|
||||
case SPACE_0F:
|
||||
case SPACE_0F38:
|
||||
case SPACE_0F3A:
|
||||
i.vex.bytes[0] = 0xc4;
|
||||
break;
|
||||
case VEX0F38:
|
||||
m = 0x2;
|
||||
i.vex.bytes[0] = 0xc4;
|
||||
break;
|
||||
case VEX0F3A:
|
||||
m = 0x3;
|
||||
i.vex.bytes[0] = 0xc4;
|
||||
break;
|
||||
case XOP08:
|
||||
m = 0x8;
|
||||
i.vex.bytes[0] = 0x8f;
|
||||
break;
|
||||
case XOP09:
|
||||
m = 0x9;
|
||||
i.vex.bytes[0] = 0x8f;
|
||||
break;
|
||||
case XOP0A:
|
||||
m = 0xa;
|
||||
case SPACE_XOP08:
|
||||
case SPACE_XOP09:
|
||||
case SPACE_XOP0A:
|
||||
i.vex.bytes[0] = 0x8f;
|
||||
break;
|
||||
default:
|
||||
@ -3770,7 +3764,7 @@ build_vex_prefix (const insn_template *t)
|
||||
|
||||
/* The high 3 bits of the second VEX byte are 1's compliment
|
||||
of RXB bits from REX. */
|
||||
i.vex.bytes[1] = (~i.rex & 0x7) << 5 | m;
|
||||
i.vex.bytes[1] = (~i.rex & 0x7) << 5 | i.tm.opcode_modifier.opcodespace;
|
||||
|
||||
i.vex.bytes[2] = (w << 7
|
||||
| register_specifier << 3
|
||||
@ -3799,8 +3793,7 @@ static void
|
||||
build_evex_prefix (void)
|
||||
{
|
||||
unsigned int register_specifier;
|
||||
unsigned int implied_prefix;
|
||||
unsigned int m, w;
|
||||
unsigned int implied_prefix, w;
|
||||
rex_byte vrex_used = 0;
|
||||
|
||||
/* Check register specifier. */
|
||||
@ -3851,26 +3844,11 @@ build_evex_prefix (void)
|
||||
i.vex.length = 4;
|
||||
i.vex.bytes[0] = 0x62;
|
||||
|
||||
/* mmmm bits. */
|
||||
switch (i.tm.opcode_modifier.opcodeprefix)
|
||||
{
|
||||
case VEX0F:
|
||||
m = 1;
|
||||
break;
|
||||
case VEX0F38:
|
||||
m = 2;
|
||||
break;
|
||||
case VEX0F3A:
|
||||
m = 3;
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
break;
|
||||
}
|
||||
|
||||
/* The high 3 bits of the second EVEX byte are 1's compliment of RXB
|
||||
bits from REX. */
|
||||
i.vex.bytes[1] = (~i.rex & 0x7) << 5 | m;
|
||||
gas_assert (i.tm.opcode_modifier.opcodespace >= SPACE_0F);
|
||||
gas_assert (i.tm.opcode_modifier.opcodespace <= SPACE_0F3A);
|
||||
i.vex.bytes[1] = (~i.rex & 0x7) << 5 | i.tm.opcode_modifier.opcodespace;
|
||||
|
||||
/* The fifth bit of the second EVEX byte is 1's compliment of the
|
||||
REX_R bit in VREX. */
|
||||
@ -4416,7 +4394,7 @@ load_insn_p (void)
|
||||
/* vldmxcsr. */
|
||||
if (i.tm.base_opcode == 0xae
|
||||
&& i.tm.opcode_modifier.vex
|
||||
&& i.tm.opcode_modifier.opcodeprefix == VEX0F
|
||||
&& i.tm.opcode_modifier.opcodespace == SPACE_0F
|
||||
&& i.tm.extension_opcode == 2)
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,3 +1,17 @@
|
||||
2021-03-23 Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
* i386-gen.c (opcode_modifiers): New OpcodeSpace element.
|
||||
* i386-opc.h (OpcodeSpace): New enumerator.
|
||||
(VEX0F, VEX0F38, VEX0F3A, XOP08, XOP09, XOP0A): Rename to ...
|
||||
(SPACE_BASE, SPACE_0F, SPACE_0F38, SPACE_0F3A, SPACE_XOP08,
|
||||
SPACE_XOP09, SPACE_XOP0A): ... respectively.
|
||||
(struct i386_opcode_modifier): New field opcodespace. Shrink
|
||||
opcodeprefix field.
|
||||
i386-opc.tbl (Space0F, Space0F38, Space0F3A, SpaceXOP08,
|
||||
SpaceXOP09, SpaceXOP0A): Define. Use them to replace
|
||||
OpcodePrefix uses.
|
||||
* i386-tbl.h: Re-generate.
|
||||
|
||||
2021-03-22 Martin Liska <mliska@suse.cz>
|
||||
|
||||
* aarch64-dis.c (parse_aarch64_dis_option): Replace usage of CONST_STRNEQ with startswith.
|
||||
|
@ -719,6 +719,7 @@ static bitfield opcode_modifiers[] =
|
||||
BITFIELD (Vex),
|
||||
BITFIELD (VexVVVV),
|
||||
BITFIELD (VexW),
|
||||
BITFIELD (OpcodeSpace),
|
||||
BITFIELD (OpcodePrefix),
|
||||
BITFIELD (VexSources),
|
||||
BITFIELD (SIB),
|
||||
|
@ -575,7 +575,25 @@ enum
|
||||
#define VEXW1 2
|
||||
#define VEXWIG 3
|
||||
VexW,
|
||||
/* Regular opcode prefix:
|
||||
/* Opcode encoding space (values chosen to be usable directly in
|
||||
VEX/XOP mmmmm and EVEX mm fields):
|
||||
0: Base opcode space.
|
||||
1: 0F opcode prefix / space.
|
||||
2: 0F38 opcode prefix / space.
|
||||
3: 0F3A opcode prefix / space.
|
||||
8: XOP 08 opcode space.
|
||||
9: XOP 09 opcode space.
|
||||
A: XOP 0A opcode space.
|
||||
*/
|
||||
#define SPACE_BASE 0
|
||||
#define SPACE_0F 1
|
||||
#define SPACE_0F38 2
|
||||
#define SPACE_0F3A 3
|
||||
#define SPACE_XOP08 8
|
||||
#define SPACE_XOP09 9
|
||||
#define SPACE_XOP0A 0xA
|
||||
OpcodeSpace,
|
||||
/* Opcode prefix:
|
||||
0: None
|
||||
1: Add 0x66 opcode prefix.
|
||||
2: Add 0xf2 opcode prefix.
|
||||
@ -585,20 +603,6 @@ enum
|
||||
#define PREFIX_0X66 1
|
||||
#define PREFIX_0XF2 2
|
||||
#define PREFIX_0XF3 3
|
||||
/* VEX opcode prefix:
|
||||
0: VEX 0x0F opcode prefix.
|
||||
1: VEX 0x0F38 opcode prefix.
|
||||
2: VEX 0x0F3A opcode prefix
|
||||
3: XOP 0x08 opcode prefix.
|
||||
4: XOP 0x09 opcode prefix
|
||||
5: XOP 0x0A opcode prefix.
|
||||
*/
|
||||
#define VEX0F 0
|
||||
#define VEX0F38 1
|
||||
#define VEX0F3A 2
|
||||
#define XOP08 3
|
||||
#define XOP09 4
|
||||
#define XOP0A 5
|
||||
OpcodePrefix,
|
||||
/* number of VEX source operands:
|
||||
0: <= 2 source operands.
|
||||
@ -742,7 +746,8 @@ typedef struct i386_opcode_modifier
|
||||
unsigned int vex:2;
|
||||
unsigned int vexvvvv:2;
|
||||
unsigned int vexw:2;
|
||||
unsigned int opcodeprefix:3;
|
||||
unsigned int opcodespace:4;
|
||||
unsigned int opcodeprefix:2;
|
||||
unsigned int vexsources:2;
|
||||
unsigned int sib:3;
|
||||
unsigned int sse2avx:1;
|
||||
|
4135
opcodes/i386-opc.tbl
4135
opcodes/i386-opc.tbl
File diff suppressed because it is too large
Load Diff
14430
opcodes/i386-tbl.h
14430
opcodes/i386-tbl.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user