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.
This commit is contained in:
Lioncache committed 2023-08-19 17:44:45 -04:00
1 parent 1fe8470933
commit c31329609f
2 files changed
+15 -27

No files matched your search

@@ -318,6 +318,7 @@ public:
void MOVLPOp(OpcodeArgs);
void MOVHPDOp(OpcodeArgs);
void MOVSDOp(OpcodeArgs);
void MOVSSOp(OpcodeArgs);
template<FEXCore::IR::IROps IROp, size_t ElementSize>
void VectorALUOp(OpcodeArgs);
template<FEXCore::IR::IROps IROp, size_t ElementSize>
@@ -376,7 +377,6 @@ public:
void MOVBetweenGPR_FPR(OpcodeArgs);
void TZCNT(OpcodeArgs);
void LZCNT(OpcodeArgs);
void MOVSSOp(OpcodeArgs);
template<size_t ElementSize, bool Scalar>
void VFCMPOp(OpcodeArgs);
template<size_t ElementSize>
@@ -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,
@@ -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) {