x86emul: extend decoding / mem access testing to XOP-encoded insns

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
Jan Beulich committed 2020-08-05 10:27:31 +02:00
1 parent 5e6dc9b8e5
commit 3cb82fe3ff
1 file changed
+147
+147
View File
@@ -1474,6 +1474,96 @@ static const struct {
{ vex_0f3a, ARRAY_SIZE(vex_0f3a) },
};
static const struct xop {
uint8_t opc[2];
uint8_t w:2;
uint8_t l:2;
} xop_08[] = {
{ { 0x85 }, W0, L0 }, /* vpmacssww */
{ { 0x86 }, W0, L0 }, /* vpmacsswd */
{ { 0x87 }, W0, L0 }, /* vpmacssdql */
{ { 0x8e }, W0, L0 }, /* vpmacssdd */
{ { 0x8f }, W0, L0 }, /* vpmacssdqh */
{ { 0x95 }, W0, L0 }, /* vpmacsww */
{ { 0x96 }, W0, L0 }, /* vpmacswd */
{ { 0x97 }, W0, L0 }, /* vpmacsdql */
{ { 0x9e }, W0, L0 }, /* vpmacsdd */
{ { 0x9f }, W0, L0 }, /* vpmacsdqh */
{ { 0xa2 }, Wn, Ln }, /* vpcmov */
{ { 0xa3 }, Wn, L0 }, /* vpperm */
{ { 0xa6 }, W0, L0 }, /* vpmadcsswd */
{ { 0xb6 }, W0, L0 }, /* vpmadcswd */
{ { 0xc0 }, W0, L0 }, /* vprotb */
{ { 0xc1 }, W0, L0 }, /* vprotw */
{ { 0xc2 }, W0, L0 }, /* vprotd */
{ { 0xc3 }, W0, L0 }, /* vprotq */
{ { 0xcc }, W0, L0 }, /* vpcomb */
{ { 0xcd }, W0, L0 }, /* vpcomw */
{ { 0xce }, W0, L0 }, /* vpcomd */
{ { 0xcf }, W0, L0 }, /* vpcomq */
{ { 0xec }, W0, L0 }, /* vpcomub */
{ { 0xed }, W0, L0 }, /* vpcomuw */
{ { 0xee }, W0, L0 }, /* vpcomud */
{ { 0xef }, W0, L0 }, /* vpcomuq */
}, xop_09[] = {
{ { 0x01, 0x08 }, Wn, L0 }, /* blcfill */
{ { 0x01, 0x10 }, Wn, L0 }, /* blsfill */
{ { 0x01, 0x18 }, Wn, L0 }, /* blcs */
{ { 0x01, 0x20 }, Wn, L0 }, /* tzmsk */
{ { 0x01, 0x28 }, Wn, L0 }, /* blcic */
{ { 0x01, 0x30 }, Wn, L0 }, /* blsic */
{ { 0x01, 0x38 }, Wn, L0 }, /* t1mskc */
{ { 0x02, 0x08 }, Wn, L0 }, /* blcmsk */
{ { 0x02, 0x30 }, Wn, L0 }, /* blci */
{ { 0x02, 0xc0 }, Wn, L0 }, /* llwpcb */
{ { 0x02, 0xc8 }, Wn, L0 }, /* slwpcb */
{ { 0x80 }, W0, Ln }, /* vfrczps */
{ { 0x81 }, W0, Ln }, /* vfrczpd */
{ { 0x82 }, W0, L0 }, /* vfrczss */
{ { 0x83 }, W0, L0 }, /* vfrczsd */
{ { 0x90 }, Wn, L0 }, /* vprotb */
{ { 0x91 }, Wn, L0 }, /* vprotw */
{ { 0x92 }, Wn, L0 }, /* vprotd */
{ { 0x93 }, Wn, L0 }, /* vprotq */
{ { 0x94 }, Wn, L0 }, /* vpshlb */
{ { 0x95 }, Wn, L0 }, /* vpshlw */
{ { 0x96 }, Wn, L0 }, /* vpshld */
{ { 0x97 }, Wn, L0 }, /* vpshlq */
{ { 0x9c }, Wn, L0 }, /* vpshab */
{ { 0x9d }, Wn, L0 }, /* vpshaw */
{ { 0x9e }, Wn, L0 }, /* vpshad */
{ { 0x9f }, Wn, L0 }, /* vpshaq */
{ { 0xc1 }, W0, L0 }, /* vphaddbw */
{ { 0xc2 }, W0, L0 }, /* vphaddbd */
{ { 0xc3 }, W0, L0 }, /* vphaddbq */
{ { 0xc6 }, W0, L0 }, /* vphaddwd */
{ { 0xc7 }, W0, L0 }, /* vphaddwq */
{ { 0xcb }, W0, L0 }, /* vphadddq */
{ { 0xd1 }, W0, L0 }, /* vphaddubw */
{ { 0xd2 }, W0, L0 }, /* vphaddubd */
{ { 0xd3 }, W0, L0 }, /* vphaddubq */
{ { 0xd6 }, W0, L0 }, /* vphadduwd */
{ { 0xd7 }, W0, L0 }, /* vphadduwq */
{ { 0xdb }, W0, L0 }, /* vphaddudq */
{ { 0xe1 }, W0, L0 }, /* vphsubbw */
{ { 0xe2 }, W0, L0 }, /* vphsubwd */
{ { 0xe3 }, W0, L0 }, /* vphsubdq */
}, xop_0a[] = {
{ { 0x10 }, Wn, L0 }, /* bextr */
{ { 0x12, 0x00 }, Wn, L0 }, /* lwpins */
{ { 0x12, 0x08 }, Wn, L0 }, /* lwpval */
};
static const struct {
const struct xop *tbl;
unsigned int num;
unsigned int imm;
} xop[] = {
{ xop_08, ARRAY_SIZE(xop_08), 1 },
{ xop_09, ARRAY_SIZE(xop_09), 0 },
{ xop_0a, ARRAY_SIZE(xop_0a), 4 },
};
#undef Wn
#undef Ln
@@ -1738,6 +1828,63 @@ void predicates_test(void *instr, struct x86_emulate_ctxt *ctxt,
}
}
for ( x = 0; x < ARRAY_SIZE(xop); ++x )
{
for ( t = 0; t < xop[x].num; ++t )
{
uint8_t *ptr = instr;
unsigned int modrm;
enum mem_access mem;
memset(instr + 5, 0xcc, 10);
*ptr++ = 0x8f;
*ptr++ = 0xe8 + x;
*ptr++ = 0x78;
memcpy(ptr, xop[x].tbl[t].opc, 2);
memset(ptr + 2, 0, xop[x].imm);
modrm = ptr[1] & 0xc0 ? 0 : 4;
mem = ptr[1] & 0xc0 ? mem_none : mem_read;
assert(xop[x].tbl[t].w != WIG);
assert(xop[x].tbl[t].l != LIG);
if ( xop[x].tbl[t].w & W0 )
{
if ( xop[x].tbl[t].l & L0 )
do_test(instr, 5 + xop[x].imm, modrm, mem, ctxt, fetch);
if ( xop[x].tbl[t].l & L1 )
{
ptr[-1] = 0x7c;
ptr[1] = mem != mem_none ? 0x00 : 0xc0;
do_test(instr, 5 + xop[x].imm, modrm, mem, ctxt, fetch);
}
}
if ( xop[x].tbl[t].w & W1 )
{
if ( xop[x].tbl[t].l & L0 )
{
ptr[-1] = 0xf8;
ptr[1] = mem != mem_none ? 0x00 : 0xc0;
do_test(instr, 5 + xop[x].imm, modrm, mem, ctxt, fetch);
}
if ( xop[x].tbl[t].l & L1 )
{
ptr[-1] = 0xfc;
ptr[1] = mem != mem_none ? 0x00 : 0xc0;
do_test(instr, 5 + xop[x].imm, modrm, mem, ctxt, fetch);
}
}
}
}
if ( errors )
exit(1);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.