|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4 41/44] x86emul: support AVX512F legacy-equivalent scalar int/FP conversion insns
VCVT{,T}S{S,D}2SI use EVEX.W for their destination (register) rather
than their (possibly memory) source operand size and hence need a
"manual" override of disp8scale.
Slightly adjust the scalar to_int() in the test harness, to increase the
chances of the operand ending up in memory.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
v4: New.
--- a/tools/tests/x86_emulator/evex-disp8.c
+++ b/tools/tests/x86_emulator/evex-disp8.c
@@ -106,8 +106,16 @@ static const struct test avx512f_all[] =
INSN(cvtps2dq, 66, 0f, 5b, vl, d, vl),
INSN(cvtps2pd, , 0f, 5a, vl_2, d, vl),
INSN(cvtps2ph, 66, 0f3a, 1d, vl_2, d_nb, vl),
+ INSN(cvtsd2si, f2, 0f, 2d, el, q, el),
INSN(cvtsd2ss, f2, 0f, 5a, el, q, el),
+ INSN(cvtsi2sd, f2, 0f, 2a, el, dq64, el),
+ INSN(cvtsi2ss, f3, 0f, 2a, el, dq64, el),
INSN(cvtss2sd, f3, 0f, 5a, el, d, el),
+ INSN(cvtss2si, f3, 0f, 2d, el, d, el),
+ INSN(cvttpd2dq, 66, 0f, e6, vl, q, vl),
+ INSN(cvttps2dq, f3, 0f, 5b, vl, d, vl),
+ INSN(cvttsd2si, f2, 0f, 2c, el, q, el),
+ INSN(cvttss2si, f3, 0f, 2c, el, d, el),
INSN_FP(div, 0f, 5e),
INSN(fmadd132, 66, 0f38, 98, vl, sd, vl),
INSN(fmadd132, 66, 0f38, 99, el, sd, el),
@@ -715,8 +723,9 @@ static void test_group(const struct test
break;
case ESZ_dq:
- test_pair(&tests[i], vl[j], ESZ_d, "d", ESZ_q, "q",
- instr, ctxt);
+ test_pair(&tests[i], vl[j], ESZ_d,
+ strncmp(tests[i].mnemonic, "cvt", 3) ? "d" : "l",
+ ESZ_q, "q", instr, ctxt);
break;
#ifdef __i386__
--- a/tools/tests/x86_emulator/simd.c
+++ b/tools/tests/x86_emulator/simd.c
@@ -89,7 +89,7 @@ static inline bool _to_bool(byte_vec_t b
#endif
#if VEC_SIZE == FLOAT_SIZE
-# define to_int(x) ((vec_t){ (int)(x)[0] })
+# define to_int(x) ({ int i_ = (x)[0]; touch(i_); ((vec_t){ i_ }); })
#elif VEC_SIZE == 8 && FLOAT_SIZE == 4 && defined(__3dNOW__)
# define to_int(x) __builtin_ia32_pi2fd(__builtin_ia32_pf2id(x))
#elif defined(FLOAT_SIZE) && VEC_SIZE > FLOAT_SIZE && defined(__AVX512F__) && \
--- a/tools/tests/x86_emulator/simd.h
+++ b/tools/tests/x86_emulator/simd.h
@@ -340,10 +340,28 @@ OVR(cvtps2dq);
OVR(cvtps2pd);
OVR(cvtps2ph);
OVR(cvtsd2ss);
+OVR(cvtsd2si);
+OVR(cvtsd2sil);
+OVR(cvtsd2siq);
+OVR(cvtsi2sd);
+OVR(cvtsi2sdl);
+OVR(cvtsi2sdq);
+OVR(cvtsi2ss);
+OVR(cvtsi2ssl);
+OVR(cvtsi2ssq);
OVR(cvtss2sd);
+OVR(cvtss2si);
+OVR(cvtss2sil);
+OVR(cvtss2siq);
OVR(cvttpd2dqx);
OVR(cvttpd2dqy);
OVR(cvttps2dq);
+OVR(cvttsd2si);
+OVR(cvttsd2sil);
+OVR(cvttsd2siq);
+OVR(cvttss2si);
+OVR(cvttss2sil);
+OVR(cvttss2siq);
OVR(movddup);
OVR(movntdq);
OVR(movntdqa);
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -296,7 +296,7 @@ static const struct twobyte_table {
[0x22 ... 0x23] = { DstImplicit|SrcMem|ModRM },
[0x28] = { DstImplicit|SrcMem|ModRM|Mov, simd_packed_fp, d8s_vl },
[0x29] = { DstMem|SrcImplicit|ModRM|Mov, simd_packed_fp, d8s_vl },
- [0x2a] = { DstImplicit|SrcMem|ModRM|Mov, simd_other },
+ [0x2a] = { DstImplicit|SrcMem|ModRM|Mov, simd_other, d8s_dq64 },
[0x2b] = { DstMem|SrcImplicit|ModRM|Mov, simd_any_fp, d8s_vl },
[0x2c ... 0x2d] = { DstImplicit|SrcMem|ModRM|Mov, simd_other },
[0x2e ... 0x2f] = { ImplicitOps|ModRM|TwoOp, simd_none, d8s_dq },
@@ -3060,6 +3060,12 @@ x86_decode(
modrm_mod = 3;
break;
+ case 0x2c: /* vcvtts{s,d}2si need special casing */
+ case 0x2d: /* vcvts{s,d}2si need special casing */
+ if ( evex_encoded() )
+ disp8scale = 2 + (evex.pfx & VEX_PREFIX_DOUBLE_MASK);
+ break;
+
case 0x5a: /* vcvtps2pd needs special casing */
if ( disp8scale && !evex.pfx && !evex.br )
--disp8scale;
@@ -6168,6 +6174,26 @@ x86_emulate(
state->simd_size = simd_none;
goto simd_0f_rm;
+ CASE_SIMD_SCALAR_FP(_EVEX, 0x0f, 0x2a): /* vcvtsi2s{s,d} r/m,xmm,xmm */
+ generate_exception_if(evex.opmsk || (ea.type != OP_REG && evex.br),
+ EXC_UD);
+ host_and_vcpu_must_have(avx512f);
+ avx512_vlen_check(true);
+ get_fpu(X86EMUL_FPU_zmm);
+
+ if ( ea.type == OP_MEM )
+ {
+ rc = read_ulong(ea.mem.seg, ea.mem.off, &src.val,
+ rex_prefix & REX_W ? 8 : 4, ctxt, ops);
+ if ( rc != X86EMUL_OKAY )
+ goto done;
+ }
+ else
+ src.val = rex_prefix & REX_W ? *ea.reg : (uint32_t)*ea.reg;
+
+ state->simd_size = simd_none;
+ goto avx512f_rm;
+
CASE_SIMD_SCALAR_FP(, 0x0f, 0x2c): /* cvtts{s,d}2si xmm/mem,reg */
CASE_SIMD_SCALAR_FP(_VEX, 0x0f, 0x2c): /* vcvtts{s,d}2si xmm/mem,reg */
CASE_SIMD_SCALAR_FP(, 0x0f, 0x2d): /* cvts{s,d}2si xmm/mem,reg */
@@ -6189,14 +6215,17 @@ x86_emulate(
}
opc = init_prefixes(stub);
+ cvts_2si:
opc[0] = b;
/* Convert GPR destination to %rAX and memory operand to (%rCX). */
rex_prefix &= ~REX_R;
vex.r = 1;
+ evex.r = 1;
if ( ea.type == OP_MEM )
{
rex_prefix &= ~REX_B;
vex.b = 1;
+ evex.b = 1;
opc[1] = 0x01;
rc = ops->read(ea.mem.seg, ea.mem.off, mmvalp,
@@ -6207,11 +6236,22 @@ x86_emulate(
else
opc[1] = modrm & 0xc7;
if ( !mode_64bit() )
+ {
vex.w = 0;
- insn_bytes = PFX_BYTES + 2;
+ evex.w = 0;
+ }
+ 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);
ea.reg = decode_gpr(&_regs, modrm_reg);
invoke_stub("", "", "=a" (*ea.reg) : "c" (mmvalp), "m" (*mmvalp));
@@ -6219,6 +6259,17 @@ x86_emulate(
state->simd_size = simd_none;
break;
+ CASE_SIMD_SCALAR_FP(_EVEX, 0x0f, 0x2c): /* vcvtts{s,d}2si xmm/mem,reg */
+ CASE_SIMD_SCALAR_FP(_EVEX, 0x0f, 0x2d): /* vcvts{s,d}2si xmm/mem,reg */
+ generate_exception_if((evex.reg != 0xf || !evex.RX || evex.opmsk ||
+ (ea.type != OP_REG && evex.br)),
+ EXC_UD);
+ host_and_vcpu_must_have(avx512f);
+ avx512_vlen_check(true);
+ get_fpu(X86EMUL_FPU_zmm);
+ opc = init_evex(stub);
+ goto cvts_2si;
+
CASE_SIMD_PACKED_FP(, 0x0f, 0x2e): /* ucomis{s,d} xmm/mem,xmm */
CASE_SIMD_PACKED_FP(_VEX, 0x0f, 0x2e): /* vucomis{s,d} xmm/mem,xmm */
CASE_SIMD_PACKED_FP(, 0x0f, 0x2f): /* comis{s,d} xmm/mem,xmm */
@@ -6870,6 +6921,7 @@ x86_emulate(
host_and_vcpu_must_have(avx512f);
get_fpu(X86EMUL_FPU_zmm);
+ avx512f_rm:
opc = init_evex(stub);
opc[0] = b;
/* Convert memory/GPR operand to (%rAX). */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |