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:
Jan Beulich 2021-03-23 17:08:39 +01:00
parent 66848ebca8
commit 441f6aca39
7 changed files with 9355 additions and 9343 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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.

View File

@ -719,6 +719,7 @@ static bitfield opcode_modifiers[] =
BITFIELD (Vex),
BITFIELD (VexVVVV),
BITFIELD (VexW),
BITFIELD (OpcodeSpace),
BITFIELD (OpcodePrefix),
BITFIELD (VexSources),
BITFIELD (SIB),

View File

@ -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;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff