|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 11/30] x86emul: switch to EVEX.R{3,4} nomenclature
The APX spec renames the R and R' fields, and it can be expected for the
SDM to follow once APX stuff is folded in. The new naming is also better
to reflect in our structure field identifiers.
Like we represent VEX.R and EVEX.R3 in rex_prefix, also represent
EVEX.R4 in rex2_prefix, simplifying the modrm_reg calculation.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
--- a/tools/tests/x86_emulator/evex-disp8.c
+++ b/tools/tests/x86_emulator/evex-disp8.c
@@ -939,10 +939,10 @@ static void test_one(const struct test *
struct {
uint8_t opcx:3;
uint8_t mbz:1;
- uint8_t R:1;
+ uint8_t r4:1;
uint8_t b:1;
uint8_t x:1;
- uint8_t r:1;
+ uint8_t r3:1;
uint8_t pfx:2;
uint8_t mbs:1;
uint8_t reg:4;
@@ -955,7 +955,7 @@ static void test_one(const struct test *
};
} evex = {
.opcx = test->spc, .pfx = test->pfx, .lr = vl,
- .R = 1, .b = 1, .x = 1, .r = 1, .mbs = 1,
+ .r4 = 1, .b = 1, .x = 1, .r3 = 1, .mbs = 1,
.reg = 0xf, .RX = 1, .opmsk = sg,
};
--- a/xen/arch/x86/x86_emulate/decode.c
+++ b/xen/arch/x86/x86_emulate/decode.c
@@ -1280,7 +1280,12 @@ int x86emul_decode(struct x86_emulate_st
generate_exception_if(!s->evex.opmsk && s->evex.z,
X86_EXC_UD);
if ( !mode_64bit() )
- s->evex.R = 1;
+ s->evex.r4 = 1;
+ else if ( s->xcr0 & X86_XCR0_APX )
+ {
+ if ( !s->evex.r4 )
+ s->rex2_prefix |= REX_R;
+ }
s->vex.opcx = s->evex.opcx;
break;
@@ -1394,8 +1399,7 @@ int x86emul_decode(struct x86_emulate_st
d &= ~ModRM;
#undef ModRM /* Only its aliases are valid to use from here on. */
s->modrm_reg = ((s->rex_prefix & 4) << 1) | ((s->modrm & 0x38) >> 3) |
- ((evex_encoded() ? !s->evex.R
- : !!(s->rex2_prefix & REX_R)) << 4);
+ (!!(s->rex2_prefix & REX_R) << 4);
s->modrm_rm = s->modrm & 0x07;
/*
--- a/xen/arch/x86/x86_emulate/private.h
+++ b/xen/arch/x86/x86_emulate/private.h
@@ -236,10 +236,10 @@ union evex {
struct { /* SDM names */
uint8_t opcx:3; /* mmm */
uint8_t mbz:1;
- uint8_t R:1; /* R' */
+ uint8_t r4:1; /* R4 (aka R') */
uint8_t b:1; /* B */
uint8_t x:1; /* X */
- uint8_t r:1; /* R */
+ uint8_t r3:1; /* R3 (aka R) */
uint8_t pfx:2; /* pp */
uint8_t mbs:1;
uint8_t reg:4; /* vvvv */
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -3774,7 +3774,8 @@ x86_emulate(
/* Convert GPR destination to %rAX and memory operand to (%rCX). */
rex_prefix &= ~REX_R;
vex.r = 1;
- evex.r = 1;
+ evex.r3 = 1;
+ evex.r4 = 1;
if ( ea.type == OP_MEM )
{
rex_prefix &= ~REX_B;
@@ -3825,7 +3826,8 @@ x86_emulate(
CASE_SIMD_SCALAR_FP(_EVEX, 0x0f, 0x2d): /* vcvts{s,d}2si xmm/mem,reg */
CASE_SIMD_SCALAR_FP(_EVEX, 0x0f, 0x78): /* vcvtts{s,d}2usi xmm/mem,reg */
CASE_SIMD_SCALAR_FP(_EVEX, 0x0f, 0x79): /* vcvts{s,d}2usi xmm/mem,reg */
- generate_exception_if((evex.reg != 0xf || !evex.RX || !evex.R ||
+ generate_exception_if((evex.reg != 0xf || !evex.RX ||
+ (!(state->xcr0 & X86_XCR0_APX) && !evex.r4) ||
evex.opmsk ||
(ea.type != OP_REG && evex.brs)),
X86_EXC_UD);
@@ -4465,7 +4467,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f38, 0x27): /* vptestm{d,q}
[xyz]mm/mem,[xyz]mm,k{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x29): /* vpcmpeqq
[xyz]mm/mem,[xyz]mm,k{k} */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x37): /* vpcmpgtq
[xyz]mm/mem,[xyz]mm,k{k} */
- generate_exception_if(!evex.r || !evex.R || evex.z, X86_EXC_UD);
+ generate_exception_if(!evex.r3 || !evex.r4 || evex.z, X86_EXC_UD);
if ( b & (ext == ext_0f38 ? 1 : 2) )
{
generate_exception_if(b != 0x27 && evex.w != (b & 1), X86_EXC_UD);
@@ -5447,7 +5449,7 @@ x86_emulate(
generate_exception_if((evex.w != (evex.pfx & VEX_PREFIX_DOUBLE_MASK) ||
(ea.type != OP_REG && evex.brs &&
(evex.pfx & VEX_PREFIX_SCALAR_MASK)) ||
- !evex.r || !evex.R || evex.z),
+ !evex.r3 || !evex.r4 || evex.z),
X86_EXC_UD);
visa_check(f);
if ( ea.type != OP_REG || !evex.brs )
@@ -6003,7 +6005,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_F3(0x0f38, 0x29): /* vpmov{b,w}2m [xyz]mm,k */
case X86EMUL_OPC_EVEX_F3(0x0f38, 0x39): /* vpmov{d,q}2m [xyz]mm,k */
- generate_exception_if(!evex.r || !evex.R, X86_EXC_UD);
+ generate_exception_if(!evex.r3 || !evex.r4, X86_EXC_UD);
/* fall through */
case X86EMUL_OPC_EVEX_F3(0x0f38, 0x28): /* vpmovm2{b,w} k,[xyz]mm */
case X86EMUL_OPC_EVEX_F3(0x0f38, 0x38): /* vpmovm2{d,q} k,[xyz]mm */
@@ -6268,7 +6270,7 @@ x86_emulate(
goto avx512f_no_sae;
case X86EMUL_OPC_EVEX_66(0x0f38, 0x8f): /* vpshufbitqmb
[xyz]mm/mem,[xyz]mm,k{k} */
- generate_exception_if(evex.w || !evex.r || !evex.R || evex.z,
X86_EXC_UD);
+ generate_exception_if(evex.w || !evex.r3 || !evex.r4 || evex.z,
X86_EXC_UD);
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f38, 0x54): /* vpopcnt{b,w}
[xyz]mm/mem,[xyz]mm{k} */
visa_check(_bitalg);
@@ -6345,7 +6347,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_F2(0x0f38, 0x68): /* vp2intersect{d,q}
[xyz]mm/mem,[xyz]mm,k+1 */
vcpu_must_have(avx512_vp2intersect);
- generate_exception_if(evex.opmsk || !evex.r || !evex.R, X86_EXC_UD);
+ generate_exception_if(evex.opmsk || !evex.r3 || !evex.r4, X86_EXC_UD);
op_bytes = 16 << evex.lr;
goto avx512f_no_sae;
@@ -6655,8 +6657,8 @@ x86_emulate(
pevex->pfx = vex_f3; /* vmovdqu{32,64} */
pevex->w = b & 1;
/* Switch to sib_index as source. */
- pevex->r = !mode_64bit() || !(state->sib_index & 0x08);
- pevex->R = !mode_64bit() || !(state->sib_index & 0x10);
+ pevex->r3 = !mode_64bit() || !(state->sib_index & 0x08);
+ pevex->r4 = !mode_64bit() || !(state->sib_index & 0x10);
opc[1] = (state->sib_index & 7) << 3;
invoke_stub("", "", "=m" (index) : "a" (&index));
@@ -6810,8 +6812,8 @@ x86_emulate(
pevex->pfx = vex_f3; /* vmovdqu{32,64} */
pevex->w = b & 1;
/* Switch to sib_index as source. */
- pevex->r = !mode_64bit() || !(state->sib_index & 0x08);
- pevex->R = !mode_64bit() || !(state->sib_index & 0x10);
+ pevex->r3 = !mode_64bit() || !(state->sib_index & 0x08);
+ pevex->r4 = !mode_64bit() || !(state->sib_index & 0x10);
opc[1] = (state->sib_index & 7) << 3;
invoke_stub("", "", "=m" (index) : "a" (&index));
@@ -7403,7 +7405,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_F2(0x0f3a, 0x66): /* vfpclassbf16
$imm8,[xyz]mm/mem,k{k} */
case X86EMUL_OPC_EVEX_F2(0x0f3a, 0xc2): /* vcmpbf16
$imm8,[xyz]mm/mem,[xyz]mm,k{k} */
- generate_exception_if(!evex.r || !evex.R || evex.z, X86_EXC_UD);
+ generate_exception_if(!evex.r3 || !evex.r4 || evex.z, X86_EXC_UD);
fallthrough;
case X86EMUL_OPC_EVEX_F2(0x0f3a, 0x08): /* vrndscalebf16
$imm8,[xyz]mm/mem,[xyz]mm{k} */
case X86EMUL_OPC_EVEX_F2(0x0f3a, 0x26): /* vgetmantbf16
$imm8,[xyz]mm/mem,[xyz]mm{k} */
@@ -7507,13 +7509,15 @@ x86_emulate(
goto pextr;
case X86EMUL_OPC_EVEX_66(0x0f, 0xc5): /* vpextrw $imm8,xmm,reg */
- generate_exception_if(ea.type != OP_REG || !evex.R, X86_EXC_UD);
+ generate_exception_if(ea.type != OP_REG ||
+ (!(state->xcr0 & X86_XCR0_APX) && !evex.r4),
+ X86_EXC_UD);
/* Convert to alternative encoding: We want to use a memory operand. */
evex.opcx = ext_0f3a;
b = 0x15;
modrm <<= 3;
- evex.r = evex.b;
- evex.R = evex.x;
+ evex.r3 = evex.b;
+ evex.r4 = evex.x;
/* fall through */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x14): /* vpextrb $imm8,xmm,r/m */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x15): /* vpextrw $imm8,xmm,r/m */
@@ -7665,7 +7669,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x1f): /* vpcmp{d,q}
$imm8,[xyz]mm/mem,[xyz]mm,k{k} */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x3e): /* vpcmpu{b,w}
$imm8,[xyz]mm/mem,[xyz]mm,k{k} */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x3f): /* vpcmp{b,w}
$imm8,[xyz]mm/mem,[xyz]mm,k{k} */
- generate_exception_if(!evex.r || !evex.R || evex.z, X86_EXC_UD);
+ generate_exception_if(!evex.r3 || !evex.r4 || evex.z, X86_EXC_UD);
if ( !(b & 0x20) )
goto avx512f_imm8_no_sae;
avx512bw_imm:
@@ -7942,7 +7946,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x66): /* vfpclassp{s,d}
$imm8,[xyz]mm/mem,k{k} */
case X86EMUL_OPC_EVEX_66(0x0f3a, 0x67): /* vfpclasss{s,d}
$imm8,xmm/mem,k{k} */
visa_check(dq);
- generate_exception_if(!evex.r || !evex.R || evex.z, X86_EXC_UD);
+ generate_exception_if(!evex.r3 || !evex.r4 || evex.z, X86_EXC_UD);
if ( !(b & 1) )
goto avx512f_imm8_no_sae;
generate_exception_if(evex.brs, X86_EXC_UD);
@@ -7952,7 +7956,7 @@ x86_emulate(
case X86EMUL_OPC_EVEX(0x0f3a, 0x66): /* vfpclassph $imm8,[xyz]mm/mem,k{k}
*/
case X86EMUL_OPC_EVEX(0x0f3a, 0x67): /* vfpclasssh $imm8,xmm/mem,k{k} */
visa_check(_fp16);
- generate_exception_if(evex.w || !evex.r || !evex.R || evex.z,
X86_EXC_UD);
+ generate_exception_if(evex.w || !evex.r3 || !evex.r4 || evex.z,
X86_EXC_UD);
if ( !(b & 1) )
goto avx512f_imm8_no_sae;
generate_exception_if(evex.brs, X86_EXC_UD);
@@ -7974,7 +7978,7 @@ x86_emulate(
/* fall through */
case X86EMUL_OPC_EVEX(0x0f3a, 0xc2): /* vcmpph
$imm8,[xyz]mm/mem,[xyz]mm,k{k} */
visa_check(_fp16);
- generate_exception_if(evex.w || !evex.r || !evex.R || evex.z,
X86_EXC_UD);
+ generate_exception_if(evex.w || !evex.r3 || !evex.r4 || evex.z,
X86_EXC_UD);
if ( ea.type != OP_REG || !evex.brs )
avx512_vlen_check(evex.pfx & VEX_PREFIX_SCALAR_MASK);
goto simd_imm8_zmm;
@@ -8206,7 +8210,8 @@ x86_emulate(
CASE_SIMD_SCALAR_FP(_EVEX, 5, 0x6c): /* vcvtts{s,d}2usis xmm/mem,reg */
CASE_SIMD_SCALAR_FP(_EVEX, 5, 0x6d): /* vcvtts{s,d}2sis xmm/mem,reg */
- generate_exception_if((evex.reg != 0xf || !evex.RX || !evex.R ||
+ generate_exception_if((evex.reg != 0xf || !evex.RX ||
+ (!(state->xcr0 & X86_XCR0_APX) && !evex.r4) ||
evex.opmsk),
X86_EXC_UD);
vcpu_must_have(avx10, 2);
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |