From d9da63d492c051fc1504e9a67d22b9aa4358b228 Mon Sep 17 00:00:00 2001 From: Lioncache Date: Wed, 8 Mar 2023 18:44:32 -0500 Subject: [PATCH] OpcodeDispatcher: Handle VPSADBW --- .../Interface/Core/OpcodeDispatcher.cpp | 1 + .../Source/Interface/Core/OpcodeDispatcher.h | 2 + .../Core/OpcodeDispatcher/Vector.cpp | 29 +++- .../Interface/Core/X86Tables/VEXTables.cpp | 2 +- unittests/ASM/VEX/vpsadbw.asm | 98 +++++++++++++ unittests/ASM/VEX/vpsadbw_256.asm | 134 ++++++++++++++++++ 6 files changed, 261 insertions(+), 5 deletions(-) create mode 100644 unittests/ASM/VEX/vpsadbw.asm create mode 100644 unittests/ASM/VEX/vpsadbw_256.asm diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 2cde014a2..e1098a061 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -5841,6 +5841,7 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() { {OPD(1, 0b01, 0xF3), 1, &OpDispatchBuilder::VPSLLOp<8>}, {OPD(1, 0b01, 0xF4), 1, &OpDispatchBuilder::VPMULLOp<4, false>}, {OPD(1, 0b01, 0xF5), 1, &OpDispatchBuilder::VPMADDWDOp}, + {OPD(1, 0b01, 0xF6), 1, &OpDispatchBuilder::VPSADBWOp}, {OPD(1, 0b01, 0xF7), 1, &OpDispatchBuilder::MASKMOVOp}, {OPD(1, 0b01, 0xF8), 1, &OpDispatchBuilder::AVXVectorALUOp}, diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index f6e0487de..06621b548 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -507,6 +507,8 @@ public: template void VPMULLOp(OpcodeArgs); + void VPSADBWOp(OpcodeArgs); + void VPSHUFBOp(OpcodeArgs); template diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 7a82c3d21..aaa0e471e 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -3415,6 +3415,7 @@ OrderedNode* OpDispatchBuilder::PSADBWOpImpl(OpcodeArgs, // This can be seen with `abs(0 - 0xFF)` returning a different result depending // on bit length const auto Size = GetSrcSize(Op); + const auto Is128Bit = Size == Core::CPUState::XMM_SSE_REG_SIZE; OrderedNode *Src1 = LoadSource(FPRClass, Op, Src1Op, Op->Flags, -1); OrderedNode *Src2 = LoadSource(FPRClass, Op, Src2Op, Op->Flags, -1); @@ -3430,6 +3431,7 @@ OrderedNode* OpDispatchBuilder::PSADBWOpImpl(OpcodeArgs, return _VAddV(Size * 2, 2, AbsResult); } + OrderedNode *Src1_Low = _VUXTL(Size, 1, Src1); OrderedNode *Src1_High = _VUXTL2(Size, 1, Src1); @@ -3442,11 +3444,25 @@ OrderedNode* OpDispatchBuilder::PSADBWOpImpl(OpcodeArgs, OrderedNode *AbsResult_Low = _VAbs(Size, 2, SubResult_Low); OrderedNode *AbsResult_High = _VAbs(Size, 2, SubResult_High); - // Now vector pairwise add all four of these - OrderedNode * Result_Low = _VAddV(Size, 2, AbsResult_Low); - OrderedNode * Result_High = _VAddV(Size, 2, AbsResult_High); + OrderedNode *Result_Low = _VAddV(16, 2, AbsResult_Low); + OrderedNode *Result_High = _VAddV(16, 2, AbsResult_High); - return _VInsElement(Size, 8, 1, 0, Result_Low, Result_High); + OrderedNode *Low = _VInsElement(Size, 8, 1, 0, Result_Low, Result_High); + if (Is128Bit) { + return Low; + } + + OrderedNode *HighSrc1 = _VDupElement(Size, 16, AbsResult_Low, 1); + OrderedNode *HighSrc2 = _VDupElement(Size, 16, AbsResult_High, 1); + + OrderedNode *HighResult_Low = _VAddV(16, 2, HighSrc1); + OrderedNode *HighResult_High = _VAddV(16, 2, HighSrc2); + + OrderedNode *High = _VInsElement(Size, 8, 1, 0, HighResult_Low, HighResult_High); + OrderedNode *Full = _VInsElement(Size, 16, 1, 0, Low, High); + + OrderedNode *Tmp = _VInsElement(Size, 8, 2, 1, Full, Full); + return _VInsElement(Size, 8, 1, 2, Tmp, Full); } void OpDispatchBuilder::PSADBW(OpcodeArgs) { @@ -3454,6 +3470,11 @@ void OpDispatchBuilder::PSADBW(OpcodeArgs) { StoreResult(FPRClass, Op, Result, -1); } +void OpDispatchBuilder::VPSADBWOp(OpcodeArgs) { + OrderedNode *Result = PSADBWOpImpl(Op, Op->Src[0], Op->Src[1]); + StoreResult(FPRClass, Op, Result, -1); +} + OrderedNode* OpDispatchBuilder::ExtendVectorElementsImpl(OpcodeArgs, size_t ElementSize, size_t DstElementSize, bool Signed) { const auto DstSize = GetDstSize(Op); diff --git a/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp b/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp index 169da8c3d..0e6dc57f2 100644 --- a/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp +++ b/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp @@ -247,7 +247,7 @@ void InitializeVEXTables() { {OPD(1, 0b01, 0xF3), 1, X86InstInfo{"VPSLLQ", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(1, 0b01, 0xF4), 1, X86InstInfo{"VPMULUDQ", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(1, 0b01, 0xF5), 1, X86InstInfo{"VPMADDWD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}}, - {OPD(1, 0b01, 0xF6), 1, X86InstInfo{"VPSADBW", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(1, 0b01, 0xF6), 1, X86InstInfo{"VPSADBW", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(1, 0b01, 0xF7), 1, X86InstInfo{"VMASKMOVDQU", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_SF_MOD_REG_ONLY | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(1, 0b01, 0xF8), 1, X86InstInfo{"VPSUBB", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}}, diff --git a/unittests/ASM/VEX/vpsadbw.asm b/unittests/ASM/VEX/vpsadbw.asm new file mode 100644 index 000000000..ce993cecc --- /dev/null +++ b/unittests/ASM/VEX/vpsadbw.asm @@ -0,0 +1,98 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0x100", "0x100", "0x000", "0x000"], + "XMM8": ["0x327", "0x2F4", "0x000", "0x000"], + "XMM9": ["0x2BA", "0x27F", "0x000", "0x000"], + "XMM10": ["0x2B1", "0x284", "0x000", "0x000"], + "XMM11": ["0x295", "0x280", "0x000", "0x000"], + "XMM12": ["0x190", "0x279", "0x000", "0x000"], + "XMM13": ["0x29B", "0x2A8", "0x000", "0x000"], + "XMM14": ["0x25B", "0x1EA", "0x000", "0x000"] + } +} +%endif + +lea rdx, [rel .reg_data] + +vmovaps xmm0, [rdx + 8 * 2] +psadbw xmm0, [rdx + 8 * 0] + +lea rdx, [rel .data] + +vmovaps xmm1, [rdx + 16 * 0] +vmovaps xmm2, [rdx + 16 * 1] +vmovaps xmm3, [rdx + 16 * 2] +vmovaps xmm4, [rdx + 16 * 3] +vmovaps xmm5, [rdx + 16 * 4] +vmovaps xmm6, [rdx + 16 * 5] +vmovaps xmm7, [rdx + 16 * 6] + +vpsadbw xmm8, xmm1, [rdx + 16 * 8] +vpsadbw xmm9, xmm2, [rdx + 16 * 9] +vpsadbw xmm10, xmm3, [rdx + 16 * 10] +vpsadbw xmm11, xmm4, [rdx + 16 * 11] +vpsadbw xmm12, xmm5, [rdx + 16 * 12] +vpsadbw xmm13, xmm6, [rdx + 16 * 13] +vpsadbw xmm14, xmm7, [rdx + 16 * 14] + +hlt + +align 16 + +.reg_data: +dq 0x4142434445464748 +dq 0x5152535455565758 + +dq 0x6162636465666768 +dq 0x7172737475767778 + +.data: +dq 0xE0FC2BA1064F6CA7 +dq 0x0F066A1E7F76809B + +dq 0xE056EDAAF3C36868 +dq 0xDEE6E694E2E9FCF0 + +dq 0x6E35A854D7AB8B6C +dq 0x775F92CA25A67E27 + +dq 0xC7CD73EC95D66F6A +dq 0xBBAEF2BB27B9A1DD + +dq 0x734DD1C7D52C3188 +dq 0xFEE7DBFD1E1E097F + +dq 0x14FA4E95EFE69AF2 +dq 0xA042629AA4A87382 + +dq 0x0E0F168238071232 +dq 0x073592C1630778B3 + +dq 0xCB4619572B372A46 +dq 0x1F040E793DCD8DA3 + +dq 0x2BF3862FABBA5730 +dq 0x2ED62CF0464F3FEF + +dq 0xEFD1BB85344B3CDE +dq 0x9E48A3B98D71E39D + +dq 0x0972FBDE8A32509D +dq 0x6998F1F652EBF7EE + +dq 0xD699C2FF301C02CE +dq 0x7005B2F1569C0EA6 + +dq 0x1862C4E286387630 +dq 0x2FA1E4A70E5D53EB + +dq 0x1445E0B7E1E80268 +dq 0x1AFE8EC18FF2EB46 + +dq 0x7F5D6A2346972E03 +dq 0x9812328F547659AC + +dq 0xC8765FC8710CD3B6 +dq 0xC519EAABA62C1D88 diff --git a/unittests/ASM/VEX/vpsadbw_256.asm b/unittests/ASM/VEX/vpsadbw_256.asm new file mode 100644 index 000000000..fd6a8df41 --- /dev/null +++ b/unittests/ASM/VEX/vpsadbw_256.asm @@ -0,0 +1,134 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0x100", "0x100", "0x080", "0x180"], + "XMM8": ["0x327", "0x21D", "0x3CA", "0x2BA"], + "XMM9": ["0x2BA", "0x3CA", "0x21D", "0x327"], + "XMM10": ["0x2B1", "0x279", "0x284", "0x1F8"], + "XMM11": ["0x295", "0x306", "0x280", "0x27B"], + "XMM12": ["0x245", "0x235", "0x279", "0x42E"], + "XMM13": ["0x29B", "0x139", "0x35B", "0x396"], + "XMM14": ["0x25B", "0x390", "0x1EA", "0x2F9"] + } +} +%endif + +lea rdx, [rel .reg_data] + +vmovaps ymm0, [rdx + 32] +vpsadbw ymm0, ymm0, [rdx] + +lea rdx, [rel .data] + +vmovaps ymm1, [rdx + 32 * 0] +vmovaps ymm2, [rdx + 32 * 1] +vmovaps ymm3, [rdx + 32 * 2] +vmovaps ymm4, [rdx + 32 * 3] +vmovaps ymm5, [rdx + 32 * 4] +vmovaps ymm6, [rdx + 32 * 5] +vmovaps ymm7, [rdx + 32 * 6] + +vpsadbw ymm8, ymm1, [rdx + 32 * 8] +vpsadbw ymm9, ymm2, [rdx + 32 * 9] +vpsadbw ymm10, ymm3, [rdx + 32 * 10] +vpsadbw ymm11, ymm4, [rdx + 32 * 11] +vpsadbw ymm12, ymm5, [rdx + 32 * 12] +vpsadbw ymm13, ymm6, [rdx + 32 * 13] +vpsadbw ymm14, ymm7, [rdx + 32 * 14] + +hlt + +align 16 + +.reg_data: +dq 0x4142434445464748 +dq 0x5152535455565758 +dq 0x6162636465666768 +dq 0x7172737475767778 + +dq 0x6162636465666768 +dq 0x7172737475767778 +dq 0x5152535455565758 +dq 0x4142434445464748 + +.data: +dq 0xE0FC2BA1064F6CA7 +dq 0x0F066A1E7F76809B +dq 0xDEE6E694E2E9FCF0 +dq 0xE056EDAAF3C36868 + +dq 0xE056EDAAF3C36868 +dq 0xDEE6E694E2E9FCF0 +dq 0x0F066A1E7F76809B +dq 0xE0FC2BA1064F6CA7 + +dq 0x6E35A854D7AB8B6C +dq 0xC7CD73EC95D66F6A +dq 0x775F92CA25A67E27 +dq 0xBBAEF2BB27B9A1DD + +dq 0xC7CD73EC95D66F6A +dq 0x6E35A854D7AB8B6C +dq 0xBBAEF2BB27B9A1DD +dq 0x775F92CA25A67E27 + +dq 0x734DD1C7D52C3188 +dq 0xA042629AA4A87382 +dq 0xFEE7DBFD1E1E097F +dq 0x14FA4E95EFE69AF2 + +dq 0x14FA4E95EFE69AF2 +dq 0xA042629AA4A87382 +dq 0x734DD1C7D52C3188 +dq 0xFEE7DBFD1E1E097F + +dq 0x0E0F168238071232 +dq 0xCB4619572B372A46 +dq 0x073592C1630778B3 +dq 0x1F040E793DCD8DA3 + +dq 0xCB4619572B372A46 +dq 0x0E0F168238071232 +dq 0x1F040E793DCD8DA3 +dq 0x073592C1630778B3 + +dq 0x2BF3862FABBA5730 +dq 0x9E48A3B98D71E39D +dq 0x2ED62CF0464F3FEF +dq 0xEFD1BB85344B3CDE + +dq 0xEFD1BB85344B3CDE +dq 0x2ED62CF0464F3FEF +dq 0x9E48A3B98D71E39D +dq 0x2BF3862FABBA5730 + +dq 0x0972FBDE8A32509D +dq 0x7005B2F1569C0EA6 +dq 0x6998F1F652EBF7EE +dq 0xD699C2FF301C02CE + +dq 0xD699C2FF301C02CE +dq 0x6998F1F652EBF7EE +dq 0x7005B2F1569C0EA6 +dq 0x0972FBDE8A32509D + +dq 0xC8765FC8710CD3B6 +dq 0x1862C4E286387630 +dq 0x2FA1E4A70E5D53EB +dq 0xC519EAABA62C1D88 + +dq 0x1445E0B7E1E80268 +dq 0x9812328F547659AC +dq 0x1AFE8EC18FF2EB46 +dq 0x7F5D6A2346972E03 + +dq 0x7F5D6A2346972E03 +dq 0x1445E0B7E1E80268 +dq 0x9812328F547659AC +dq 0x1AFE8EC18FF2EB46 + +dq 0x1445E0B7E1E80268 +dq 0xC8765FC8710CD3B6 +dq 0xC519EAABA62C1D88 +dq 0x1AFE8EC18FF2EB46