From 3ced41414e3774d589918de0502a945bcc343a2b Mon Sep 17 00:00:00 2001 From: Lioncache Date: Tue, 14 Feb 2023 17:49:29 -0500 Subject: [PATCH] OpcodeDispatcher: Handle VMOVSD --- .../Interface/Core/OpcodeDispatcher.cpp | 2 ++ .../Source/Interface/Core/OpcodeDispatcher.h | 3 ++ .../Core/OpcodeDispatcher/Vector.cpp | 26 +++++++++----- .../Interface/Core/X86Tables/VEXTables.cpp | 4 +-- unittests/ASM/VEX/vmovsd_from_mem.asm | 29 ++++++++++++++++ unittests/ASM/VEX/vmovsd_to_mem.asm | 27 +++++++++++++++ unittests/ASM/VEX/vmovsd_vectors.asm | 34 +++++++++++++++++++ 7 files changed, 114 insertions(+), 11 deletions(-) create mode 100644 unittests/ASM/VEX/vmovsd_from_mem.asm create mode 100644 unittests/ASM/VEX/vmovsd_to_mem.asm create mode 100644 unittests/ASM/VEX/vmovsd_vectors.asm diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index f1b3ad112..a8c4cae7e 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -5815,9 +5815,11 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() { {OPD(1, 0b00, 0x10), 1, &OpDispatchBuilder::VMOVUPS_VMOVUPD_Op}, {OPD(1, 0b01, 0x10), 1, &OpDispatchBuilder::VMOVUPS_VMOVUPD_Op}, {OPD(1, 0b10, 0x10), 1, &OpDispatchBuilder::VMOVSSOp}, + {OPD(1, 0b11, 0x10), 1, &OpDispatchBuilder::VMOVSDOp}, {OPD(1, 0b00, 0x11), 1, &OpDispatchBuilder::VMOVUPS_VMOVUPD_Op}, {OPD(1, 0b01, 0x11), 1, &OpDispatchBuilder::VMOVUPS_VMOVUPD_Op}, {OPD(1, 0b10, 0x11), 1, &OpDispatchBuilder::VMOVSSOp}, + {OPD(1, 0b11, 0x11), 1, &OpDispatchBuilder::VMOVSDOp}, {OPD(1, 0b00, 0x12), 1, &OpDispatchBuilder::VMOVLPOp}, {OPD(1, 0b01, 0x12), 1, &OpDispatchBuilder::VMOVLPOp}, diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 87c067ff8..8f1143209 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -460,6 +460,7 @@ public: void VMOVSHDUPOp(OpcodeArgs); void VMOVSLDUPOp(OpcodeArgs); + void VMOVSDOp(OpcodeArgs); void VMOVSSOp(OpcodeArgs); void VMOVVectorNTOp(OpcodeArgs); @@ -847,6 +848,8 @@ private: const X86Tables::DecodedOperand& Src2, const X86Tables::DecodedOperand& Imm); + void VMOVScalarOpImpl(OpcodeArgs, size_t ElementSize); + OrderedNode* VFCMPOpImpl(OpcodeArgs, size_t ElementSize, bool Scalar, OrderedNode *Src1, OrderedNode *Src2, uint8_t CompType); diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 34d66329b..f0fec2db6 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -250,24 +250,32 @@ void OpDispatchBuilder::MOVSDOp(OpcodeArgs) { } } -void OpDispatchBuilder::VMOVSSOp(OpcodeArgs) { +void OpDispatchBuilder::VMOVScalarOpImpl(OpcodeArgs, size_t ElementSize) { if (Op->Dest.IsGPR() && Op->Src[0].IsGPR() && Op->Src[1].IsGPR()) { - // VMOVSS xmm1, xmm2, xmm3 + // VMOVSS/SD xmm1, xmm2, xmm3 OrderedNode *Src1 = LoadSource_WithOpSize(FPRClass, Op, Op->Src[0], 16, Op->Flags, -1); - OrderedNode *Src2 = LoadSource_WithOpSize(FPRClass, Op, Op->Src[1], 4, Op->Flags, -1); - OrderedNode *Result = _VInsElement(16, 4, 0, 0, Src1, Src2); + OrderedNode *Src2 = LoadSource_WithOpSize(FPRClass, Op, Op->Src[1], ElementSize, Op->Flags, -1); + OrderedNode *Result = _VInsElement(16, ElementSize, 0, 0, Src1, Src2); StoreResult(FPRClass, Op, Result, -1); } else if (Op->Dest.IsGPR()) { - // VMOVSS xmm1, mem32 - OrderedNode *Src = LoadSource_WithOpSize(FPRClass, Op, Op->Src[1], 4, Op->Flags, -1); + // VMOVSS/SD xmm1, mem32/mem64 + OrderedNode *Src = LoadSource_WithOpSize(FPRClass, Op, Op->Src[1], ElementSize, Op->Flags, -1); StoreResult(FPRClass, Op, Src, -1); } else { - // VMOVSS mem32, xmm1 - OrderedNode *Src = LoadSource_WithOpSize(FPRClass, Op, Op->Src[1], 4, Op->Flags, -1); - StoreResult_WithOpSize(FPRClass, Op, Op->Dest, Src, 4, -1); + // VMOVSS/SD mem32/mem64, xmm1 + OrderedNode *Src = LoadSource_WithOpSize(FPRClass, Op, Op->Src[1], ElementSize, Op->Flags, -1); + StoreResult_WithOpSize(FPRClass, Op, Op->Dest, Src, ElementSize, -1); } } +void OpDispatchBuilder::VMOVSDOp(OpcodeArgs) { + VMOVScalarOpImpl(Op, 8); +} + +void OpDispatchBuilder::VMOVSSOp(OpcodeArgs) { + VMOVScalarOpImpl(Op, 4); +} + void OpDispatchBuilder::VectorALUOpImpl(OpcodeArgs, IROps IROp, size_t ElementSize) { const auto Size = GetSrcSize(Op); OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); diff --git a/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp b/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp index 980843a88..9b53b42e5 100644 --- a/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp +++ b/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp @@ -20,12 +20,12 @@ void InitializeVEXTables() { {OPD(1, 0b00, 0x10), 1, X86InstInfo{"VMOVUPS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(1, 0b01, 0x10), 1, X86InstInfo{"VMOVUPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(1, 0b10, 0x10), 1, X86InstInfo{"VMOVSS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}}, - {OPD(1, 0b11, 0x10), 1, X86InstInfo{"VMOVSD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(1, 0b11, 0x10), 1, X86InstInfo{"VMOVSD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(1, 0b00, 0x11), 1, X86InstInfo{"VMOVUPS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_DST | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(1, 0b01, 0x11), 1, X86InstInfo{"VMOVUPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_DST | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(1, 0b10, 0x11), 1, X86InstInfo{"VMOVSS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_DST | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}}, - {OPD(1, 0b11, 0x11), 1, X86InstInfo{"VMOVSD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(1, 0b11, 0x11), 1, X86InstInfo{"VMOVSD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_DST | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(1, 0b00, 0x12), 1, X86InstInfo{"VMOVLPS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_MEM_ONLY | FLAGS_XMM_FLAGS | FLAGS_VEX_1ST_SRC, 0, nullptr}}, {OPD(1, 0b01, 0x12), 1, X86InstInfo{"VMOVLPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_MEM_ONLY | FLAGS_XMM_FLAGS | FLAGS_VEX_1ST_SRC, 0, nullptr}}, diff --git a/unittests/ASM/VEX/vmovsd_from_mem.asm b/unittests/ASM/VEX/vmovsd_from_mem.asm new file mode 100644 index 000000000..01c662674 --- /dev/null +++ b/unittests/ASM/VEX/vmovsd_from_mem.asm @@ -0,0 +1,29 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0x4142434445464748", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"] + } +} +%endif + +lea rdx, [rel .data] + +vmovapd ymm0, [rdx + 32] + +; Move data into register +vmovsd xmm0, [rdx] + +hlt + +align 32 +.data: +dq 0x4142434445464748 +dq 0x5152535455565758 +dq 0x0000000000000000 +dq 0x0000000000000000 + +dq 0xFFFFFFFFFFFFFFFF +dq 0xFFFFFFFFFFFFFFFF +dq 0xFFFFFFFFFFFFFFFF +dq 0xFFFFFFFFFFFFFFFF diff --git a/unittests/ASM/VEX/vmovsd_to_mem.asm b/unittests/ASM/VEX/vmovsd_to_mem.asm new file mode 100644 index 000000000..489f1e57b --- /dev/null +++ b/unittests/ASM/VEX/vmovsd_to_mem.asm @@ -0,0 +1,27 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0x4142434445464748", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"] + } +} +%endif + +lea rdx, [rel .data] + +vmovapd xmm0, [rdx] + +; Moves lower 64bits to memory +vmovsd [rdx + 16], xmm0 + +; Ensure 128bits weren't written +vmovapd xmm0, [rdx + 16] + +hlt + +align 32 +.data: +dq 0x4142434445464748 +dq 0x5152535455565758 +dq 0x0000000000000000 +dq 0x0000000000000000 \ No newline at end of file diff --git a/unittests/ASM/VEX/vmovsd_vectors.asm b/unittests/ASM/VEX/vmovsd_vectors.asm new file mode 100644 index 000000000..e4729a7b6 --- /dev/null +++ b/unittests/ASM/VEX/vmovsd_vectors.asm @@ -0,0 +1,34 @@ + +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0xAAAAAAAABBBBBBBB", "0xCCCCCCCCDDDDDDDD", "0xEEEEEEEEFFFFFFFF", "0x9999999988888888"], + "XMM1": ["0x1111111122222222", "0x3333333344444444", "0x5555555566666666", "0x7777777788888888"], + "XMM2": ["0x1111111122222222", "0xCCCCCCCCDDDDDDDD", "0x0000000000000000", "0x0000000000000000"], + "XMM3": ["0xAAAAAAAABBBBBBBB", "0x3333333344444444", "0x0000000000000000", "0x0000000000000000"] + } +} +%endif + +lea rdx, [rel .data] + +vmovapd ymm0, [rdx] +vmovapd ymm1, [rdx + 32] + +vmovsd xmm2, xmm0, xmm1 +vmovsd xmm3, xmm1, xmm0 + +hlt + +align 32 +.data: +dq 0xAAAAAAAABBBBBBBB +dq 0xCCCCCCCCDDDDDDDD +dq 0xEEEEEEEEFFFFFFFF +dq 0x9999999988888888 + +dq 0x1111111122222222 +dq 0x3333333344444444 +dq 0x5555555566666666 +dq 0x7777777788888888