mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-27 20:01:04 +01:00
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:
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) {
|
||||
|
||||
Reference in new issue
Block a user