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>
|
2021-03-23 Jan Beulich <jbeulich@suse.com>
|
||||||
|
|
||||||
* config/tc-i386.c (load_insn_p): Use PREFIX_NONE. Fold two
|
* 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
|
static void
|
||||||
pte (insn_template *t)
|
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;
|
unsigned int j;
|
||||||
|
|
||||||
fprintf (stdout, " %d operands ", t->operands);
|
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);
|
fprintf (stdout, "opcode %x ", t->base_opcode);
|
||||||
if (t->extension_opcode != None)
|
if (t->extension_opcode != None)
|
||||||
fprintf (stdout, "ext %x ", t->extension_opcode);
|
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.dir_encoding == dir_encoding_default
|
||||||
&& i.operands == i.reg_operands
|
&& i.operands == i.reg_operands
|
||||||
&& operand_type_equal (&i.types[0], &i.types[i.operands - 1])
|
&& 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.tm.opcode_modifier.load || i.tm.opcode_modifier.d)
|
||||||
&& i.rex == REX_B)
|
&& i.rex == REX_B)
|
||||||
{
|
{
|
||||||
@ -3644,7 +3654,7 @@ build_vex_prefix (const insn_template *t)
|
|||||||
union i386_op temp_op;
|
union i386_op temp_op;
|
||||||
i386_operand_type temp_type;
|
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 (!i.tm.opcode_modifier.sae);
|
||||||
gas_assert (operand_type_equal (&i.types[i.operands - 2],
|
gas_assert (operand_type_equal (&i.types[i.operands - 2],
|
||||||
&i.types[i.operands - 3]));
|
&i.types[i.operands - 3]));
|
||||||
@ -3715,7 +3725,7 @@ build_vex_prefix (const insn_template *t)
|
|||||||
/* Use 2-byte VEX prefix if possible. */
|
/* Use 2-byte VEX prefix if possible. */
|
||||||
if (w == 0
|
if (w == 0
|
||||||
&& i.vec_encoding != vex_encoding_vex3
|
&& 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)
|
&& (i.rex & (REX_W | REX_X | REX_B)) == 0)
|
||||||
{
|
{
|
||||||
/* 2-byte VEX prefix. */
|
/* 2-byte VEX prefix. */
|
||||||
@ -3734,34 +3744,18 @@ build_vex_prefix (const insn_template *t)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* 3-byte VEX prefix. */
|
/* 3-byte VEX prefix. */
|
||||||
unsigned int m;
|
|
||||||
|
|
||||||
i.vex.length = 3;
|
i.vex.length = 3;
|
||||||
|
|
||||||
switch (i.tm.opcode_modifier.opcodeprefix)
|
switch (i.tm.opcode_modifier.opcodespace)
|
||||||
{
|
{
|
||||||
case VEX0F:
|
case SPACE_0F:
|
||||||
m = 0x1;
|
case SPACE_0F38:
|
||||||
|
case SPACE_0F3A:
|
||||||
i.vex.bytes[0] = 0xc4;
|
i.vex.bytes[0] = 0xc4;
|
||||||
break;
|
break;
|
||||||
case VEX0F38:
|
case SPACE_XOP08:
|
||||||
m = 0x2;
|
case SPACE_XOP09:
|
||||||
i.vex.bytes[0] = 0xc4;
|
case SPACE_XOP0A:
|
||||||
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;
|
|
||||||
i.vex.bytes[0] = 0x8f;
|
i.vex.bytes[0] = 0x8f;
|
||||||
break;
|
break;
|
||||||
default:
|
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
|
/* The high 3 bits of the second VEX byte are 1's compliment
|
||||||
of RXB bits from REX. */
|
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
|
i.vex.bytes[2] = (w << 7
|
||||||
| register_specifier << 3
|
| register_specifier << 3
|
||||||
@ -3799,8 +3793,7 @@ static void
|
|||||||
build_evex_prefix (void)
|
build_evex_prefix (void)
|
||||||
{
|
{
|
||||||
unsigned int register_specifier;
|
unsigned int register_specifier;
|
||||||
unsigned int implied_prefix;
|
unsigned int implied_prefix, w;
|
||||||
unsigned int m, w;
|
|
||||||
rex_byte vrex_used = 0;
|
rex_byte vrex_used = 0;
|
||||||
|
|
||||||
/* Check register specifier. */
|
/* Check register specifier. */
|
||||||
@ -3851,26 +3844,11 @@ build_evex_prefix (void)
|
|||||||
i.vex.length = 4;
|
i.vex.length = 4;
|
||||||
i.vex.bytes[0] = 0x62;
|
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
|
/* The high 3 bits of the second EVEX byte are 1's compliment of RXB
|
||||||
bits from REX. */
|
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
|
/* The fifth bit of the second EVEX byte is 1's compliment of the
|
||||||
REX_R bit in VREX. */
|
REX_R bit in VREX. */
|
||||||
@ -4416,7 +4394,7 @@ load_insn_p (void)
|
|||||||
/* vldmxcsr. */
|
/* vldmxcsr. */
|
||||||
if (i.tm.base_opcode == 0xae
|
if (i.tm.base_opcode == 0xae
|
||||||
&& i.tm.opcode_modifier.vex
|
&& i.tm.opcode_modifier.vex
|
||||||
&& i.tm.opcode_modifier.opcodeprefix == VEX0F
|
&& i.tm.opcode_modifier.opcodespace == SPACE_0F
|
||||||
&& i.tm.extension_opcode == 2)
|
&& i.tm.extension_opcode == 2)
|
||||||
return 1;
|
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>
|
2021-03-22 Martin Liska <mliska@suse.cz>
|
||||||
|
|
||||||
* aarch64-dis.c (parse_aarch64_dis_option): Replace usage of CONST_STRNEQ with startswith.
|
* 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 (Vex),
|
||||||
BITFIELD (VexVVVV),
|
BITFIELD (VexVVVV),
|
||||||
BITFIELD (VexW),
|
BITFIELD (VexW),
|
||||||
|
BITFIELD (OpcodeSpace),
|
||||||
BITFIELD (OpcodePrefix),
|
BITFIELD (OpcodePrefix),
|
||||||
BITFIELD (VexSources),
|
BITFIELD (VexSources),
|
||||||
BITFIELD (SIB),
|
BITFIELD (SIB),
|
||||||
|
@ -575,7 +575,25 @@ enum
|
|||||||
#define VEXW1 2
|
#define VEXW1 2
|
||||||
#define VEXWIG 3
|
#define VEXWIG 3
|
||||||
VexW,
|
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
|
0: None
|
||||||
1: Add 0x66 opcode prefix.
|
1: Add 0x66 opcode prefix.
|
||||||
2: Add 0xf2 opcode prefix.
|
2: Add 0xf2 opcode prefix.
|
||||||
@ -585,20 +603,6 @@ enum
|
|||||||
#define PREFIX_0X66 1
|
#define PREFIX_0X66 1
|
||||||
#define PREFIX_0XF2 2
|
#define PREFIX_0XF2 2
|
||||||
#define PREFIX_0XF3 3
|
#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,
|
OpcodePrefix,
|
||||||
/* number of VEX source operands:
|
/* number of VEX source operands:
|
||||||
0: <= 2 source operands.
|
0: <= 2 source operands.
|
||||||
@ -742,7 +746,8 @@ typedef struct i386_opcode_modifier
|
|||||||
unsigned int vex:2;
|
unsigned int vex:2;
|
||||||
unsigned int vexvvvv:2;
|
unsigned int vexvvvv:2;
|
||||||
unsigned int vexw:2;
|
unsigned int vexw:2;
|
||||||
unsigned int opcodeprefix:3;
|
unsigned int opcodespace:4;
|
||||||
|
unsigned int opcodeprefix:2;
|
||||||
unsigned int vexsources:2;
|
unsigned int vexsources:2;
|
||||||
unsigned int sib:3;
|
unsigned int sib:3;
|
||||||
unsigned int sse2avx:1;
|
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