p***@xen.org
2018-11-20 14:24:07 UTC
commit d00b0e80b703e814a58d6034f1f99aeea8bc5493
Author: Jan Beulich <***@suse.com>
AuthorDate: Tue Nov 20 15:12:38 2018 +0100
Commit: Jan Beulich <***@suse.com>
CommitDate: Tue Nov 20 15:12:38 2018 +0100
x86emul: support AVX512F v{,u}comis{d,s} insns
Signed-off-by: Jan Beulich <***@suse.com>
Acked-by: Andrew Cooper <***@citrix.com>
---
tools/tests/x86_emulator/evex-disp8.c | 4 ++++
xen/arch/x86/x86_emulate/x86_emulate.c | 34 +++++++++++++++++++++++++++++-----
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/tools/tests/x86_emulator/evex-disp8.c b/tools/tests/x86_emulator/evex-disp8.c
index 43c4a9f992..9b6d14b9c9 100644
--- a/tools/tests/x86_emulator/evex-disp8.c
+++ b/tools/tests/x86_emulator/evex-disp8.c
@@ -107,6 +107,8 @@ static const struct test avx512f_all[] = {
INSN_FP(add, 0f, 58),
INSN(broadcastss, 66, 0f38, 18, el, d, el),
INSN_FP(cmp, 0f, c2),
+ INSN(comisd, 66, 0f, 2f, el, q, el),
+ INSN(comiss, , 0f, 2f, el, d, el),
INSN_FP(div, 0f, 5e),
INSN(fmadd132, 66, 0f38, 98, vl, sd, vl),
INSN(fmadd132, 66, 0f38, 99, el, sd, el),
@@ -166,6 +168,8 @@ static const struct test avx512f_all[] = {
INSN_PFP(shuf, 0f, c6),
INSN_FP(sqrt, 0f, 51),
INSN_FP(sub, 0f, 5c),
+ INSN(ucomisd, 66, 0f, 2e, el, q, el),
+ INSN(ucomiss, , 0f, 2e, el, d, el),
INSN_PFP(unpckh, 0f, 15),
INSN_PFP(unpckl, 0f, 14),
};
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
index 73ce8ddd99..91c0292779 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -299,7 +299,7 @@ static const struct twobyte_table {
[0x2a] = { DstImplicit|SrcMem|ModRM|Mov, simd_other },
[0x2b] = { DstMem|SrcImplicit|ModRM|Mov, simd_any_fp, d8s_vl },
[0x2c ... 0x2d] = { DstImplicit|SrcMem|ModRM|Mov, simd_other },
- [0x2e ... 0x2f] = { ImplicitOps|ModRM|TwoOp },
+ [0x2e ... 0x2f] = { ImplicitOps|ModRM|TwoOp, simd_none, d8s_dq },
[0x30 ... 0x35] = { ImplicitOps },
[0x37] = { ImplicitOps },
[0x38] = { DstReg|SrcMem|ModRM },
@@ -6125,24 +6125,34 @@ x86_emulate(
}
opc = init_prefixes(stub);
+ op_bytes = 4 << vex.pfx;
+ vcomi:
opc[0] = b;
opc[1] = modrm;
if ( ea.type == OP_MEM )
{
- rc = ops->read(ea.mem.seg, ea.mem.off, mmvalp, vex.pfx ? 8 : 4,
- ctxt);
+ rc = ops->read(ea.mem.seg, ea.mem.off, mmvalp, op_bytes, ctxt);
if ( rc != X86EMUL_OKAY )
goto done;
/* Convert memory operand to (%rAX). */
rex_prefix &= ~REX_B;
vex.b = 1;
+ evex.b = 1;
opc[1] &= 0x38;
}
- insn_bytes = PFX_BYTES + 2;
+ if ( evex_encoded() )
+ {
+ insn_bytes = EVEX_PFX_BYTES + 2;
+ copy_EVEX(opc, evex);
+ }
+ else
+ {
+ insn_bytes = PFX_BYTES + 2;
+ copy_REX_VEX(opc, rex_prefix, vex);
+ }
opc[2] = 0xc3;
- copy_REX_VEX(opc, rex_prefix, vex);
invoke_stub(_PRE_EFLAGS("[eflags]", "[mask]", "[tmp]"),
_POST_EFLAGS("[eflags]", "[mask]", "[tmp]"),
[eflags] "+g" (_regs.eflags),
@@ -6153,6 +6163,20 @@ x86_emulate(
ASSERT(!state->simd_size);
break;
+ CASE_SIMD_PACKED_FP(_EVEX, 0x0f, 0x2e): /* vucomis{s,d} xmm/mem,xmm */
+ CASE_SIMD_PACKED_FP(_EVEX, 0x0f, 0x2f): /* vcomis{s,d} xmm/mem,xmm */
+ generate_exception_if((evex.reg != 0xf || !evex.RX || evex.opmsk ||
+ (ea.type != OP_REG && evex.br) ||
+ evex.w != evex.pfx),
+ EXC_UD);
+ host_and_vcpu_must_have(avx512f);
+ avx512_vlen_check(true);
+ get_fpu(X86EMUL_FPU_zmm);
+
+ opc = init_evex(stub);
+ op_bytes = 4 << evex.w;
+ goto vcomi;
+
case X86EMUL_OPC(0x0f, 0x30): /* wrmsr */
generate_exception_if(!mode_ring0(), EXC_GP, 0);
fail_if(ops->write_msr == NULL);
--
generated by git-patchbot for /home/xen/git/xen.git#staging
Author: Jan Beulich <***@suse.com>
AuthorDate: Tue Nov 20 15:12:38 2018 +0100
Commit: Jan Beulich <***@suse.com>
CommitDate: Tue Nov 20 15:12:38 2018 +0100
x86emul: support AVX512F v{,u}comis{d,s} insns
Signed-off-by: Jan Beulich <***@suse.com>
Acked-by: Andrew Cooper <***@citrix.com>
---
tools/tests/x86_emulator/evex-disp8.c | 4 ++++
xen/arch/x86/x86_emulate/x86_emulate.c | 34 +++++++++++++++++++++++++++++-----
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/tools/tests/x86_emulator/evex-disp8.c b/tools/tests/x86_emulator/evex-disp8.c
index 43c4a9f992..9b6d14b9c9 100644
--- a/tools/tests/x86_emulator/evex-disp8.c
+++ b/tools/tests/x86_emulator/evex-disp8.c
@@ -107,6 +107,8 @@ static const struct test avx512f_all[] = {
INSN_FP(add, 0f, 58),
INSN(broadcastss, 66, 0f38, 18, el, d, el),
INSN_FP(cmp, 0f, c2),
+ INSN(comisd, 66, 0f, 2f, el, q, el),
+ INSN(comiss, , 0f, 2f, el, d, el),
INSN_FP(div, 0f, 5e),
INSN(fmadd132, 66, 0f38, 98, vl, sd, vl),
INSN(fmadd132, 66, 0f38, 99, el, sd, el),
@@ -166,6 +168,8 @@ static const struct test avx512f_all[] = {
INSN_PFP(shuf, 0f, c6),
INSN_FP(sqrt, 0f, 51),
INSN_FP(sub, 0f, 5c),
+ INSN(ucomisd, 66, 0f, 2e, el, q, el),
+ INSN(ucomiss, , 0f, 2e, el, d, el),
INSN_PFP(unpckh, 0f, 15),
INSN_PFP(unpckl, 0f, 14),
};
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
index 73ce8ddd99..91c0292779 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -299,7 +299,7 @@ static const struct twobyte_table {
[0x2a] = { DstImplicit|SrcMem|ModRM|Mov, simd_other },
[0x2b] = { DstMem|SrcImplicit|ModRM|Mov, simd_any_fp, d8s_vl },
[0x2c ... 0x2d] = { DstImplicit|SrcMem|ModRM|Mov, simd_other },
- [0x2e ... 0x2f] = { ImplicitOps|ModRM|TwoOp },
+ [0x2e ... 0x2f] = { ImplicitOps|ModRM|TwoOp, simd_none, d8s_dq },
[0x30 ... 0x35] = { ImplicitOps },
[0x37] = { ImplicitOps },
[0x38] = { DstReg|SrcMem|ModRM },
@@ -6125,24 +6125,34 @@ x86_emulate(
}
opc = init_prefixes(stub);
+ op_bytes = 4 << vex.pfx;
+ vcomi:
opc[0] = b;
opc[1] = modrm;
if ( ea.type == OP_MEM )
{
- rc = ops->read(ea.mem.seg, ea.mem.off, mmvalp, vex.pfx ? 8 : 4,
- ctxt);
+ rc = ops->read(ea.mem.seg, ea.mem.off, mmvalp, op_bytes, ctxt);
if ( rc != X86EMUL_OKAY )
goto done;
/* Convert memory operand to (%rAX). */
rex_prefix &= ~REX_B;
vex.b = 1;
+ evex.b = 1;
opc[1] &= 0x38;
}
- insn_bytes = PFX_BYTES + 2;
+ if ( evex_encoded() )
+ {
+ insn_bytes = EVEX_PFX_BYTES + 2;
+ copy_EVEX(opc, evex);
+ }
+ else
+ {
+ insn_bytes = PFX_BYTES + 2;
+ copy_REX_VEX(opc, rex_prefix, vex);
+ }
opc[2] = 0xc3;
- copy_REX_VEX(opc, rex_prefix, vex);
invoke_stub(_PRE_EFLAGS("[eflags]", "[mask]", "[tmp]"),
_POST_EFLAGS("[eflags]", "[mask]", "[tmp]"),
[eflags] "+g" (_regs.eflags),
@@ -6153,6 +6163,20 @@ x86_emulate(
ASSERT(!state->simd_size);
break;
+ CASE_SIMD_PACKED_FP(_EVEX, 0x0f, 0x2e): /* vucomis{s,d} xmm/mem,xmm */
+ CASE_SIMD_PACKED_FP(_EVEX, 0x0f, 0x2f): /* vcomis{s,d} xmm/mem,xmm */
+ generate_exception_if((evex.reg != 0xf || !evex.RX || evex.opmsk ||
+ (ea.type != OP_REG && evex.br) ||
+ evex.w != evex.pfx),
+ EXC_UD);
+ host_and_vcpu_must_have(avx512f);
+ avx512_vlen_check(true);
+ get_fpu(X86EMUL_FPU_zmm);
+
+ opc = init_evex(stub);
+ op_bytes = 4 << evex.w;
+ goto vcomi;
+
case X86EMUL_OPC(0x0f, 0x30): /* wrmsr */
generate_exception_if(!mode_ring0(), EXC_GP, 0);
fail_if(ops->write_msr == NULL);
--
generated by git-patchbot for /home/xen/git/xen.git#staging