From c31329609f6083abc2ee44833b60974bca390bfd Mon Sep 17 00:00:00 2001 From: Lioncache Date: Sat, 19 Aug 2023 17:44:43 -0400 Subject: [PATCH] OpcodeDispatcher: Unify handling code for MOVSD and MOVSS These have the same behavior and only differ based on element size, so we can join the implementations together instead of duplicating them across both functions. --- .../Source/Interface/Core/OpcodeDispatcher.h | 3 +- .../Core/OpcodeDispatcher/Vector.cpp | 39 +++++++------------ 2 files changed, 15 insertions(+), 27 deletions(-) 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) {