[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86emul: support POPCNT
commit f88e810cc130d919dc69dfb1e632a602c9d10823 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Tue Jan 17 10:32:54 2017 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Tue Jan 17 10:32:54 2017 +0100 x86emul: support POPCNT Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- tools/tests/x86_emulator/test_x86_emulator.c | 46 ++++++++++++++++++++++++++++ tools/tests/x86_emulator/x86_emulate.h | 6 ++++ xen/arch/x86/x86_emulate/x86_emulate.c | 15 ++++++++- xen/include/asm-x86/cpufeature.h | 1 + 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/tools/tests/x86_emulator/test_x86_emulator.c b/tools/tests/x86_emulator/test_x86_emulator.c index 0d5655a..1cd3581 100644 --- a/tools/tests/x86_emulator/test_x86_emulator.c +++ b/tools/tests/x86_emulator/test_x86_emulator.c @@ -684,6 +684,52 @@ int main(int argc, char **argv) goto fail; printf("okay\n"); + printf("%-40s", "Testing popcnt (%edx),%cx..."); + if ( cpu_has_popcnt ) + { + instr[0] = 0x66; instr[1] = 0xf3; + instr[2] = 0x0f; instr[3] = 0xb8; instr[4] = 0x0a; + + *res = 0xfedcba98; + regs.edx = (unsigned long)res; + regs.eflags = 0xac3; + regs.eip = (unsigned long)&instr[0]; + rc = x86_emulate(&ctxt, &emulops); + if ( (rc != X86EMUL_OKAY) || (uint16_t)regs.ecx != 8 || *res != 0xfedcba98 || + (regs.eflags & 0xfeb) != 0x202 || + (regs.eip != (unsigned long)&instr[5]) ) + goto fail; + printf("okay\n"); + + printf("%-40s", "Testing popcnt (%edx),%ecx..."); + regs.eflags = 0xac3; + regs.eip = (unsigned long)&instr[1]; + rc = x86_emulate(&ctxt, &emulops); + if ( (rc != X86EMUL_OKAY) || regs.ecx != 20 || *res != 0xfedcba98 || + (regs.eflags & 0xfeb) != 0x202 || + (regs.eip != (unsigned long)&instr[5]) ) + goto fail; + printf("okay\n"); + +#ifdef __x86_64__ + printf("%-40s", "Testing popcnt (%rdx),%rcx..."); + instr[0] = 0xf3; + instr[1] = 0x48; + res[1] = 0x12345678; + regs.eflags = 0xac3; + regs.eip = (unsigned long)&instr[0]; + rc = x86_emulate(&ctxt, &emulops); + if ( (rc != X86EMUL_OKAY) || regs.ecx != 33 || + res[0] != 0xfedcba98 || res[1] != 0x12345678 || + (regs.eflags & 0xfeb) != 0x202 || + (regs.eip != (unsigned long)&instr[5]) ) + goto fail; + printf("okay\n"); +#endif + } + else + printf("skipped\n"); + printf("%-40s", "Testing lar (null selector)..."); instr[0] = 0x0f; instr[1] = 0x02; instr[2] = 0xc1; regs.eflags = 0x240; diff --git a/tools/tests/x86_emulator/x86_emulate.h b/tools/tests/x86_emulator/x86_emulate.h index 8bc2e43..596d55a 100644 --- a/tools/tests/x86_emulator/x86_emulate.h +++ b/tools/tests/x86_emulator/x86_emulate.h @@ -81,6 +81,12 @@ static inline uint64_t xgetbv(uint32_t xcr) (res.d & (1U << 26)) != 0; \ }) +#define cpu_has_popcnt ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(1, 0, &res, NULL); \ + (res.c & (1U << 23)) != 0; \ +}) + #define cpu_has_xsave ({ \ struct cpuid_leaf res; \ emul_test_cpuid(1, 0, &res, NULL); \ diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index 20285b2..6d6c53d 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -1335,6 +1335,7 @@ static bool vcpu_has( #define vcpu_has_cx16() vcpu_has( 1, ECX, 13, ctxt, ops) #define vcpu_has_sse4_2() vcpu_has( 1, ECX, 20, ctxt, ops) #define vcpu_has_movbe() vcpu_has( 1, ECX, 22, ctxt, ops) +#define vcpu_has_popcnt() vcpu_has( 1, ECX, 23, ctxt, ops) #define vcpu_has_avx() vcpu_has( 1, ECX, 28, ctxt, ops) #define vcpu_has_lahf_lm() vcpu_has(0x80000001, ECX, 0, ctxt, ops) #define vcpu_has_cr8_legacy() vcpu_has(0x80000001, ECX, 4, ctxt, ops) @@ -2103,8 +2104,12 @@ x86_decode_twobyte( op_bytes = mode_64bit() ? 8 : 4; break; + case 0xb8: /* jmpe / popcnt */ + if ( rep_prefix() ) + ctxt->opcode |= MASK_INSR(vex.pfx, X86EMUL_OPC_PFX_MASK); + break; + /* Intentionally not handling here despite being modified by F3: - case 0xb8: jmpe / popcnt case 0xbc: bsf / tzcnt case 0xbd: bsr / lzcnt * They're being dealt with in the execution phase (if at all). @@ -5614,6 +5619,14 @@ x86_emulate( dst.val = (uint16_t)src.val; break; + case X86EMUL_OPC_F3(0x0f, 0xb8): /* popcnt r/m,r */ + host_and_vcpu_must_have(popcnt); + asm ( "popcnt %1,%0" : "=r" (dst.val) : "rm" (src.val) ); + _regs._eflags &= ~EFLAGS_MASK; + if ( !dst.val ) + _regs._eflags |= EFLG_ZF; + break; + case X86EMUL_OPC(0x0f, 0xba): /* Grp8 */ switch ( modrm_reg & 7 ) { diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h index f34d01c..ba1c5e5 100644 --- a/xen/include/asm-x86/cpufeature.h +++ b/xen/include/asm-x86/cpufeature.h @@ -40,6 +40,7 @@ #define cpu_has_mmx 1 #define cpu_has_sse3 boot_cpu_has(X86_FEATURE_SSE3) #define cpu_has_sse4_2 boot_cpu_has(X86_FEATURE_SSE4_2) +#define cpu_has_popcnt boot_cpu_has(X86_FEATURE_POPCNT) #define cpu_has_htt boot_cpu_has(X86_FEATURE_HTT) #define cpu_has_nx boot_cpu_has(X86_FEATURE_NX) #define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLUSH) -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |