diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 56f842df8..c7e48550c 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -6082,6 +6082,9 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() { {OPD(3, 0b01, 0x38), 1, &OpDispatchBuilder::VINSERTOp}, + {OPD(3, 0b01, 0x40), 1, &OpDispatchBuilder::VDPPOp<4>}, + {OPD(3, 0b01, 0x41), 1, &OpDispatchBuilder::VDPPOp<8>}, + {OPD(3, 0b01, 0x46), 1, &OpDispatchBuilder::VPERM2Op}, {OPD(3, 0b01, 0xDF), 1, &OpDispatchBuilder::VAESKeyGenAssistOp}, diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index cca150728..3559fe703 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -440,6 +440,9 @@ public: template void VBROADCASTOp(OpcodeArgs); + template + void VDPPOp(OpcodeArgs); + template void VHADDPOp(OpcodeArgs); @@ -751,6 +754,10 @@ private: OrderedNode* AESKeyGenAssistImpl(OpcodeArgs); OrderedNode* AESIMCImpl(OpcodeArgs); + OrderedNode* DPPOpImpl(OpcodeArgs, const X86Tables::DecodedOperand& Src1, + const X86Tables::DecodedOperand& Src2, + const X86Tables::DecodedOperand& Imm, size_t ElementSize); + OrderedNode* ExtendVectorElementsImpl(OpcodeArgs, size_t ElementSize, size_t DstElementSize, bool Signed); diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 4ed69cbdb..7fafbea1e 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -3488,47 +3488,60 @@ void OpDispatchBuilder::VPHMINPOSUWOp(OpcodeArgs) { StoreResult(FPRClass, Op, Result, -1); } -template -void OpDispatchBuilder::DPPOp(OpcodeArgs) { - LOGMAN_THROW_A_FMT(Op->Src[1].IsLiteral(), "Src1 needs to be literal here"); - uint8_t Mask = Op->Src[1].Data.Literal.Value; - uint8_t SrcMask = Mask >> 4; - uint8_t DstMask = Mask & 0xF; +OrderedNode* OpDispatchBuilder::DPPOpImpl(OpcodeArgs, const X86Tables::DecodedOperand& Src1, + const X86Tables::DecodedOperand& Src2, + const X86Tables::DecodedOperand& Imm, size_t ElementSize) { + LOGMAN_THROW_A_FMT(Imm.IsLiteral(), "Imm needs to be literal here"); + const uint8_t Mask = Imm.Data.Literal.Value; + const uint8_t SrcMask = Mask >> 4; + const uint8_t DstMask = Mask & 0xF; - OrderedNode *ZeroVec = _VectorZero(16); + const auto DstSize = GetDstSize(Op); - OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); - OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); + OrderedNode *Src1V = LoadSource(FPRClass, Op, Src1, Op->Flags, -1); + OrderedNode *Src2V = LoadSource(FPRClass, Op, Src2, Op->Flags, -1); + + OrderedNode *ZeroVec = _VectorZero(DstSize); // First step is to do an FMUL - OrderedNode *Temp = _VFMul(16, ElementSize, Dest, Src); + OrderedNode *Temp = _VFMul(DstSize, ElementSize, Src1V, Src2V); // Now we zero out elements based on src mask - for (size_t i = 0; i < (16 / ElementSize); ++i) { - if ((SrcMask & (1 << i)) == 0) { - Temp = _VInsElement(16, ElementSize, i, 0, Temp, ZeroVec); + for (size_t i = 0; i < (DstSize / ElementSize); ++i) { + const auto Bit = 1U << (i % 4); + + if ((SrcMask & Bit) == 0) { + Temp = _VInsElement(DstSize, ElementSize, i, 0, Temp, ZeroVec); } } // Now we need to do a horizontal add of the elements // We only have pairwise float add so this needs to be done in steps - Temp = _VFAddP(16, ElementSize, Temp, ZeroVec); + Temp = _VFAddP(DstSize, ElementSize, Temp, ZeroVec); - if constexpr (ElementSize == 4) { + if (ElementSize == 4) { // For 32-bit float we need one more step to add all four results together - Temp = _VFAddP(16, ElementSize, Temp, ZeroVec); + Temp = _VFAddP(DstSize, ElementSize, Temp, ZeroVec); } // Now using the destination mask we choose where the result ends up // It can duplicate and zero results - auto Result = ZeroVec; + OrderedNode *Result = ZeroVec; - for (size_t i = 0; i < (16 / ElementSize); ++i) { - if (DstMask & (1 << i)) { - Result = _VInsElement(16, ElementSize, i, 0, Result, Temp); + for (size_t i = 0; i < (DstSize / ElementSize); ++i) { + const auto Bit = 1U << (i % 4); + + if ((DstMask & Bit) != 0) { + Result = _VInsElement(DstSize, ElementSize, i, 0, Result, Temp); } } + return Result; +} + +template +void OpDispatchBuilder::DPPOp(OpcodeArgs) { + OrderedNode *Result = DPPOpImpl(Op, Op->Dest, Op->Src[0], Op->Src[1], ElementSize); StoreResult(FPRClass, Op, Result, -1); } @@ -3537,6 +3550,20 @@ void OpDispatchBuilder::DPPOp<4>(OpcodeArgs); template void OpDispatchBuilder::DPPOp<8>(OpcodeArgs); +template +void OpDispatchBuilder::VDPPOp(OpcodeArgs) { + OrderedNode *Result = DPPOpImpl(Op, Op->Src[0], Op->Src[1], Op->Src[2], ElementSize); + + // We don't need to emit a _VMov to clear the upper lane, since DPPOpImpl uses a zero vector + // to construct the results, so the upper lane will always be cleared for the 128-bit version. + StoreResult(FPRClass, Op, Result, -1); +} + +template +void OpDispatchBuilder::VDPPOp<4>(OpcodeArgs); +template +void OpDispatchBuilder::VDPPOp<8>(OpcodeArgs); + void OpDispatchBuilder::MPSADBWOp(OpcodeArgs) { LOGMAN_THROW_A_FMT(Op->Src[1].IsLiteral(), "Src1 needs to be literal here"); uint8_t Select = Op->Src[1].Data.Literal.Value; diff --git a/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp b/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp index 1320f479a..9394383b7 100644 --- a/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp +++ b/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp @@ -437,8 +437,8 @@ void InitializeVEXTables() { {OPD(3, 0b01, 0x38), 1, X86InstInfo{"VINSERTI128", TYPE_INST, GenFlagsSameSize(SIZE_256BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 1, nullptr}}, {OPD(3, 0b01, 0x39), 1, X86InstInfo{"VEXTRACTI128", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(3, 0b01, 0x40), 1, X86InstInfo{"VDPPS", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(3, 0b01, 0x41), 1, X86InstInfo{"VDPPD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(3, 0b01, 0x40), 1, X86InstInfo{"VDPPS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 1, nullptr}}, + {OPD(3, 0b01, 0x41), 1, X86InstInfo{"VDPPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 1, nullptr}}, {OPD(3, 0b01, 0x42), 1, X86InstInfo{"VMPSADBW", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, {OPD(3, 0b01, 0x44), 1, X86InstInfo{"VPCLMULQDQ", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 1, nullptr}}, {OPD(3, 0b01, 0x46), 1, X86InstInfo{"VPERM2I128", TYPE_INST, GenFlagsSameSize(SIZE_256BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 1, nullptr}}, diff --git a/unittests/ASM/VEX/vdppd.asm b/unittests/ASM/VEX/vdppd.asm new file mode 100644 index 000000000..46f74f504 --- /dev/null +++ b/unittests/ASM/VEX/vdppd.asm @@ -0,0 +1,56 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM8": ["0x41278C496C911A6E", "0x41278C496C911A6E", "0x0000000000000000", "0x0000000000000000"], + "XMM9": ["0x41235CCC64AFB361", "0x41235CCC64AFB361", "0x0000000000000000", "0x0000000000000000"], + "XMM10": ["0x412BACE273945DC5", "0x412BACE273945DC5", "0x0000000000000000", "0x0000000000000000"], + "XMM11": ["0x412CF22EF582FD76", "0x412CF22EF582FD76", "0x0000000000000000", "0x0000000000000000"], + "XMM12": ["0x4121C80E40F3BC7B", "0x4121C80E40F3BC7B", "0x0000000000000000", "0x0000000000000000"], + "XMM13": ["0x0000000000000000", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"], + "XMM14": ["0x0000000000000000", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"], + "XMM15": ["0x0000000000000000", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"] + } +} +%endif + +lea rdx, [rel .data] + +vmovaps xmm0, [rdx + 16 * 0] +vmovaps xmm1, [rdx + 16 * 1] +vmovaps xmm2, [rdx + 16 * 2] +vmovaps xmm3, [rdx + 16 * 3] +vmovaps xmm4, [rdx + 16 * 4] +vmovaps xmm5, [rdx + 16 * 5] +vmovaps xmm6, [rdx + 16 * 6] +vmovaps xmm7, [rdx + 16 * 7] + +vdppd xmm8, xmm0, [rdx + 16 * 8], 11111111b +vdppd xmm9, xmm1, [rdx + 16 * 9], 11111111b +vdppd xmm10, xmm2, [rdx + 16 * 10], 11111111b +vdppd xmm11, xmm3, [rdx + 16 * 11], 11111111b +vdppd xmm12, xmm4, [rdx + 16 * 12], 11111111b +vdppd xmm13, xmm5, [rdx + 16 * 13], 00000000b +vdppd xmm14, xmm6, [rdx + 16 * 14], 11110000b +vdppd xmm15, xmm7, [rdx + 16 * 15], 00001111b + +hlt + +align 32 +.data: +dq 470.4127, 683.87 +dq 711.3545, 511.5631 +dq 996.8793, 548.682 +dq 588.9345, 832.5925 +dq 210.6613, 792.6059 +dq 298.4494, 154.4895 +dq 818.4 , 881.6027 +dq 705.3087, 687.478 +dq 737.0665, 621.31 +dq 755.3097, 189.9614 +dq 552.4284, 649.1206 +dq 798.252 , 574.5732 +dq 593.7565, 577.3129 +dq 383.3844, 443.3476 +dq 414.3571, 615.1567 +dq 94.898 , 438.3107 diff --git a/unittests/ASM/VEX/vdpps_128.asm b/unittests/ASM/VEX/vdpps_128.asm new file mode 100644 index 000000000..3ed5c0171 --- /dev/null +++ b/unittests/ASM/VEX/vdpps_128.asm @@ -0,0 +1,56 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM8": ["0x492FEB2E492FEB2E", "0x492FEB2E492FEB2E", "0x0000000000000000", "0x0000000000000000"], + "XMM9": ["0x499A5226499A5226", "0x499A5226499A5226", "0x0000000000000000", "0x0000000000000000"], + "XMM10": ["0x494ECFA4494ECFA4", "0x494ECFA4494ECFA4", "0x0000000000000000", "0x0000000000000000"], + "XMM11": ["0x495F7816495F7816", "0x495F7816495F7816", "0x0000000000000000", "0x0000000000000000"], + "XMM12": ["0x496E3962496E3962", "0x496E3962496E3962", "0x0000000000000000", "0x0000000000000000"], + "XMM13": ["0x0000000000000000", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"], + "XMM14": ["0x0000000000000000", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"], + "XMM15": ["0x0000000000000000", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"] + } +} +%endif + +lea rdx, [rel .data] + +vmovaps xmm0, [rdx + 16 * 0] +vmovaps xmm1, [rdx + 16 * 1] +vmovaps xmm2, [rdx + 16 * 2] +vmovaps xmm3, [rdx + 16 * 3] +vmovaps xmm4, [rdx + 16 * 4] +vmovaps xmm5, [rdx + 16 * 5] +vmovaps xmm6, [rdx + 16 * 6] +vmovaps xmm7, [rdx + 16 * 7] + +vdpps xmm8, xmm0, [rdx + 16 * 8], 11111111b +vdpps xmm9, xmm1, [rdx + 16 * 9], 11111111b +vdpps xmm10, xmm2, [rdx + 16 * 10], 11111111b +vdpps xmm11, xmm3, [rdx + 16 * 11], 11111111b +vdpps xmm12, xmm4, [rdx + 16 * 12], 11111111b +vdpps xmm13, xmm5, [rdx + 16 * 13], 00000000b +vdpps xmm14, xmm6, [rdx + 16 * 14], 11110000b +vdpps xmm15, xmm7, [rdx + 16 * 15], 00001111b + +hlt + +align 32 +.data: +dd 655.9708, 532.2244, 108.0451, 512.4019 +dd 754.227 , 586.0859, 127.7574, 114.8167 +dd 764.4266, 226.6145, 337.864 , 320.3296 +dd 296.5247, 480.0057, 28.4267 , 565.9418 +dd 265.8255, 536.4473, 754.3489, 460.681 +dd 818.7269, 43.7204 , 464.592 , 847.9381 +dd 306.0592, 702.7584, 887.6473, 551.5908 +dd 620.9001, 520.9829, 232.9532, 510.3388 +dd 204.8474, 225.626 , 564.973 , 790.5175 +dd 836.1953, 844.5266, 633.5626, 501.7409 +dd 393.2616, 674.4415, 244.3265, 971.1598 +dd 770.8029, 746.1836, 255.9902, 567.7578 +dd 187.7175, 924.181 , 466.4362, 169.8267 +dd 651.7481, 462.4206, 396.6924, 355.8538 +dd 6.148 , 523.1443, 989.7004, 713.6646 +dd 497.5427, 657.6965, 651.0534, 778.5236 diff --git a/unittests/ASM/VEX/vdpps_256.asm b/unittests/ASM/VEX/vdpps_256.asm new file mode 100644 index 000000000..cc2ec5819 --- /dev/null +++ b/unittests/ASM/VEX/vdpps_256.asm @@ -0,0 +1,87 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM8": ["0x492FEB2E492FEB2E", "0x492FEB2E492FEB2E", "0x492FEB2E492FEB2E", "0x492FEB2E492FEB2E"], + "XMM9": ["0x499A5226499A5226", "0x499A5226499A5226", "0x499A5226499A5226", "0x499A5226499A5226"], + "XMM10": ["0x494ECFA4494ECFA4", "0x494ECFA4494ECFA4", "0x494ECFA4494ECFA4", "0x494ECFA4494ECFA4"], + "XMM11": ["0x495F7816495F7816", "0x495F7816495F7816", "0x495F7816495F7816", "0x495F7816495F7816"], + "XMM12": ["0x496E3962496E3962", "0x496E3962496E3962", "0x496E3962496E3962", "0x496E3962496E3962"], + "XMM13": ["0x0000000000000000", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"], + "XMM14": ["0x0000000000000000", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"], + "XMM15": ["0x0000000000000000", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"] + } +} +%endif + +lea rdx, [rel .data] + +vmovaps ymm0, [rdx + 32 * 0] +vmovaps ymm1, [rdx + 32 * 1] +vmovaps ymm2, [rdx + 32 * 2] +vmovaps ymm3, [rdx + 32 * 3] +vmovaps ymm4, [rdx + 32 * 4] +vmovaps ymm5, [rdx + 32 * 5] +vmovaps ymm6, [rdx + 32 * 6] +vmovaps ymm7, [rdx + 32 * 7] + +vdpps ymm8, ymm0, [rdx + 32 * 8], 11111111b +vdpps ymm9, ymm1, [rdx + 32 * 9], 11111111b +vdpps ymm10, ymm2, [rdx + 32 * 10], 11111111b +vdpps ymm11, ymm3, [rdx + 32 * 11], 11111111b +vdpps ymm12, ymm4, [rdx + 32 * 12], 11111111b +vdpps ymm13, ymm5, [rdx + 32 * 13], 00000000b +vdpps ymm14, ymm6, [rdx + 32 * 14], 11110000b +vdpps ymm15, ymm7, [rdx + 32 * 15], 00001111b + +hlt + +align 32 +.data: +dd 655.9708, 532.2244, 108.0451, 512.4019 +dd 655.9708, 532.2244, 108.0451, 512.4019 + +dd 754.227 , 586.0859, 127.7574, 114.8167 +dd 754.227 , 586.0859, 127.7574, 114.8167 + +dd 764.4266, 226.6145, 337.864 , 320.3296 +dd 764.4266, 226.6145, 337.864 , 320.3296 + +dd 296.5247, 480.0057, 28.4267 , 565.9418 +dd 296.5247, 480.0057, 28.4267 , 565.9418 + +dd 265.8255, 536.4473, 754.3489, 460.681 +dd 265.8255, 536.4473, 754.3489, 460.681 + +dd 818.7269, 43.7204 , 464.592 , 847.9381 +dd 818.7269, 43.7204 , 464.592 , 847.9381 + +dd 306.0592, 702.7584, 887.6473, 551.5908 +dd 306.0592, 702.7584, 887.6473, 551.5908 + +dd 620.9001, 520.9829, 232.9532, 510.3388 +dd 620.9001, 520.9829, 232.9532, 510.3388 + +dd 204.8474, 225.626 , 564.973 , 790.5175 +dd 204.8474, 225.626 , 564.973 , 790.5175 + +dd 836.1953, 844.5266, 633.5626, 501.7409 +dd 836.1953, 844.5266, 633.5626, 501.7409 + +dd 393.2616, 674.4415, 244.3265, 971.1598 +dd 393.2616, 674.4415, 244.3265, 971.1598 + +dd 770.8029, 746.1836, 255.9902, 567.7578 +dd 770.8029, 746.1836, 255.9902, 567.7578 + +dd 187.7175, 924.181 , 466.4362, 169.8267 +dd 187.7175, 924.181 , 466.4362, 169.8267 + +dd 651.7481, 462.4206, 396.6924, 355.8538 +dd 651.7481, 462.4206, 396.6924, 355.8538 + +dd 6.148 , 523.1443, 989.7004, 713.6646 +dd 6.148 , 523.1443, 989.7004, 713.6646 + +dd 497.5427, 657.6965, 651.0534, 778.5236 +dd 497.5427, 657.6965, 651.0534, 778.5236