|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 19/30] x86emul: extend copy_VEX() for APX use
As long as we work just with non-eGPR-s internally, we can engage the
VEX counterpart encodings to carry out emulation of EVEX-from-VEX
promoted insns. VEX3 and EVEX are actually pretty similar in their 1st
and 2nd payload bytes:
VEX3 C4 R X B mmmmm W vvvv L pp
EVEX 62 R3 X3 B3 R4 B4 mmm W vvvv U pp z LL b V4 aaa
with the from-VEX form only altering the 3rd payload byte:
00 L 0 V4 NF 00
Therefore by clearing B4, R4, and U we can easily transform EVEX into
VEX. (Don't transform EVEX.LL just yet - we'd have to pass in the EVEX
struct [or a pointer to it], when in reality for now all promoted APX
insns are EVEX.128 anyway.)
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -115,9 +115,12 @@ static const uint8_t sse_prefix[] = { 0x
buf_ + 3; \
})
-#define copy_VEX(ptr, vex) ({ \
+#define copy_VEX(ptr, vex, from_evex) ({ \
if ( !mode_64bit() ) \
(vex).reg |= 8; \
+ if ( from_evex ) \
+ /* Clear what was EVEX.B4 and EVEX.R4. */ \
+ (vex).opcx &= 7; \
gcc11_wrap(ptr)[0 - PFX_BYTES] = ext < ext_8f08 ? 0xc4 : 0x8f; \
(ptr)[1 - PFX_BYTES] = (vex).raw[0]; \
(ptr)[2 - PFX_BYTES] = (vex).raw[1]; \
@@ -126,7 +129,7 @@ static const uint8_t sse_prefix[] = { 0x
#define copy_REX_VEX(ptr, rex, vex) do { \
if ( (vex).opcx != vex_none ) \
- copy_VEX(ptr, vex); \
+ copy_VEX(ptr, vex, false); \
else \
{ \
if ( (vex).pfx ) \
@@ -5378,7 +5381,7 @@ x86_emulate(
opc[1] = modrm & 0xf8;
place_ret(&opc[2]);
- copy_VEX(opc, vex);
+ copy_VEX(opc, vex, false);
ea.reg = decode_gpr(&_regs, NULL, modrm_rm);
invoke_stub("", "", "=m" (dummy) : "a" (*ea.reg));
@@ -5422,7 +5425,7 @@ x86_emulate(
opc[1] = modrm & 0xc7;
place_ret(&opc[2]);
- copy_VEX(opc, vex);
+ copy_VEX(opc, vex, false);
invoke_stub("", "", "=a" (dst.val) : [dummy] "i" (0));
put_stub(stub);
@@ -5450,7 +5453,7 @@ x86_emulate(
opc[1] = modrm;
place_ret(&opc[2]);
- copy_VEX(opc, vex);
+ copy_VEX(opc, vex, false);
_regs.eflags &= ~EFLAGS_MASK;
invoke_stub("",
_POST_EFLAGS("[eflags]", "[mask]", "[tmp]"),
@@ -6370,7 +6373,7 @@ x86_emulate(
* for that purpose.
*/
opc = init_prefixes(stub);
- pvex = copy_VEX(opc, vex);
+ pvex = copy_VEX(opc, vex, false);
pvex->opcx = vex_0f;
if ( elem_bytes == 4 )
pvex->pfx = vex_np;
@@ -6806,7 +6809,7 @@ x86_emulate(
/* Read destination, index, and mask registers. */
opc = init_prefixes(stub);
- pvex = copy_VEX(opc, vex);
+ pvex = copy_VEX(opc, vex, false);
pvex->opcx = vex_0f;
opc[0] = 0x7f; /* vmovdqa */
/* Use (%rax) as destination and modrm_reg as source. */
@@ -6876,7 +6879,7 @@ x86_emulate(
/* Write destination and mask registers. */
opc = init_prefixes(stub);
- pvex = copy_VEX(opc, vex);
+ pvex = copy_VEX(opc, vex, false);
pvex->opcx = vex_0f;
opc[0] = 0x6f; /* vmovdqa */
/* Use modrm_reg as destination and (%rax) as source. */
@@ -7942,7 +7945,7 @@ x86_emulate(
else
{
insn_bytes = PFX_BYTES + 3;
- copy_VEX(opc, vex);
+ copy_VEX(opc, vex, false);
}
place_ret(&opc[3]);
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |