Merge pull request #5923 from Sonicadvance1/231

OpcodeDispatcher: Explicitly handle no-nop vector moves
This commit is contained in:
LC authored and GitHub committed 2026-09-04 17:54:36 -04:00
commit b78bde7ec8
3 files changed
+11 -7

No files matched your search

@@ -360,6 +360,7 @@ public:
void MOVGPRNTOp(OpcodeArgs);
void MOVVectorAlignedOp(OpcodeArgs);
void MOVVectorUnalignedOp(OpcodeArgs);
void MOVVectorUnalignedNoNopOp(OpcodeArgs);
void MOVVectorNTOp(OpcodeArgs, bool IsAVX);
void ALUOp(OpcodeArgs, FEXCore::IR::IROps ALUIROp, FEXCore::IR::IROps AtomicFetchOp, unsigned SrcIdx);
void LSLOp(OpcodeArgs);
@@ -26,8 +26,8 @@ constexpr DispatchTableEntry OpDispatch_DDDTable[] = {
{0xA0, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VPFCMPOp, 2>},
{0xA4, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VFMAX, OpSize::i32Bit>},
// Can be treated as a move
{0xA6, 1, &OpDispatchBuilder::MOVVectorUnalignedOp},
{0xA7, 1, &OpDispatchBuilder::MOVVectorUnalignedOp},
{0xA6, 1, &OpDispatchBuilder::MOVVectorUnalignedNoNopOp},
{0xA7, 1, &OpDispatchBuilder::MOVVectorUnalignedNoNopOp},
{0xAA, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUROp, IR::OP_VFSUB, OpSize::i32Bit>},
{0xAE, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VFADDP, OpSize::i32Bit>},
@@ -35,7 +35,7 @@ constexpr DispatchTableEntry OpDispatch_DDDTable[] = {
{0xB0, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VPFCMPOp, 0>},
{0xB4, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VFMUL, OpSize::i32Bit>},
// Can be treated as a move
{0xB6, 1, &OpDispatchBuilder::MOVVectorUnalignedOp},
{0xB6, 1, &OpDispatchBuilder::MOVVectorUnalignedNoNopOp},
{0xB7, 1, &OpDispatchBuilder::PMULHRWOp},
{0xBB, 1, &OpDispatchBuilder::PSWAPDOp},
@@ -34,10 +34,7 @@ void OpDispatchBuilder::MOVVectorAlignedOp(OpcodeArgs) {
}
void OpDispatchBuilder::MOVVectorUnalignedOp(OpcodeArgs) {
const bool DestIsMMX =
Op->Dest.IsGPR() && Op->Dest.Data.GPR.GPR >= FEXCore::X86State::REG_MM_0 && Op->Dest.Data.GPR.GPR <= FEXCore::X86State::REG_MM_7;
if (!DestIsMMX && Op->Dest.IsGPR() && Op->Src[0].IsGPR() && Op->Dest.Data.GPR.GPR == Op->Src[0].Data.GPR.GPR) {
if (Op->Dest.IsGPR() && Op->Src[0].IsGPR() && Op->Dest.Data.GPR.GPR == Op->Src[0].Data.GPR.GPR) {
// Nop
return;
}
@@ -45,6 +42,12 @@ void OpDispatchBuilder::MOVVectorUnalignedOp(OpcodeArgs) {
StoreResult_WithAVXInsert(VectorOpType::SSE, RegClass::FPR, Op, Src);
}
void OpDispatchBuilder::MOVVectorUnalignedNoNopOp(OpcodeArgs) {
// Moves to same register might have secondary-effects and can't convert to a nop.
Ref Src = LoadSourceFPR(Op, Op->Src[0], Op->Flags, {.Align = OpSize::i8Bit});
StoreResult_WithAVXInsert(VectorOpType::SSE, RegClass::FPR, Op, Src);
}
void OpDispatchBuilder::MOVVectorNTOp(OpcodeArgs, bool IsAVX) {
const auto Size = OpSizeFromDst(Op);