From 35798c8d9da9ebddc279745813d725991bc91273 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 23 Sep 2020 16:50:06 -0700 Subject: [PATCH 1/2] Implements missing mmx conversion ops --- .../Core/Interpreter/InterpreterCore.cpp | 2 +- .../Interface/Core/OpcodeDispatcher.cpp | 52 ++++++++++++++++--- .../Source/Interface/Core/OpcodeDispatcher.h | 2 + .../Core/X86Tables/SecondaryTables.cpp | 6 +-- 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp index fc7e67cd5..05b1b6159 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp @@ -3792,7 +3792,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) { break; } case 0x0408: { // Float <- Double - uint8_t Elements = OpSize / Op->SrcElementSize; + uint8_t Elements = (OpSize << 1) / Op->SrcElementSize; switch (Op->SrcElementSize) { DO_VECTOR_1SRC_2TYPE_OP(8, float, double, Func, 0, 0) } diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 3bbd71d4e..020cc148c 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -5903,24 +5903,59 @@ void OpDispatchBuilder::MMX_To_XMM_Vector_CVT_Int_To_Float(OpcodeArgs) { OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); size_t ElementSize = SrcElementSize; - size_t Size = GetSrcSize(Op); + size_t DstSize = GetDstSize(Op); if (Widen) { - Src = _VSXTL(Src, Size, ElementSize); + Src = _VSXTL(Src, DstSize, ElementSize); ElementSize <<= 1; } if (Signed) - Src = _Vector_SToF(Src, Size, ElementSize); + Src = _Vector_SToF(Src, DstSize, ElementSize); else - Src = _Vector_UToF(Src, Size, ElementSize); + Src = _Vector_UToF(Src, DstSize, ElementSize); - OrderedNode *Dest = LoadSource_WithOpSize(FPRClass, Op, Op->Dest, GetDstSize(Op), Op->Flags, -1); - // Insert the lower bits - Dest = _VInsElement(GetDstSize(Op), 8, 0, 0, Dest, Src); + OrderedNode *Dest{}; + + if (Widen) { + Dest = Src; + } + else { + Dest = LoadSource_WithOpSize(FPRClass, Op, Op->Dest, DstSize, Op->Flags, -1); + // Insert the lower bits + Dest = _VInsElement(GetDstSize(Op), 8, 0, 0, Dest, Src); + } StoreResult(FPRClass, Op, Dest, -1); } +template +void OpDispatchBuilder::XMM_To_MMX_Vector_CVT_Float_To_Int(OpcodeArgs) { + OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); + + size_t ElementSize = SrcElementSize; + size_t Size = GetDstSize(Op); + + if (Narrow) { + Src = _Vector_FToF(Size, SrcElementSize >> 1, SrcElementSize, Src); + ElementSize >>= 1; + } + + if (HostRoundingMode) { + if (Signed) + Src = _Vector_FToS(Src, Size, ElementSize); + else + Src = _Vector_FToU(Src, Size, ElementSize); + } + else { + if (Signed) + Src = _Vector_FToZS(Src, Size, ElementSize); + else + Src = _Vector_FToZU(Src, Size, ElementSize); + } + + StoreResult_WithOpSize(FPRClass, Op, Op->Dest, Src, Size, -1); +} + void OpDispatchBuilder::MASKMOVOp(OpcodeArgs) { // Until we get correct PHI nodes this is required to be a loop unroll uint8_t GPRSize = CTX->Config.Is64BitMode ? 8 : 4; @@ -8013,6 +8048,9 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) { {0x16, 2, &OpDispatchBuilder::MOVHPDOp}, {0x19, 7, &OpDispatchBuilder::NOPOp}, {0x28, 2, &OpDispatchBuilder::MOVAPSOp}, + {0x2A, 1, &OpDispatchBuilder::MMX_To_XMM_Vector_CVT_Int_To_Float<4, true, true>}, + {0x2C, 1, &OpDispatchBuilder::XMM_To_MMX_Vector_CVT_Float_To_Int<8, true, true, true>}, + {0x2D, 1, &OpDispatchBuilder::XMM_To_MMX_Vector_CVT_Float_To_Int<8, true, true, false>}, {0x2E, 2, &OpDispatchBuilder::UCOMISxOp<8>}, {0x40, 16, &OpDispatchBuilder::CMOVOp}, diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 6a798af39..ef2c17852 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -286,6 +286,8 @@ public: void Vector_CVT_Float_To_Int(OpcodeArgs); template void MMX_To_XMM_Vector_CVT_Int_To_Float(OpcodeArgs); + template + void XMM_To_MMX_Vector_CVT_Float_To_Int(OpcodeArgs); void MASKMOVOp(OpcodeArgs); void MOVBetweenGPR_FPR(OpcodeArgs); void TZCNT(OpcodeArgs); diff --git a/External/FEXCore/Source/Interface/Core/X86Tables/SecondaryTables.cpp b/External/FEXCore/Source/Interface/Core/X86Tables/SecondaryTables.cpp index 4a1cd8afa..1902ac254 100644 --- a/External/FEXCore/Source/Interface/Core/X86Tables/SecondaryTables.cpp +++ b/External/FEXCore/Source/Interface/Core/X86Tables/SecondaryTables.cpp @@ -431,10 +431,10 @@ void InitializeSecondaryTables() { {0x28, 1, X86InstInfo{"MOVAPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, {0x29, 1, X86InstInfo{"MOVAPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_DST | FLAGS_XMM_FLAGS, 0, nullptr}}, - {0x2A, 1, X86InstInfo{"CVTPI2PD", TYPE_MMX, FLAGS_NONE, 0, nullptr}}, + {0x2A, 1, X86InstInfo{"CVTPI2PD", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX_SRC, 0, nullptr}}, {0x2B, 1, X86InstInfo{"MOVNTPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_MEM_ONLY | FLAGS_SF_MOD_DST | FLAGS_XMM_FLAGS, 0, nullptr}}, - {0x2C, 1, X86InstInfo{"CVTTPD2PI", TYPE_MMX, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, - {0x2D, 1, X86InstInfo{"CVTPD2PI", TYPE_MMX, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, + {0x2C, 1, X86InstInfo{"CVTTPD2PI", TYPE_INST, GenFlagsSizes(SIZE_64BIT, SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX_DST, 0, nullptr}}, + {0x2D, 1, X86InstInfo{"CVTPD2PI", TYPE_INST, GenFlagsSizes(SIZE_64BIT, SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS | FLAGS_SF_MMX_DST, 0, nullptr}}, {0x2E, 1, X86InstInfo{"UCOMISD", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, {0x2F, 1, X86InstInfo{"COMISD", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_64BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, From b0065435e2293ada5e36c1b1256317f94335a7bc Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 23 Sep 2020 16:50:39 -0700 Subject: [PATCH 2/2] Missing MMX conversion ops unit tests --- unittests/ASM/OpSize/66_2A.asm | 24 +++++++++++++++++++ unittests/ASM/OpSize/66_2C.asm | 38 ++++++++++++++++++++++++++++++ unittests/ASM/OpSize/66_2D.asm | 43 ++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 unittests/ASM/OpSize/66_2A.asm create mode 100644 unittests/ASM/OpSize/66_2C.asm create mode 100644 unittests/ASM/OpSize/66_2D.asm diff --git a/unittests/ASM/OpSize/66_2A.asm b/unittests/ASM/OpSize/66_2A.asm new file mode 100644 index 000000000..7c8e5d653 --- /dev/null +++ b/unittests/ASM/OpSize/66_2A.asm @@ -0,0 +1,24 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x3ff0000000000000", "0x0"], + "XMM1": ["0xc000000000000000", "0xbff0000000000000"] + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x0000000000000001 +mov [rdx + 8 * 0], rax +mov rax, 0xFFFFFFFFFFFFFFFE +mov [rdx + 8 * 1], rax + +movq mm0, [rdx] +cvtpi2pd xmm0, mm0 +cvtpi2pd xmm1, [rdx + 8 * 1] + +hlt diff --git a/unittests/ASM/OpSize/66_2C.asm b/unittests/ASM/OpSize/66_2C.asm new file mode 100644 index 000000000..5f6f42132 --- /dev/null +++ b/unittests/ASM/OpSize/66_2C.asm @@ -0,0 +1,38 @@ +%ifdef CONFIG +{ + "RegData": { + "MM0": "0x0000000200000001", + "MM1": "0xFFFFFFFEFFFFFFFF" + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x3ff0000000000000 +mov [rdx + 8 * 0], rax +mov rax, 0x4000000000000000 +mov [rdx + 8 * 1], rax + +mov rax, 0xbff0000000000000 +mov [rdx + 8 * 2], rax +mov rax, 0xc000000000000000 +mov [rdx + 8 * 3], rax + +mov rax, 0x4142434445464748 +mov [rdx + 8 * 4], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 5], rax + +movq mm0, [rdx + 8 * 4] +movq mm1, [rdx + 8 * 4] + +movapd xmm2, [rdx + 8 * 0] + +cvttpd2pi mm0, xmm2 +cvttpd2pi mm1, [rdx + 8 * 2] + +hlt diff --git a/unittests/ASM/OpSize/66_2D.asm b/unittests/ASM/OpSize/66_2D.asm new file mode 100644 index 000000000..301486876 --- /dev/null +++ b/unittests/ASM/OpSize/66_2D.asm @@ -0,0 +1,43 @@ +%ifdef CONFIG +{ + "RegData": { + "MM0": "0x0000000200000001", + "MM1": "0xFFFFFFFEFFFFFFFF" + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +; Set up MXCSR to truncate +mov eax, 0x7F80 +mov [rdx + 8 * 0], eax +ldmxcsr [rdx + 8 * 0] + +mov rax, 0x3ff0000000000000 +mov [rdx + 8 * 0], rax +mov rax, 0x4000000000000000 +mov [rdx + 8 * 1], rax + +mov rax, 0xbff0000000000000 +mov [rdx + 8 * 2], rax +mov rax, 0xc000000000000000 +mov [rdx + 8 * 3], rax + +mov rax, 0x4142434445464748 +mov [rdx + 8 * 4], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 5], rax + +movq mm0, [rdx + 8 * 4] +movq mm1, [rdx + 8 * 4] + +movapd xmm2, [rdx + 8 * 0] + +cvtpd2pi mm0, xmm2 +cvtpd2pi mm1, [rdx + 8 * 2] + +hlt