diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/VectorOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/VectorOps.cpp index caf9159d2..cd89e6889 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/VectorOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/VectorOps.cpp @@ -899,17 +899,18 @@ DEF_OP(VZip) { } DEF_OP(VUnZip) { - auto Op = IROp->C(); + const auto Op = IROp->C(); const uint8_t OpSize = IROp->Size; void *Src1 = GetSrc(Data->SSAData, Op->VectorLower); void *Src2 = GetSrc(Data->SSAData, Op->VectorUpper); - uint8_t Tmp[16]; - uint8_t Elements = OpSize / Op->Header.ElementSize; - unsigned Start = IROp->Op == IR::OP_VUNZIP ? 0 : 1; + uint8_t Tmp[Core::CPUState::XMM_AVX_REG_SIZE]; + const uint8_t ElementSize = Op->Header.ElementSize; + uint8_t Elements = OpSize / ElementSize; + const unsigned Start = IROp->Op == IR::OP_VUNZIP ? 0 : 1; Elements >>= 1; - switch (Op->Header.ElementSize) { + switch (ElementSize) { case 1: { auto *Dst_d = reinterpret_cast(Tmp); auto *Src1_d = reinterpret_cast(Src1); @@ -950,7 +951,9 @@ DEF_OP(VUnZip) { } break; } - default: LOGMAN_MSG_A_FMT("Unknown Element Size: {}", Op->Header.ElementSize); break; + default: + LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize); + break; } memcpy(GDP, Tmp, OpSize); diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp index 1eb6387d4..2b647b5c1 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp @@ -2247,44 +2247,79 @@ DEF_OP(VZip2) { } DEF_OP(VUnZip) { - auto Op = IROp->C(); - const uint8_t OpSize = IROp->Size; - if (OpSize == 8) { - switch (Op->Header.ElementSize) { + const auto Op = IROp->C(); + const auto OpSize = IROp->Size; + + const auto ElementSize = Op->Header.ElementSize; + const auto Is256Bit = OpSize == Core::CPUState::XMM_AVX_REG_SIZE; + + const auto Dst = GetDst(Node); + const auto VectorLower = GetSrc(Op->VectorLower.ID()); + const auto VectorUpper = GetSrc(Op->VectorUpper.ID()); + + if (HostSupportsSVE && Is256Bit) { + switch (ElementSize) { case 1: { - uzp1(GetDst(Node).V8B(), GetSrc(Op->VectorLower.ID()).V8B(), GetSrc(Op->VectorUpper.ID()).V8B()); - break; + uzp1(Dst.Z().VnB(), VectorLower.Z().VnB(), VectorUpper.Z().VnB()); + break; } case 2: { - uzp1(GetDst(Node).V4H(), GetSrc(Op->VectorLower.ID()).V4H(), GetSrc(Op->VectorUpper.ID()).V4H()); - break; + uzp1(Dst.Z().VnH(), VectorLower.Z().VnH(), VectorUpper.Z().VnH()); + break; } case 4: { - uzp1(GetDst(Node).V2S(), GetSrc(Op->VectorLower.ID()).V2S(), GetSrc(Op->VectorUpper.ID()).V2S()); - break; - } - default: LOGMAN_MSG_A_FMT("Unknown Element Size: {}", Op->Header.ElementSize); break; - } - } - else { - switch (Op->Header.ElementSize) { - case 1: { - uzp1(GetDst(Node).V16B(), GetSrc(Op->VectorLower.ID()).V16B(), GetSrc(Op->VectorUpper.ID()).V16B()); - break; - } - case 2: { - uzp1(GetDst(Node).V8H(), GetSrc(Op->VectorLower.ID()).V8H(), GetSrc(Op->VectorUpper.ID()).V8H()); - break; - } - case 4: { - uzp1(GetDst(Node).V4S(), GetSrc(Op->VectorLower.ID()).V4S(), GetSrc(Op->VectorUpper.ID()).V4S()); - break; + uzp1(Dst.Z().VnS(), VectorLower.Z().VnS(), VectorUpper.Z().VnS()); + break; } case 8: { - uzp1(GetDst(Node).V2D(), GetSrc(Op->VectorLower.ID()).V2D(), GetSrc(Op->VectorUpper.ID()).V2D()); - break; + uzp1(Dst.Z().VnD(), VectorLower.Z().VnD(), VectorUpper.Z().VnD()); + break; + } + default: + LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize); + break; + } + } else { + if (OpSize == 8) { + switch (ElementSize) { + case 1: { + uzp1(Dst.V8B(), VectorLower.V8B(), VectorUpper.V8B()); + break; + } + case 2: { + uzp1(Dst.V4H(), VectorLower.V4H(), VectorUpper.V4H()); + break; + } + case 4: { + uzp1(Dst.V2S(), VectorLower.V2S(), VectorUpper.V2S()); + break; + } + default: + LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize); + break; + } + } else { + switch (ElementSize) { + case 1: { + uzp1(Dst.V16B(), VectorLower.V16B(), VectorUpper.V16B()); + break; + } + case 2: { + uzp1(Dst.V8H(), VectorLower.V8H(), VectorUpper.V8H()); + break; + } + case 4: { + uzp1(Dst.V4S(), VectorLower.V4S(), VectorUpper.V4S()); + break; + } + case 8: { + uzp1(Dst.V2D(), VectorLower.V2D(), VectorUpper.V2D()); + break; + } + default: + LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize); + break; } - default: LOGMAN_MSG_A_FMT("Unknown Element Size: {}", Op->Header.ElementSize); break; } } } diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/VectorOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/VectorOps.cpp index 7c218fee3..59c5a0d83 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/VectorOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/VectorOps.cpp @@ -1384,24 +1384,38 @@ DEF_OP(VZip2) { } DEF_OP(VUnZip) { - auto Op = IROp->C(); - const uint8_t OpSize = IROp->Size; + const auto Op = IROp->C(); + const auto OpSize = IROp->Size; + + const auto ElementSize = Op->Header.ElementSize; + const auto Is256Bit = OpSize == Core::CPUState::XMM_AVX_REG_SIZE; + + const auto Dst = GetDst(Node); + const auto VectorLower = GetSrc(Op->VectorLower.ID()); + const auto VectorUpper = GetSrc(Op->VectorUpper.ID()); if (OpSize == 8) { LOGMAN_MSG_A_FMT("Unsupported register size on VUnZip"); } else { - switch (Op->Header.ElementSize) { + switch (ElementSize) { case 1: { // Shuffle low bits mov(rax, 0x0E'0C'0A'08'06'04'02'00); // Lower mov(rcx, 0x80'80'80'80'80'80'80'80); // Upper vmovq(xmm15, rax); pinsrq(xmm15, rcx, 1); - vpshufb(xmm14, GetSrc(Op->VectorLower.ID()), xmm15); - vpshufb(xmm13, GetSrc(Op->VectorUpper.ID()), xmm15); - // movlhps back to combine - vmovlhps(GetDst(Node), xmm14, xmm13); + if (Is256Bit) { + vinserti128(ymm15, ymm15, xmm15, 1); + vpshufb(ymm14, ToYMM(VectorLower), ymm15); + vpshufb(ymm13, ToYMM(VectorUpper), ymm15); + vpunpcklqdq(ToYMM(Dst), ymm14, ymm13); + } else { + vpshufb(xmm14, VectorLower, xmm15); + vpshufb(xmm13, VectorUpper, xmm15); + // movlhps back to combine + vmovlhps(Dst, xmm14, xmm13); + } break; } case 2: { @@ -1410,27 +1424,38 @@ DEF_OP(VUnZip) { mov(rcx, 0x80'80'80'80'80'80'80'80); // Upper vmovq(xmm15, rax); pinsrq(xmm15, rcx, 1); - vpshufb(xmm14, GetSrc(Op->VectorLower.ID()), xmm15); - vpshufb(xmm13, GetSrc(Op->VectorUpper.ID()), xmm15); - // movlhps back to combine - vmovlhps(GetDst(Node), xmm14, xmm13); + if (Is256Bit) { + vinserti128(ymm15, ymm15, xmm15, 1); + vpshufb(ymm14, ToYMM(VectorLower), ymm15); + vpshufb(ymm13, ToYMM(VectorUpper), ymm15); + vpunpcklqdq(ToYMM(Dst), ymm14, ymm13); + } else { + vpshufb(xmm14, VectorLower, xmm15); + vpshufb(xmm13, VectorUpper, xmm15); + // movlhps back to combine + vmovlhps(Dst, xmm14, xmm13); + } break; } case 4: { - vshufps(GetDst(Node), - GetSrc(Op->VectorLower.ID()), - GetSrc(Op->VectorUpper.ID()), - 0b10'00'10'00); + if (Is256Bit) { + vshufps(ToYMM(Dst), ToYMM(VectorLower), ToYMM(VectorUpper), 0b10'00'10'00); + } else { + vshufps(Dst, VectorLower, VectorUpper, 0b10'00'10'00); + } break; } case 8: { - vshufpd(GetDst(Node), - GetSrc(Op->VectorLower.ID()), - GetSrc(Op->VectorUpper.ID()), - 0b0'0); + if (Is256Bit) { + vshufpd(ToYMM(Dst), ToYMM(VectorLower), ToYMM(VectorUpper), 0b0'0); + } else { + vshufpd(Dst, VectorLower, VectorUpper, 0b0'0); + } break; } - default: LOGMAN_MSG_A_FMT("Unknown Element Size: {}", Op->Header.ElementSize); break; + default: + LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize); + break; } } }