|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 27/30] x86emul: support APX+MOVRS insn
Besides adding table entries and case labels there's once again very
little to do here; generic map 4 handling takes care of things.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
SDE: -dmr
--- a/tools/tests/x86_emulator/evex-disp8.c
+++ b/tools/tests/x86_emulator/evex-disp8.c
@@ -1181,6 +1181,12 @@ static const struct test movdiri[] = {
INSN(movdiri, , map4, f9, el, dq, no),
};
+static const struct test movrs[] = {
+ INSN(movrs, , map4, 8a, el, b, no),
+ INSN(movrs, , map4, 8b, el, dq, no),
+ INSN(movrsw, 66, map4, 8b, el, w, no),
+};
+
static const struct test popcnt[] = {
INSN(popcnt, , map4, 88, el, dq, no),
INSN(popcntw, 66, map4, 88, el, w, no),
@@ -1801,6 +1807,7 @@ void evex_disp8_test(void *instr, struct
RUN(movbe);
RUN(movdir64b);
RUN(movdiri);
+ RUN(movrs);
RUN(popcnt);
#undef RUN
--- a/tools/tests/x86_emulator/predicates.c
+++ b/tools/tests/x86_emulator/predicates.c
@@ -2266,6 +2266,9 @@ static const struct evex {
{ { 0x85 }, 2, T, R, pfx_66, Wn, L0, SCC }, /* ctest<scc> */
{ { 0x88 }, 2, T, R, pfx_no, Wn, L0 }, /* popcnt */
{ { 0x88 }, 2, T, R, pfx_66, Wn, L0 }, /* popcnt */
+ { { 0x8a }, 2, T, R, pfx_no, WIG, L0 }, /* movrs */
+ { { 0x8b }, 2, T, R, pfx_no, Wn, L0 }, /* movrs */
+ { { 0x8b }, 2, T, R, pfx_66, Wn, L0 }, /* movrs */
{ { 0x8f, 0xc0 }, 2, F, R, pfx_no, Wn, L0, ND }, /* pop2 */
{ { 0xa5 }, 2, T, W, pfx_no, Wn, L0, ND }, /* shld */
{ { 0xa5 }, 2, T, W, pfx_66, Wn, L0, ND }, /* shld */
--- a/tools/tests/x86_emulator/test_x86_emulator.c
+++ b/tools/tests/x86_emulator/test_x86_emulator.c
@@ -2356,6 +2356,22 @@ int main(int argc, char **argv)
goto fail;
printf("okay\n");
+ if ( cpu_has_apx_f )
+ {
+ printf("%-40s", "Testing movrs 6(%r31),%r30w...");
+ instr[0] = 0x62; instr[1] = 0x4c; instr[2] = 0x7d; instr[3] = 0x08;
+ instr[4] = 0x8b; instr[5] = 0x77; instr[6] = 0x06;
+ regs.rip = (unsigned long)&instr[0];
+ load_egpr(30, 0x8888777766665555UL);
+ load_egpr(31, (unsigned long)res);
+ rc = x86_emulate(&ctxt, &emulops);
+ if ( (rc != X86EMUL_OKAY) ||
+ (regs.rip != (unsigned long)&instr[7]) ||
+ !check_egpr(30, 0x8888777766668877UL) )
+ goto fail;
+ printf("okay\n");
+ }
+
cpu_policy.feat.movrs = movrs;
}
--- a/xen/arch/x86/x86_emulate/decode.c
+++ b/xen/arch/x86/x86_emulate/decode.c
@@ -738,6 +738,13 @@ static const struct map4_table {
[vex_np] = { },
[vex_66] = { },
},
+ [0x8a] = { /* MOVRS (byte) */
+ [vex_np] = { .byte = true },
+ },
+ [0x8b] = { /* MOVRS ({,d,q}word) */
+ [vex_np] = { },
+ [vex_66] = { },
+ },
[0x88] = { /* POPCNT ({,d,q}word) */
[vex_np] = { .nf = true, .nci_ndd_nf = true },
[vex_66] = { .nf = true, .nci_ndd_nf = true },
@@ -1420,6 +1427,11 @@ decode_map4(struct x86_emulate_state *s,
nf = map4_table[(s->modrm_reg & 7) << 3][s->evex.pfx].nf;
break;
+ case 0x8a: case 0x8b: /* movrs */
+ case 0xf9: /* movdiri */
+ s->desc |= Mov;
+ break;
+
case 0xc0: case 0xc1: case 0xd0 ... 0xd3: /* Grp2 */
/* rcl/rcr do not allow EVEX.nf to be set. */
nf = (s->modrm_reg & 6) != 2;
@@ -1463,10 +1475,6 @@ decode_map4(struct x86_emulate_state *s,
s->op_bytes = 0;
break;
- case 0xf9: /* movdiri */
- s->desc |= Mov;
- break;
-
case 0xff: /* Grp5 */
switch ( s->modrm_reg & 7 )
{
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -6807,6 +6807,9 @@ x86_emulate(
case X86EMUL_OPC(0x0f38, 0x8a)
... X86EMUL_OPC(0x0f38, 0x8b): /* movrs */
+ case X86EMUL_OPC_EVEX (4, 0x8a): /* movrs r/m,r8 */
+ case X86EMUL_OPC_EVEX (4, 0x8b): /* movrs r/m,reg */
+ case X86EMUL_OPC_EVEX_66(4, 0x8b): /* movrs r/m,r16 */
vcpu_must_have(movrs);
dst.val = src.val;
break;
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |