diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 6baa36d9a..2a708781f 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -6089,7 +6089,7 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() { {OPD(1, 0b01, 0xEE), 1, &OpDispatchBuilder::AVXVectorALUOp}, {OPD(1, 0b01, 0xEF), 1, &OpDispatchBuilder::AVXVectorALUOp}, - {OPD(1, 0b11, 0xF0), 1, &OpDispatchBuilder::MOVUPS_MOVUPDOp}, + {OPD(1, 0b11, 0xF0), 1, &OpDispatchBuilder::MOVVectorUnalignedOp}, {OPD(1, 0b01, 0xF1), 1, &OpDispatchBuilder::VPSLLOp<2>}, {OPD(1, 0b01, 0xF2), 1, &OpDispatchBuilder::VPSLLOp<4>}, {OPD(1, 0b01, 0xF3), 1, &OpDispatchBuilder::VPSLLOp<8>}, @@ -6410,9 +6410,9 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0x3F, 1, &OpDispatchBuilder::ThunkOp}, {0x40, 16, &OpDispatchBuilder::CMOVOp}, {0x6E, 1, &OpDispatchBuilder::MOVBetweenGPR_FPR}, - {0x6F, 1, &OpDispatchBuilder::MOVUPS_MOVUPDOp}, + {0x6F, 1, &OpDispatchBuilder::MOVQMMXOp}, {0x7E, 1, &OpDispatchBuilder::MOVBetweenGPR_FPR}, - {0x7F, 1, &OpDispatchBuilder::MOVUPS_MOVUPDOp}, + {0x7F, 1, &OpDispatchBuilder::MOVQMMXOp}, {0x80, 16, &OpDispatchBuilder::CondJUMPOp}, {0x90, 16, &OpDispatchBuilder::SETccOp}, {0xA0, 1, &OpDispatchBuilder::PUSHSegmentOp}, @@ -6441,12 +6441,12 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0xC8, 8, &OpDispatchBuilder::BSWAPOp}, // SSE - {0x10, 2, &OpDispatchBuilder::MOVUPS_MOVUPDOp}, + {0x10, 2, &OpDispatchBuilder::MOVVectorUnalignedOp}, {0x12, 2, &OpDispatchBuilder::MOVLPOp}, {0x14, 1, &OpDispatchBuilder::PUNPCKLOp<4>}, {0x15, 1, &OpDispatchBuilder::PUNPCKHOp<4>}, {0x16, 2, &OpDispatchBuilder::MOVHPDOp}, - {0x28, 2, &OpDispatchBuilder::MOVAPS_MOVAPDOp}, + {0x28, 2, &OpDispatchBuilder::MOVVectorAlignedOp}, {0x2A, 1, &OpDispatchBuilder::InsertMMX_To_XMM_Vector_CVT_Int_To_Float}, {0x2B, 1, &OpDispatchBuilder::MOVVectorNTOp}, {0x2C, 1, &OpDispatchBuilder::XMM_To_MMX_Vector_CVT_Float_To_Int<4, false, false>}, @@ -6689,10 +6689,10 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0x5D, 1, &OpDispatchBuilder::VectorScalarInsertALUOp}, {0x5E, 1, &OpDispatchBuilder::VectorScalarInsertALUOp}, {0x5F, 1, &OpDispatchBuilder::VectorScalarInsertALUOp}, - {0x6F, 1, &OpDispatchBuilder::MOVUPS_MOVUPDOp}, + {0x6F, 1, &OpDispatchBuilder::MOVVectorUnalignedOp}, {0x70, 1, &OpDispatchBuilder::PSHUFWOp}, {0x7E, 1, &OpDispatchBuilder::MOVQOp}, - {0x7F, 1, &OpDispatchBuilder::MOVUPS_MOVUPDOp}, + {0x7F, 1, &OpDispatchBuilder::MOVVectorUnalignedOp}, {0xB8, 1, &OpDispatchBuilder::PopcountOp}, {0xBC, 1, &OpDispatchBuilder::TZCNT}, {0xBD, 1, &OpDispatchBuilder::LZCNT}, @@ -6706,7 +6706,7 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0x12, 1, &OpDispatchBuilder::MOVDDUPOp}, {0x19, 7, &OpDispatchBuilder::NOPOp}, {0x2A, 1, &OpDispatchBuilder::InsertCVTGPR_To_FPR<8>}, - {0x2B, 1, &OpDispatchBuilder::MOVVectorOp}, + {0x2B, 1, &OpDispatchBuilder::MOVVectorUnalignedOp}, {0x2C, 1, &OpDispatchBuilder::CVTFPR_To_GPR<8, false>}, {0x2D, 1, &OpDispatchBuilder::CVTFPR_To_GPR<8, true>}, {0x51, 1, &OpDispatchBuilder::VectorScalarUnaryInsertALUOp}, @@ -6725,17 +6725,17 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0xD6, 1, &OpDispatchBuilder::MOVQ2DQ}, {0xC2, 1, &OpDispatchBuilder::InsertScalarFCMPOp<8>}, {0xE6, 1, &OpDispatchBuilder::Vector_CVT_Float_To_Int<8, true, true>}, - {0xF0, 1, &OpDispatchBuilder::MOVVectorOp}, + {0xF0, 1, &OpDispatchBuilder::MOVVectorUnalignedOp}, }; constexpr std::tuple OpSizeModOpTable[] = { - {0x10, 2, &OpDispatchBuilder::MOVVectorOp}, + {0x10, 2, &OpDispatchBuilder::MOVVectorUnalignedOp}, {0x12, 2, &OpDispatchBuilder::MOVLPOp}, {0x14, 1, &OpDispatchBuilder::PUNPCKLOp<8>}, {0x15, 1, &OpDispatchBuilder::PUNPCKHOp<8>}, {0x16, 2, &OpDispatchBuilder::MOVHPDOp}, {0x19, 7, &OpDispatchBuilder::NOPOp}, - {0x28, 2, &OpDispatchBuilder::MOVAPS_MOVAPDOp}, + {0x28, 2, &OpDispatchBuilder::MOVVectorAlignedOp}, {0x2A, 1, &OpDispatchBuilder::MMX_To_XMM_Vector_CVT_Int_To_Float}, {0x2B, 1, &OpDispatchBuilder::MOVVectorNTOp}, {0x2C, 1, &OpDispatchBuilder::XMM_To_MMX_Vector_CVT_Float_To_Int<8, true, false>}, @@ -6772,7 +6772,7 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0x6C, 1, &OpDispatchBuilder::PUNPCKLOp<8>}, {0x6D, 1, &OpDispatchBuilder::PUNPCKHOp<8>}, {0x6E, 1, &OpDispatchBuilder::MOVBetweenGPR_FPR}, - {0x6F, 1, &OpDispatchBuilder::MOVUPS_MOVUPDOp}, + {0x6F, 1, &OpDispatchBuilder::MOVVectorAlignedOp}, {0x70, 1, &OpDispatchBuilder::PSHUFDOp}, {0x74, 1, &OpDispatchBuilder::VectorALUOp}, @@ -6782,7 +6782,7 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0x7C, 1, &OpDispatchBuilder::VectorALUOp}, {0x7D, 1, &OpDispatchBuilder::HSUBP<8>}, {0x7E, 1, &OpDispatchBuilder::MOVBetweenGPR_FPR}, - {0x7F, 1, &OpDispatchBuilder::MOVUPS_MOVUPDOp}, + {0x7F, 1, &OpDispatchBuilder::MOVVectorAlignedOp}, {0xC2, 1, &OpDispatchBuilder::VFCMPOp<8>}, {0xC4, 1, &OpDispatchBuilder::PINSROp<2>}, {0xC5, 1, &OpDispatchBuilder::PExtrOp<2>}, @@ -7558,8 +7558,8 @@ constexpr uint16_t PF_F2 = 3; {0xA0, 1, &OpDispatchBuilder::VPFCMPOp<2>}, {0xA4, 1, &OpDispatchBuilder::VectorALUOp}, // Can be treated as a move - {0xA6, 1, &OpDispatchBuilder::MOVVectorOp}, - {0xA7, 1, &OpDispatchBuilder::MOVVectorOp}, + {0xA6, 1, &OpDispatchBuilder::MOVVectorUnalignedOp}, + {0xA7, 1, &OpDispatchBuilder::MOVVectorUnalignedOp}, {0xAA, 1, &OpDispatchBuilder::VectorALUROp}, {0xAE, 1, &OpDispatchBuilder::VectorALUOp}, @@ -7567,7 +7567,7 @@ constexpr uint16_t PF_F2 = 3; {0xB0, 1, &OpDispatchBuilder::VPFCMPOp<0>}, {0xB4, 1, &OpDispatchBuilder::VectorALUOp}, // Can be treated as a move - {0xB6, 1, &OpDispatchBuilder::MOVVectorOp}, + {0xB6, 1, &OpDispatchBuilder::MOVVectorUnalignedOp}, {0xB7, 1, &OpDispatchBuilder::PMULHRWOp}, {0xBB, 1, &OpDispatchBuilder::PSWAPDOp}, diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index bf69030e1..6b6c1e4e5 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -222,7 +222,8 @@ public: template void MOVGPROp(OpcodeArgs); void MOVGPRNTOp(OpcodeArgs); - void MOVVectorOp(OpcodeArgs); + void MOVVectorAlignedOp(OpcodeArgs); + void MOVVectorUnalignedOp(OpcodeArgs); void MOVVectorNTOp(OpcodeArgs); template void ALUOp(OpcodeArgs); @@ -359,8 +360,6 @@ public: void SGDTOp(OpcodeArgs); // SSE - void MOVAPS_MOVAPDOp(OpcodeArgs); - void MOVUPS_MOVUPDOp(OpcodeArgs); void MOVLPOp(OpcodeArgs); void MOVHPDOp(OpcodeArgs); void MOVSDOp(OpcodeArgs); @@ -375,6 +374,7 @@ public: void VectorUnaryDuplicateOp(OpcodeArgs); void MOVQOp(OpcodeArgs); + void MOVQMMXOp(OpcodeArgs); template void MOVMSKOp(OpcodeArgs); void MOVMSKOpOne(OpcodeArgs); diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index ba4a305da..c24ebaf0e 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -24,7 +24,17 @@ $end_info$ namespace FEXCore::IR { #define OpcodeArgs [[maybe_unused]] FEXCore::X86Tables::DecodedOp Op -void OpDispatchBuilder::MOVVectorOp(OpcodeArgs) { +void OpDispatchBuilder::MOVVectorAlignedOp(OpcodeArgs) { + if (Op->Dest.IsGPR() && Op->Src[0].IsGPR() && + Op->Dest.Data.GPR.GPR == Op->Src[0].Data.GPR.GPR) { + // Nop + return; + } + OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags); + StoreResult(FPRClass, Op, Src, -1); +} + +void OpDispatchBuilder::MOVVectorUnalignedOp(OpcodeArgs) { if (Op->Dest.IsGPR() && Op->Src[0].IsGPR() && Op->Dest.Data.GPR.GPR == Op->Src[0].Data.GPR.GPR) { // Nop @@ -40,11 +50,6 @@ void OpDispatchBuilder::MOVVectorNTOp(OpcodeArgs) { StoreResult(FPRClass, Op, Src, 1, MemoryAccessType::STREAM); } -void OpDispatchBuilder::MOVAPS_MOVAPDOp(OpcodeArgs) { - OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags); - StoreResult(FPRClass, Op, Src, -1); -} - void OpDispatchBuilder::VMOVAPS_VMOVAPDOp(OpcodeArgs) { const auto SrcSize = GetSrcSize(Op); const auto Is128Bit = SrcSize == Core::CPUState::XMM_SSE_REG_SIZE; @@ -57,11 +62,6 @@ void OpDispatchBuilder::VMOVAPS_VMOVAPDOp(OpcodeArgs) { StoreResult(FPRClass, Op, Src, -1); } -void OpDispatchBuilder::MOVUPS_MOVUPDOp(OpcodeArgs) { - OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, {.Align = 1}); - StoreResult(FPRClass, Op, Src, 1); -} - void OpDispatchBuilder::VMOVUPS_VMOVUPDOp(OpcodeArgs) { const auto SrcSize = GetSrcSize(Op); const auto Is128Bit = SrcSize == Core::CPUState::XMM_SSE_REG_SIZE; @@ -1053,6 +1053,11 @@ void OpDispatchBuilder::MOVQOp(OpcodeArgs) { } } +void OpDispatchBuilder::MOVQMMXOp(OpcodeArgs) { + OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, {.Align = 1}); + StoreResult(FPRClass, Op, Src, 1); +} + template void OpDispatchBuilder::MOVMSKOp(OpcodeArgs) { auto Size = GetSrcSize(Op); diff --git a/unittests/InstructionCountCI/Secondary.json b/unittests/InstructionCountCI/Secondary.json index 9c250e75e..da8e2dc9c 100644 --- a/unittests/InstructionCountCI/Secondary.json +++ b/unittests/InstructionCountCI/Secondary.json @@ -25,6 +25,20 @@ "strb w20, [x28, #1010]" ] }, + "movups xmm0, xmm0": { + "ExpectedInstructionCount": 0, + "Optimal": "Yes", + "Comment": "0x0f 0x10", + "ExpectedArm64ASM": [] + }, + "movups xmm0, xmm1": { + "ExpectedInstructionCount": 1, + "Optimal": "Yes", + "Comment": "0x0f 0x10", + "ExpectedArm64ASM": [ + "mov v16.16b, v17.16b" + ] + }, "movups xmm0, [rax]": { "ExpectedInstructionCount": 1, "Optimal": "Yes", @@ -111,6 +125,20 @@ "Comment": "0x0f 0x19", "ExpectedArm64ASM": [] }, + "movaps xmm0, xmm0": { + "ExpectedInstructionCount": 0, + "Optimal": "Yes", + "Comment": "0x0f 0x28", + "ExpectedArm64ASM": [] + }, + "movaps xmm0, xmm1": { + "ExpectedInstructionCount": 1, + "Optimal": "Yes", + "Comment": "0x0f 0x28", + "ExpectedArm64ASM": [ + "mov v16.16b, v17.16b" + ] + }, "movaps xmm0, [rax]": { "ExpectedInstructionCount": 1, "Optimal": "Yes", diff --git a/unittests/InstructionCountCI/Secondary_OpSize.json b/unittests/InstructionCountCI/Secondary_OpSize.json index bf53ba026..9f196fc7f 100644 --- a/unittests/InstructionCountCI/Secondary_OpSize.json +++ b/unittests/InstructionCountCI/Secondary_OpSize.json @@ -87,6 +87,12 @@ "st1 {v16.d}[1], [x4]" ] }, + "movapd xmm0, xmm0": { + "ExpectedInstructionCount": 0, + "Optimal": "Yes", + "Comment": "0x66 0x0f 0x28", + "ExpectedArm64ASM": [] + }, "movapd xmm0, xmm1": { "ExpectedInstructionCount": 1, "Optimal": "Yes", @@ -522,6 +528,12 @@ "fmov d16, x4" ] }, + "movdqa xmm0, xmm0": { + "ExpectedInstructionCount": 0, + "Optimal": "Yes", + "Comment": "0x66 0x0f 0x6f", + "ExpectedArm64ASM": [] + }, "movdqa xmm0, xmm1": { "ExpectedInstructionCount": 1, "Optimal": "Yes", diff --git a/unittests/InstructionCountCI/Secondary_REP.json b/unittests/InstructionCountCI/Secondary_REP.json index 2a395f009..4a96db52f 100644 --- a/unittests/InstructionCountCI/Secondary_REP.json +++ b/unittests/InstructionCountCI/Secondary_REP.json @@ -321,6 +321,12 @@ "mov v16.s[0], v0.s[0]" ] }, + "movdqu xmm0, xmm0": { + "ExpectedInstructionCount": 0, + "Optimal": "Yes", + "Comment": "0xf3 0x0f 0x6f", + "ExpectedArm64ASM": [] + }, "movdqu xmm0, xmm1": { "ExpectedInstructionCount": 1, "Optimal": "Yes", @@ -398,6 +404,14 @@ "trn1 v16.2d, v17.2d, v2.2d" ] }, + "movq xmm0, xmm0": { + "ExpectedInstructionCount": 1, + "Optimal": "Yes", + "Comment": "0xf3 0x0f 0x7e", + "ExpectedArm64ASM": [ + "mov v16.8b, v16.8b" + ] + }, "movq xmm0, xmm1": { "ExpectedInstructionCount": 1, "Optimal": "Yes",