diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index a39aff41d..4ccabcce5 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -318,6 +318,7 @@ public: void MOVLPOp(OpcodeArgs); void MOVHPDOp(OpcodeArgs); void MOVSDOp(OpcodeArgs); + void MOVSSOp(OpcodeArgs); template void VectorALUOp(OpcodeArgs); template @@ -376,7 +377,6 @@ public: void MOVBetweenGPR_FPR(OpcodeArgs); void TZCNT(OpcodeArgs); void LZCNT(OpcodeArgs); - void MOVSSOp(OpcodeArgs); template void VFCMPOp(OpcodeArgs); template @@ -973,6 +973,7 @@ private: const X86Tables::DecodedOperand& MaskOp, const X86Tables::DecodedOperand& DataOp); + void MOVScalarOpImpl(OpcodeArgs, size_t ElementSize); void VMOVScalarOpImpl(OpcodeArgs, size_t ElementSize); OrderedNode* VFCMPOpImpl(OpcodeArgs, size_t ElementSize, bool Scalar, diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 83462a821..063ee769f 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -165,46 +165,33 @@ void OpDispatchBuilder::VMOVSLDUPOp(OpcodeArgs) { StoreResult(FPRClass, Op, Result, -1); } -void OpDispatchBuilder::MOVSSOp(OpcodeArgs) { +void OpDispatchBuilder::MOVScalarOpImpl(OpcodeArgs, size_t ElementSize) { if (Op->Dest.IsGPR() && Op->Src[0].IsGPR()) { - // MOVSS xmm1, xmm2 + // MOVSS/SD xmm1, xmm2 OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); - auto Result = _VInsElement(16, 4, 0, 0, Dest, Src); + auto Result = _VInsElement(16, ElementSize, 0, 0, Dest, Src); StoreResult(FPRClass, Op, Result, -1); } else if (Op->Dest.IsGPR()) { - // MOVSS xmm1, mem32 - // xmm1[127:0] <- zext(mem32) - OrderedNode *Src = LoadSource_WithOpSize(FPRClass, Op, Op->Src[0], 4, Op->Flags, -1); + // MOVSS/SD xmm1, mem32/mem64 + // xmm1[127:0] <- zext(mem32/mem64) + OrderedNode *Src = LoadSource_WithOpSize(FPRClass, Op, Op->Src[0], ElementSize, Op->Flags, -1); StoreResult(FPRClass, Op, Src, -1); } else { - // MOVSS mem32, xmm1 + // MOVSS/SD mem32/mem64, xmm1 OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); - StoreResult_WithOpSize(FPRClass, Op, Op->Dest, Src, 4, -1); + StoreResult_WithOpSize(FPRClass, Op, Op->Dest, Src, ElementSize, -1); } } +void OpDispatchBuilder::MOVSSOp(OpcodeArgs) { + MOVScalarOpImpl(Op, 4); +} + void OpDispatchBuilder::MOVSDOp(OpcodeArgs) { - if (Op->Dest.IsGPR() && Op->Src[0].IsGPR()) { - // xmm1[63:0] <- xmm2[63:0] - OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); - OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); - auto Result = _VInsElement(16, 8, 0, 0, Dest, Src); - StoreResult(FPRClass, Op, Result, -1); - } - else if (Op->Dest.IsGPR()) { - // xmm1[127:0] <- zext(mem64) - OrderedNode *Src = LoadSource_WithOpSize(FPRClass, Op, Op->Src[0], 8, Op->Flags, -1); - StoreResult(FPRClass, Op, Src, -1); - } - else { - // In this case memory is the destination and the low bits of the XMM are source - // Mem64 = xmm2[63:0] - OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); - StoreResult_WithOpSize(FPRClass, Op, Op->Dest, Src, 8, -1); - } + MOVScalarOpImpl(Op, 8); } void OpDispatchBuilder::VMOVScalarOpImpl(OpcodeArgs, size_t ElementSize) {