diff --git a/Source/Core/Common/x64Emitter.cpp b/Source/Core/Common/x64Emitter.cpp index 14458ae7d44..31f33edc282 100644 --- a/Source/Core/Common/x64Emitter.cpp +++ b/Source/Core/Common/x64Emitter.cpp @@ -250,7 +250,7 @@ void OpArg::WriteVEX(XEmitter* emit, X64Reg regOp1, X64Reg regOp2, int L, int pp int X = !(indexReg & 8); int B = !(offsetOrBaseReg & 8); - int vvvv = (regOp2 == X64Reg::INVALID_REG) ? 0xf : (regOp2 ^ 0xf); + u8 vvvv = (regOp2 == X64Reg::INVALID_REG) ? 0xf : (regOp2 ^ 0xf); // do we need any VEX fields that only appear in the three-byte form? if (X == 1 && B == 1 && W == 0 && mmmmm == 1) @@ -343,7 +343,7 @@ void OpArg::WriteRest(XEmitter* emit, int extraBytes, X64Reg _operandReg, if (SIB) oreg = 4; - emit->WriteModRM(mod, _operandReg & 7, oreg & 7); + emit->WriteModRM(mod, _operandReg, oreg); if (SIB) { @@ -1844,8 +1844,9 @@ void XEmitter::WriteVEXOp(u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, con { int mmmmm = GetVEXmmmmm(op); int pp = GetVEXpp(opPrefix); - // FIXME: we currently don't support 256-bit instructions, and "size" is not the vector size here - arg.WriteVEX(this, regOp1, regOp2, 0, pp, mmmmm, W); + // Note that mixing an XMM register with a YMM register is invalid, which isn't checked here. + int L = (regOp1 != INVALID_REG && regOp1 & 0x100) || (regOp2 != INVALID_REG && regOp2 & 0x100); + arg.WriteVEX(this, regOp1, regOp2, L, pp, mmmmm, W); Write8(op & 0xFF); arg.WriteRest(this, extrabytes, regOp1); } diff --git a/Source/Core/Common/x64Reg.h b/Source/Core/Common/x64Reg.h index a868e3047a5..c3597384296 100644 --- a/Source/Core/Common/x64Reg.h +++ b/Source/Core/Common/x64Reg.h @@ -72,7 +72,8 @@ enum X64Reg XMM14, XMM15, - YMM0 = 0, + // Use the bit 0x100 to distinguish XMM and YMM registers. + YMM0 = 0x100, YMM1, YMM2, YMM3,