|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 25/30] x86emul: support APX+MOVBE insn
Besides adding table entries and case labels there's very little to do
here; generic map 4 handling takes care of things.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
--- a/tools/tests/x86_emulator/evex-disp8.c
+++ b/tools/tests/x86_emulator/evex-disp8.c
@@ -1159,6 +1159,13 @@ static const struct test lzcnt[] = {
INSN(lzcntw, 66, map4, f5, el, w, no),
};
+static const struct test movbe[] = {
+ INSN(movbe, , map4, 60, el, dq, no),
+ INSN(movbe, , map4, 61, el, dq, no),
+ INSN(movbew, 66, map4, 60, el, w, no),
+ INSN(movbew, 66, map4, 61, el, w, no),
+};
+
static const struct test popcnt[] = {
INSN(popcnt, , map4, 88, el, dq, no),
INSN(popcntw, 66, map4, 88, el, w, no),
@@ -1756,6 +1763,7 @@ void evex_disp8_test(void *instr, struct
RUN(bmi2);
RUN(cmpccxadd);
RUN(lzcnt);
+ RUN(movbe);
RUN(popcnt);
#undef RUN
--- a/tools/tests/x86_emulator/predicates.c
+++ b/tools/tests/x86_emulator/predicates.c
@@ -2202,6 +2202,10 @@ static const struct evex {
CND(0x40, 2, T, R, pfx_no, Wn, L0, ND ), /* {,cf}cmov<cc> */ \
CND(0x40, 2, T, R, pfx_66, Wn, L0, ND ), /* {,cf}cmov<cc> */ \
CND(0x40, 2, T, W, pfx_f2, WIG, L0 ), /* set<cc> */
+ { { 0x60 }, 2, T, R, pfx_no, Wn, L0 }, /* movbe */
+ { { 0x60 }, 2, T, R, pfx_66, Wn, L0 }, /* movbe */
+ { { 0x61 }, 2, T, W, pfx_no, Wn, L0 }, /* movbe */
+ { { 0x61 }, 2, T, W, pfx_66, Wn, L0 }, /* movbe */
{ { 0x66 }, 2, T, R, pfx_66, Wn, L0 }, /* adcx */
{ { 0x66 }, 2, T, R, pfx_f3, Wn, L0 }, /* adox */
{ { 0x69 }, 6, T, R, pfx_no, Wn, L0 }, /* imul */
--- a/tools/tests/x86_emulator/test_x86_emulator.c
+++ b/tools/tests/x86_emulator/test_x86_emulator.c
@@ -2475,6 +2475,35 @@ int main(int argc, char **argv)
goto fail;
printf("okay\n");
+#ifdef __x86_64__
+ printf("%-40s", "Testing movbe %rax,%rcx...");
+ instr[0] = 0x62; instr[1] = 0xf4; instr[2] = 0xfc; instr[3] = 0x08;
+ instr[4] = 0x60; instr[5] = 0xc8;
+ regs.rip = (unsigned long)&instr[0];
+ rc = x86_emulate(&ctxt, &emulops);
+ if ( (rc != X86EMUL_OKAY) ||
+ (regs.rcx != 0x1234567800000000UL) ||
+ (regs.rip != (unsigned long)&instr[6]) )
+ goto fail;
+ printf("okay\n");
+
+ if ( cpu_has_apx_f )
+ {
+ printf("%-40s", "Testing movbe %r30w,2(%r31)...");
+ instr[1] = 0x4c; instr[2] = 0x7d;
+ instr[4] = 0x61; instr[5] = 0x77; instr[6] = 0x02;
+ regs.rip = (unsigned long)&instr[0];
+ load_egpr(30, 0x12345678);
+ load_egpr(31, (unsigned long)res);
+ rc = x86_emulate(&ctxt, &emulops);
+ if ( (rc != X86EMUL_OKAY) ||
+ (*res != 0x78561234) ||
+ (regs.rip != (unsigned long)&instr[7]) )
+ goto fail;
+ printf("okay\n");
+ }
+#endif
+
printf("%-40s", "Testing popcnt (%edx),%cx...");
if ( cpu_has_popcnt )
{
--- a/tools/tests/x86_emulator/x86-emulate.h
+++ b/tools/tests/x86_emulator/x86-emulate.h
@@ -168,6 +168,7 @@ void wrpkru(unsigned int val);
#define cpu_has_fma (cpu_policy.basic.fma && xcr0_mask(6))
#define cpu_has_sse4_1 cpu_policy.basic.sse4_1
#define cpu_has_sse4_2 cpu_policy.basic.sse4_2
+#define cpu_has_movbe cpu_policy.basic.movbe
#define cpu_has_popcnt cpu_policy.basic.popcnt
#define cpu_has_aesni cpu_policy.basic.aesni
#define cpu_has_avx (cpu_policy.basic.avx && xcr0_mask(6))
--- a/xen/arch/x86/x86_emulate/decode.c
+++ b/xen/arch/x86/x86_emulate/decode.c
@@ -691,6 +691,14 @@ static const struct map4_table {
[vex_f2] = { .to_mem = true, .byte = true, .nd = true,
.nci_ndd_nf = true },
},
+ [0x60] = { /* MOVBE ({,d,q}word) */
+ [vex_np] = { },
+ [vex_66] = { },
+ },
+ [0x61] = { /* MOVBE ({,d,q}word) */
+ [vex_np] = { .to_mem = true },
+ [vex_66] = { .to_mem = true },
+ },
[0x66] = {
[vex_66] = { .nd = true }, /* ADCX */
[vex_f3] = { .nd = true }, /* ADOX */
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -7345,6 +7345,11 @@ x86_emulate(
case X86EMUL_OPC(0x0f38, 0xf0): /* movbe m,r */
case X86EMUL_OPC(0x0f38, 0xf1): /* movbe r,m */
generate_exception_if(ea.type != OP_MEM, X86_EXC_UD);
+ fallthrough;
+ case X86EMUL_OPC_EVEX (4, 0x60): /* movbe r/m,reg */
+ case X86EMUL_OPC_EVEX_66(4, 0x60): /* movbe r/m,r16 */
+ case X86EMUL_OPC_EVEX (4, 0x61): /* movbe reg,r/m */
+ case X86EMUL_OPC_EVEX_66(4, 0x61): /* movbe r16,r/m */
vcpu_must_have(movbe);
switch ( op_bytes )
{
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |