IR: Handle 256-bit VUnZip

Extends VUnZip to handle 256-bit vectors.
This commit is contained in:
lioncash committed 2022-10-25 15:49:02 +00:00
1 parent 2272b30a91
commit 80cf3ca6b9
3 files changed
+119 -56

No files matched your search

@@ -899,17 +899,18 @@ DEF_OP(VZip) {
}
DEF_OP(VUnZip) {
auto Op = IROp->C<IR::IROp_VUnZip>();
const auto Op = IROp->C<IR::IROp_VUnZip>();
const uint8_t OpSize = IROp->Size;
void *Src1 = GetSrc<void*>(Data->SSAData, Op->VectorLower);
void *Src2 = GetSrc<void*>(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<uint8_t*>(Tmp);
auto *Src1_d = reinterpret_cast<uint8_t*>(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);
@@ -2247,44 +2247,79 @@ DEF_OP(VZip2) {
}
DEF_OP(VUnZip) {
auto Op = IROp->C<IR::IROp_VUnZip>();
const uint8_t OpSize = IROp->Size;
if (OpSize == 8) {
switch (Op->Header.ElementSize) {
const auto Op = IROp->C<IR::IROp_VUnZip>();
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;
}
}
}
@@ -1384,24 +1384,38 @@ DEF_OP(VZip2) {
}
DEF_OP(VUnZip) {
auto Op = IROp->C<IR::IROp_VUnZip>();
const uint8_t OpSize = IROp->Size;
const auto Op = IROp->C<IR::IROp_VUnZip>();
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;
}
}
}