[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 02/18] x86emul: support most memory accessing MMX/SSE{, 2, 3} insns
On 15/02/17 11:07, Jan Beulich wrote: > --- a/xen/arch/x86/x86_emulate/x86_emulate.c > +++ b/xen/arch/x86/x86_emulate/x86_emulate.c > @@ -45,6 +45,8 @@ > #define ModRM (1<<6) > /* Destination is only written; never read. */ > #define Mov (1<<7) > +/* VEX/EVEX (SIMD only): 2nd source operand unused (must be all ones) */ > +#define TwoOp Mov Is this safe? It looks overloaded to me. The Mov behaviour is still applicable even with TwoOp VEX/EVEX encodings. > /* All operands are implicit in the opcode. */ > #define ImplicitOps (DstImplicit|SrcImplicit) > > @@ -180,8 +182,44 @@ static const opcode_desc_t opcode_table[ > ImplicitOps, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, > DstMem|SrcNone|ModRM > }; > > +enum simd_opsize { > + simd_none, Please can we have newlines here, > + /* > + * Ordinary packed integers: > + * - 64 bits without prefix 66 (MMX) > + * - 128 bits with prefix 66 (SSEn) > + * - 128/256 bits depending on VEX.L (AVX) > + */ and here, etc, to help identify which comment is attached to which enum. > + simd_packed_int, > + /* > + * Ordinary packed/scalar floating point: > + * - 128 bits without prefix or with prefix 66 (SSEn) > + * - 128/256 bits depending on VEX.L (AVX) > + * - 32 bits with prefix F3 (scalar single) > + * - 64 bits with prefix F2 (scalar doubgle) > + */ > + simd_any_fp, > + /* > + * Packed floating point: > + * - 128 bits without prefix or with prefix 66 (SSEn) > + * - 128/256 bits depending on VEX.L (AVX) > + */ > + simd_packed_fp, > + /* > + * Single precision packed/scalar floating point: > + * - 128 bits without prefix (SSEn) > + * - 128/256 bits depending on VEX.L, no prefix (AVX) > + * - 32 bits with prefix F3 (scalar) > + */ > + simd_single_fp, > + /* Operand size encoded in non-standard way. */ > + simd_other , > +}; > +typedef uint8_t simd_opsize_t; > + > static const struct { > opcode_desc_t desc; > + simd_opsize_t size; > } twobyte_table[256] = { > [0x00] = { ModRM }, > [0x01] = { ImplicitOps|ModRM }, > @@ -196,22 +234,41 @@ static const struct { > [0x0d] = { ImplicitOps|ModRM }, > [0x0e] = { ImplicitOps }, > [0x0f] = { ModRM|SrcImmByte }, > - [0x10 ... 0x1f] = { ImplicitOps|ModRM }, > + [0x10] = { DstImplicit|SrcMem|ModRM|Mov, simd_any_fp }, > + [0x11] = { DstMem|SrcImplicit|ModRM|Mov, simd_any_fp }, > + [0x12 ... 0x13] = { ImplicitOps|ModRM }, > + [0x14 ... 0x15] = { DstImplicit|SrcMem|ModRM, simd_packed_fp }, > + [0x16 ... 0x1f] = { ImplicitOps|ModRM }, > [0x20 ... 0x21] = { DstMem|SrcImplicit|ModRM }, > [0x22 ... 0x23] = { DstImplicit|SrcMem|ModRM }, > - [0x28 ... 0x2f] = { ImplicitOps|ModRM }, > + [0x28] = { DstImplicit|SrcMem|ModRM|Mov, simd_packed_fp }, > + [0x29] = { DstMem|SrcImplicit|ModRM|Mov, simd_packed_fp }, > + [0x2a] = { ImplicitOps|ModRM }, > + [0x2b] = { DstMem|SrcImplicit|ModRM|Mov, simd_any_fp }, > + [0x2c ... 0x2f] = { ImplicitOps|ModRM }, > [0x30 ... 0x35] = { ImplicitOps }, > [0x37] = { ImplicitOps }, > [0x38] = { DstReg|SrcMem|ModRM }, > [0x3a] = { DstReg|SrcImmByte|ModRM }, > [0x40 ... 0x4f] = { DstReg|SrcMem|ModRM|Mov }, > - [0x50 ... 0x6e] = { ModRM }, > - [0x6f] = { ImplicitOps|ModRM }, > - [0x70 ... 0x73] = { SrcImmByte|ModRM }, > - [0x74 ... 0x76] = { ModRM }, > - [0x77] = { ImplicitOps }, > + [0x50] = { ModRM }, > + [0x51] = { DstImplicit|SrcMem|ModRM|TwoOp, simd_any_fp }, > + [0x52 ... 0x53] = { DstImplicit|SrcMem|ModRM|TwoOp, simd_single_fp }, RCPPS/RCPSS all have 3 operands. Why is TwoOp used here? > + [0x54 ... 0x57] = { DstImplicit|SrcMem|ModRM, simd_packed_fp }, > + [0x58 ... 0x59] = { DstImplicit|SrcMem|ModRM, simd_any_fp }, > + [0x5a ... 0x5b] = { ModRM }, > + [0x5c ... 0x5f] = { DstImplicit|SrcMem|ModRM, simd_any_fp }, > + [0x60 ... 0x62] = { DstImplicit|SrcMem|ModRM, simd_other }, > + [0x63 ... 0x67] = { DstImplicit|SrcMem|ModRM, simd_packed_int }, > + [0x68 ... 0x6a] = { DstImplicit|SrcMem|ModRM, simd_other }, > + [0x6b ... 0x6d] = { DstImplicit|SrcMem|ModRM, simd_packed_int }, > + [0x6e ... 0x6f] = { ImplicitOps|ModRM }, > + [0x70] = { SrcImmByte|ModRM|TwoOp, simd_other }, > + [0x71 ... 0x73] = { SrcImmByte|ModRM }, > + [0x74 ... 0x76] = { DstImplicit|SrcMem|ModRM, simd_packed_int }, > + [0x77] = { DstImplicit|SrcNone }, > [0x78 ... 0x79] = { ModRM }, > - [0x7c ... 0x7d] = { ModRM }, > + [0x7c ... 0x7d] = { DstImplicit|SrcMem|ModRM, simd_other }, > [0x7e ... 0x7f] = { ImplicitOps|ModRM }, > [0x80 ... 0x8f] = { DstImplicit|SrcImm }, > [0x90 ... 0x9f] = { ByteOp|DstMem|SrcNone|ModRM|Mov }, > @@ -2601,13 +2692,53 @@ x86_decode( > ea.mem.off = truncate_ea(ea.mem.off); > } > > - /* > - * When prefix 66 has a meaning different from operand-size override, > - * operand size defaults to 4 and can't be overridden to 2. > - */ > - if ( op_bytes == 2 && > - (ctxt->opcode & X86EMUL_OPC_PFX_MASK) == X86EMUL_OPC_66(0, 0) ) > - op_bytes = 4; > + switch ( state->simd_size ) > + { > + case simd_none: > + /* > + * When prefix 66 has a meaning different from operand-size override, > + * operand size defaults to 4 and can't be overridden to 2. > + */ > + if ( op_bytes == 2 && > + (ctxt->opcode & X86EMUL_OPC_PFX_MASK) == X86EMUL_OPC_66(0, 0) ) > + op_bytes = 4; > + break; > + > + case simd_packed_int: > + switch ( vex.pfx ) > + { > + case vex_none: op_bytes = 8; break; > + case vex_66: op_bytes = 16 << vex.l; break; > + default: op_bytes = 0; break; > + } > + break; > + > + case simd_single_fp: > + if ( vex.pfx & VEX_PREFIX_DOUBLE_MASK ) This logic would be far easier to follow by using vex.pfx == vex_66 || vex.pfx == vex_f2. > + { > + op_bytes = 0; > + break; > + case simd_packed_fp: > + if ( vex.pfx & VEX_PREFIX_SCALAR_MASK ) Similarly here, vex_none || vex_f3 Having said that, taking VSHUFPS (0xc6) as example of simd_packed_fp, this instruction is defined for vex_none and vex_66, both of which have op_bytes of 16 when not vex encoded. > @@ -5020,116 +5159,117 @@ x86_emulate( > case X86EMUL_OPC(0x0f, 0x19) ... X86EMUL_OPC(0x0f, 0x1f): /* nop */ > break; > > - case X86EMUL_OPC(0x0f, 0x2b): /* movntps xmm,m128 */ > - case X86EMUL_OPC_VEX(0x0f, 0x2b): /* vmovntps xmm,m128 */ > - /* vmovntps ymm,m256 */ > - case X86EMUL_OPC_66(0x0f, 0x2b): /* movntpd xmm,m128 */ > - case X86EMUL_OPC_VEX_66(0x0f, 0x2b): /* vmovntpd xmm,m128 */ > - /* vmovntpd ymm,m256 */ > - fail_if(ea.type != OP_MEM); > - /* fall through */ > - case X86EMUL_OPC(0x0f, 0x28): /* movaps xmm/m128,xmm */ > - case X86EMUL_OPC_VEX(0x0f, 0x28): /* vmovaps xmm/m128,xmm */ > - /* vmovaps ymm/m256,ymm */ > - case X86EMUL_OPC_66(0x0f, 0x28): /* movapd xmm/m128,xmm */ > - case X86EMUL_OPC_VEX_66(0x0f, 0x28): /* vmovapd xmm/m128,xmm */ > - /* vmovapd ymm/m256,ymm */ > - case X86EMUL_OPC(0x0f, 0x29): /* movaps xmm,xmm/m128 */ > - case X86EMUL_OPC_VEX(0x0f, 0x29): /* vmovaps xmm,xmm/m128 */ > - /* vmovaps ymm,ymm/m256 */ > - case X86EMUL_OPC_66(0x0f, 0x29): /* movapd xmm,xmm/m128 */ > - case X86EMUL_OPC_VEX_66(0x0f, 0x29): /* vmovapd xmm,xmm/m128 */ > - /* vmovapd ymm,ymm/m256 */ > - case X86EMUL_OPC(0x0f, 0x10): /* movups xmm/m128,xmm */ > - case X86EMUL_OPC_VEX(0x0f, 0x10): /* vmovups xmm/m128,xmm */ > - /* vmovups ymm/m256,ymm */ > - case X86EMUL_OPC_66(0x0f, 0x10): /* movupd xmm/m128,xmm */ > - case X86EMUL_OPC_VEX_66(0x0f, 0x10): /* vmovupd xmm/m128,xmm */ > - /* vmovupd ymm/m256,ymm */ > - case X86EMUL_OPC_F3(0x0f, 0x10): /* movss xmm/m32,xmm */ > - case X86EMUL_OPC_VEX_F3(0x0f, 0x10): /* vmovss xmm/m32,xmm */ > - case X86EMUL_OPC_F2(0x0f, 0x10): /* movsd xmm/m64,xmm */ > - case X86EMUL_OPC_VEX_F2(0x0f, 0x10): /* vmovsd xmm/m64,xmm */ > - case X86EMUL_OPC(0x0f, 0x11): /* movups xmm,xmm/m128 */ > - case X86EMUL_OPC_VEX(0x0f, 0x11): /* vmovups xmm,xmm/m128 */ > - /* vmovups ymm,ymm/m256 */ > - case X86EMUL_OPC_66(0x0f, 0x11): /* movupd xmm,xmm/m128 */ > - case X86EMUL_OPC_VEX_66(0x0f, 0x11): /* vmovupd xmm,xmm/m128 */ > - /* vmovupd ymm,ymm/m256 */ > - case X86EMUL_OPC_F3(0x0f, 0x11): /* movss xmm,xmm/m32 */ > - case X86EMUL_OPC_VEX_F3(0x0f, 0x11): /* vmovss xmm,xmm/m32 */ > - case X86EMUL_OPC_F2(0x0f, 0x11): /* movsd xmm,xmm/m64 */ > - case X86EMUL_OPC_VEX_F2(0x0f, 0x11): /* vmovsd xmm,xmm/m64 */ > - { > - uint8_t *buf = get_stub(stub); > +#define CASE_SIMD_PACKED_INT(pfx, opc) \ > + case X86EMUL_OPC(pfx, opc): \ > + case X86EMUL_OPC_66(pfx, opc) > +#define CASE_SIMD_SINGLE_FP(kind, pfx, opc) \ > + case X86EMUL_OPC##kind(pfx, opc): \ > + case X86EMUL_OPC##kind##_F3(pfx, opc) > +#define CASE_SIMD_DOUBLE_FP(kind, pfx, opc) \ > + case X86EMUL_OPC##kind##_66(pfx, opc): \ > + case X86EMUL_OPC##kind##_F2(pfx, opc) > +#define CASE_SIMD_ALL_FP(kind, pfx, opc) \ > + CASE_SIMD_SINGLE_FP(kind, pfx, opc): \ > + CASE_SIMD_DOUBLE_FP(kind, pfx, opc) > +#define CASE_SIMD_PACKED_FP(kind, pfx, opc) \ > + case X86EMUL_OPC##kind(pfx, opc): \ > + case X86EMUL_OPC##kind##_66(pfx, opc) > +#define CASE_SIMD_SCALAR_FP(kind, pfx, opc) \ > + case X86EMUL_OPC##kind##_F3(pfx, opc): \ > + case X86EMUL_OPC##kind##_F2(pfx, opc) > > - fic.insn_bytes = 5; > - buf[0] = 0x3e; > - buf[1] = 0x3e; > - buf[2] = 0x0f; > - buf[3] = b; > - buf[4] = modrm; > - buf[5] = 0xc3; > + CASE_SIMD_SCALAR_FP(, 0x0f, 0x2b): /* movnts{s,d} xmm,mem */ > + host_and_vcpu_must_have(sse4a); > + /* fall through */ > + CASE_SIMD_PACKED_FP(, 0x0f, 0x2b): /* movntp{s,d} xmm,m128 */ > + CASE_SIMD_PACKED_FP(_VEX, 0x0f, 0x2b): /* vmovntp{s,d} {x,y}mm,mem */ > + generate_exception_if(ea.type != OP_MEM, EXC_UD); > + sfence = true; Why do we need to emit an sfence at this point? The software hitting this emulation is the entity which should be making sfence decisions. > + /* fall through */ > + CASE_SIMD_ALL_FP(, 0x0f, 0x10): /* mov{up,s}{s,d} xmm/mem,xmm */ > + CASE_SIMD_PACKED_FP(_VEX, 0x0f, 0x10): /* vmovup{s,d} > {x,y}mm/mem,{x,y}mm */ > + CASE_SIMD_SCALAR_FP(_VEX, 0x0f, 0x10): /* vmovs{s,d} mem,xmm */ > + /* vmovs{s,d} xmm,xmm,xmm */ > + CASE_SIMD_ALL_FP(, 0x0f, 0x11): /* mov{up,s}{s,d} xmm,xmm/mem */ > + CASE_SIMD_PACKED_FP(_VEX, 0x0f, 0x11): /* vmovup{s,d} > {x,y}mm,{x,y}mm/mem */ > + CASE_SIMD_SCALAR_FP(_VEX, 0x0f, 0x11): /* vmovs{s,d} xmm,mem */ > + /* vmovs{s,d} xmm,xmm,xmm */ > + CASE_SIMD_PACKED_FP(, 0x0f, 0x14): /* unpcklp{s,d} xmm/m128,xmm */ > + CASE_SIMD_PACKED_FP(_VEX, 0x0f, 0x14): /* vunpcklp{s,d} > {x,y}mm/mem,{x,y}mm,{x,y}mm */ > + CASE_SIMD_PACKED_FP(, 0x0f, 0x15): /* unpckhp{s,d} xmm/m128,xmm */ > + CASE_SIMD_PACKED_FP(_VEX, 0x0f, 0x15): /* vunpckhp{s,d} > {x,y}mm/mem,{x,y}mm,{x,y}mm */ > + CASE_SIMD_PACKED_FP(, 0x0f, 0x28): /* movap{s,d} xmm/m128,xmm */ > + CASE_SIMD_PACKED_FP(_VEX, 0x0f, 0x28): /* vmovap{s,d} > {x,y}mm/mem,{x,y}mm */ > + CASE_SIMD_PACKED_FP(, 0x0f, 0x29): /* movap{s,d} xmm,xmm/m128 */ > + CASE_SIMD_PACKED_FP(_VEX, 0x0f, 0x29): /* vmovap{s,d} > {x,y}mm,{x,y}mm/mem */ > + CASE_SIMD_ALL_FP(, 0x0f, 0x51): /* sqrt{p,s}{s,d} xmm/mem,xmm */ > + CASE_SIMD_ALL_FP(_VEX, 0x0f, 0x51): /* vsqrtp{s,d} > {x,y}mm/mem,{x,y}mm */ > + /* vsqrts{s,d} xmm/m32,xmm,xmm */ > + CASE_SIMD_SINGLE_FP(, 0x0f, 0x52): /* rsqrt{p,s}s xmm/mem,xmm */ > + CASE_SIMD_SINGLE_FP(_VEX, 0x0f, 0x52): /* vrsqrtps {x,y}mm/mem,{x,y}mm */ > + /* vrsqrtss xmm/m32,xmm,xmm */ > + CASE_SIMD_SINGLE_FP(, 0x0f, 0x53): /* rcp{p,s}s xmm/mem,xmm */ > + CASE_SIMD_SINGLE_FP(_VEX, 0x0f, 0x53): /* vrcpps {x,y}mm/mem,{x,y}mm */ > + /* vrcpss xmm/m32,xmm,xmm */ > + CASE_SIMD_PACKED_FP(, 0x0f, 0x54): /* andp{s,d} xmm/m128,xmm */ > + CASE_SIMD_PACKED_FP(_VEX, 0x0f, 0x54): /* vandp{s,d} > {x,y}mm/mem,{x,y}mm,{x,y}mm */ > + CASE_SIMD_PACKED_FP(, 0x0f, 0x55): /* andnp{s,d} xmm/m128,xmm */ > + CASE_SIMD_PACKED_FP(_VEX, 0x0f, 0x55): /* vandnp{s,d} > {x,y}mm/mem,{x,y}mm,{x,y}mm */ > + CASE_SIMD_PACKED_FP(, 0x0f, 0x56): /* orp{s,d} xmm/m128,xmm */ > + CASE_SIMD_PACKED_FP(_VEX, 0x0f, 0x56): /* vorp{s,d} > {x,y}mm/mem,{x,y}mm,{x,y}mm */ > + CASE_SIMD_PACKED_FP(, 0x0f, 0x57): /* xorp{s,d} xmm/m128,xmm */ > + CASE_SIMD_PACKED_FP(_VEX, 0x0f, 0x57): /* vxorp{s,d} > {x,y}mm/mem,{x,y}mm,{x,y}mm */ > + CASE_SIMD_ALL_FP(, 0x0f, 0x58): /* add{p,s}{s,d} xmm/mem,xmm */ > + CASE_SIMD_ALL_FP(_VEX, 0x0f, 0x58): /* vadd{p,s}{s,d} > {x,y}mm/mem,{x,y}mm,{x,y}mm */ > + CASE_SIMD_ALL_FP(, 0x0f, 0x59): /* mul{p,s}{s,d} xmm/mem,xmm */ > + CASE_SIMD_ALL_FP(_VEX, 0x0f, 0x59): /* vmul{p,s}{s,d} > {x,y}mm/mem,{x,y}mm,{x,y}mm */ > + CASE_SIMD_ALL_FP(, 0x0f, 0x5c): /* sub{p,s}{s,d} xmm/mem,xmm */ > + CASE_SIMD_ALL_FP(_VEX, 0x0f, 0x5c): /* vsub{p,s}{s,d} > {x,y}mm/mem,{x,y}mm,{x,y}mm */ > + CASE_SIMD_ALL_FP(, 0x0f, 0x5d): /* min{p,s}{s,d} xmm/mem,xmm */ > + CASE_SIMD_ALL_FP(_VEX, 0x0f, 0x5d): /* vmin{p,s}{s,d} > {x,y}mm/mem,{x,y}mm,{x,y}mm */ > + CASE_SIMD_ALL_FP(, 0x0f, 0x5e): /* div{p,s}{s,d} xmm/mem,xmm */ > + CASE_SIMD_ALL_FP(_VEX, 0x0f, 0x5e): /* vdiv{p,s}{s,d} > {x,y}mm/mem,{x,y}mm,{x,y}mm */ > + CASE_SIMD_ALL_FP(, 0x0f, 0x5f): /* max{p,s}{s,d} xmm/mem,xmm */ > + CASE_SIMD_ALL_FP(_VEX, 0x0f, 0x5f): /* vmax{p,s}{s,d} > {x,y}mm/mem,{x,y}mm,{x,y}mm */ > if ( vex.opcx == vex_none ) > { > if ( vex.pfx & VEX_PREFIX_DOUBLE_MASK ) > + { > + simd_0f_sse2: > vcpu_must_have(sse2); > + } > else > vcpu_must_have(sse); > - ea.bytes = 16; > - SET_SSE_PREFIX(buf[0], vex.pfx); > + simd_0f_xmm: > get_fpu(X86EMUL_FPU_xmm, &fic); > } > else > { > - fail_if((vex.reg != 0xf) && > - ((ea.type == OP_MEM) || > - !(vex.pfx & VEX_PREFIX_SCALAR_MASK))); > + /* vmovs{s,d} to/from memory have only two operands. */ > + if ( (b & ~1) == 0x10 && ea.type == OP_MEM ) > + d |= TwoOp; > + simd_0f_avx: > host_and_vcpu_must_have(avx); > + simd_0f_ymm: > get_fpu(X86EMUL_FPU_ymm, &fic); > - ea.bytes = 16 << vex.l; > } > - if ( vex.pfx & VEX_PREFIX_SCALAR_MASK ) > - ea.bytes = vex.pfx & VEX_PREFIX_DOUBLE_MASK ? 8 : 4; > + simd_0f_common: > + { > + uint8_t *buf = get_stub(stub); > + > + buf[0] = 0x3e; > + buf[1] = 0x3e; > + buf[2] = 0x0f; > + buf[3] = b; > + buf[4] = modrm; > if ( ea.type == OP_MEM ) > { > - uint32_t mxcsr = 0; > - > - if ( b < 0x28 ) > - mxcsr = MXCSR_MM; > - else if ( vcpu_has_misalignsse() ) > - asm ( "stmxcsr %0" : "=m" (mxcsr) ); > - generate_exception_if(!(mxcsr & MXCSR_MM) && > - !is_aligned(ea.mem.seg, ea.mem.off, > ea.bytes, > - ctxt, ops), > - EXC_GP, 0); > - if ( !(b & 1) ) > - rc = ops->read(ea.mem.seg, ea.mem.off+0, mmvalp, > - ea.bytes, ctxt); > - else > - fail_if(!ops->write); /* Check before running the stub. */ > /* convert memory operand to (%rAX) */ > rex_prefix &= ~REX_B; > vex.b = 1; > buf[4] &= 0x38; > } > - if ( !rc ) > - { > - copy_REX_VEX(buf, rex_prefix, vex); > - asm volatile ( "call *%0" : : "r" (stub.func), "a" (mmvalp) > - : "memory" ); > - } > - put_fpu(&fic); > - put_stub(stub); > - if ( !rc && (b & 1) && (ea.type == OP_MEM) ) > - { > - ASSERT(ops->write); /* See the fail_if() above. */ > - rc = ops->write(ea.mem.seg, ea.mem.off, mmvalp, > - ea.bytes, ctxt); > - } > - if ( rc ) > - goto done; > - dst.type = OP_NONE; > + fic.insn_bytes = 5; > break; > } > > @@ -6457,22 +6917,6 @@ x86_insn_is_mem_write(const struct x86_e > case 0x6c: case 0x6d: /* INS */ > case 0xa4: case 0xa5: /* MOVS */ > case 0xaa: case 0xab: /* STOS */ > - case X86EMUL_OPC(0x0f, 0x11): /* MOVUPS */ > - case X86EMUL_OPC_VEX(0x0f, 0x11): /* VMOVUPS */ > - case X86EMUL_OPC_66(0x0f, 0x11): /* MOVUPD */ > - case X86EMUL_OPC_VEX_66(0x0f, 0x11): /* VMOVUPD */ > - case X86EMUL_OPC_F3(0x0f, 0x11): /* MOVSS */ > - case X86EMUL_OPC_VEX_F3(0x0f, 0x11): /* VMOVSS */ > - case X86EMUL_OPC_F2(0x0f, 0x11): /* MOVSD */ > - case X86EMUL_OPC_VEX_F2(0x0f, 0x11): /* VMOVSD */ > - case X86EMUL_OPC(0x0f, 0x29): /* MOVAPS */ > - case X86EMUL_OPC_VEX(0x0f, 0x29): /* VMOVAPS */ > - case X86EMUL_OPC_66(0x0f, 0x29): /* MOVAPD */ > - case X86EMUL_OPC_VEX_66(0x0f, 0x29): /* VMOVAPD */ > - case X86EMUL_OPC(0x0f, 0x2b): /* MOVNTPS */ > - case X86EMUL_OPC_VEX(0x0f, 0x2b): /* VMOVNTPS */ > - case X86EMUL_OPC_66(0x0f, 0x2b): /* MOVNTPD */ > - case X86EMUL_OPC_VEX_66(0x0f, 0x2b): /* VMOVNTPD */ Where have these gone? ~Andrew > case X86EMUL_OPC(0x0f, 0x7e): /* MOVD/MOVQ */ > case X86EMUL_OPC_66(0x0f, 0x7e): /* MOVD/MOVQ */ > case X86EMUL_OPC_VEX_66(0x0f, 0x7e): /* VMOVD/VMOVQ */ _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |