[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 05/10] x86emul: extend decoding / mem access testing to XOP-encoded insns
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- a/tools/tests/x86_emulator/predicates.c +++ b/tools/tests/x86_emulator/predicates.c @@ -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 @@ -1736,6 +1826,63 @@ void predicates_test(void *instr, struct } } } + } + + 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 )
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |