Skip to content

Commit

Permalink
Merge pull request #1992 from lioncash/uminv
Browse files Browse the repository at this point in the history
VectorOps: Handle 256-bit VUMinV
  • Loading branch information
Sonicadvance1 committed Sep 15, 2022
2 parents 96fecfd + 95fbcd7 commit 0261ed3
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 21 deletions.
13 changes: 8 additions & 5 deletions External/FEXCore/Source/Interface/Core/Interpreter/VectorOps.cpp
Expand Up @@ -405,19 +405,22 @@ DEF_OP(VUMinV) {
const int8_t OpSize = IROp->Size;

void *Src = GetSrc<void*>(Data->SSAData, Op->Vector);
uint8_t Tmp[16];
uint8_t Tmp[32];

const uint8_t Elements = OpSize / Op->Header.ElementSize;
const uint8_t ElementSize = Op->Header.ElementSize;
const uint8_t Elements = OpSize / ElementSize;

const auto Func = [](auto current, auto a) { return std::min(current, a); };
switch (Op->Header.ElementSize) {
switch (ElementSize) {
DO_VECTOR_REDUCE_1SRC_OP(1, uint8_t, Func, ~0)
DO_VECTOR_REDUCE_1SRC_OP(2, uint16_t, Func, ~0)
DO_VECTOR_REDUCE_1SRC_OP(4, uint32_t, Func, ~0U)
DO_VECTOR_REDUCE_1SRC_OP(8, uint64_t, Func, ~0ULL)
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, Op->Header.ElementSize);
memcpy(GDP, Tmp, ElementSize);
}

DEF_OP(VURAvg) {
Expand Down
57 changes: 47 additions & 10 deletions External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp
Expand Up @@ -608,16 +608,53 @@ DEF_OP(VAddV) {

DEF_OP(VUMinV) {
auto Op = IROp->C<IR::IROp_VUMinV>();
const uint8_t OpSize = IROp->Size;
const uint8_t Elements = OpSize / Op->Header.ElementSize;
// Vector
switch (Op->Header.ElementSize) {
case 1:
case 2:
case 4:
uminv(GetDst(Node).VCast(Op->Header.ElementSize * 8, 1), GetSrc(Op->Vector.ID()).VCast(OpSize * 8, Elements));
break;
default: LOGMAN_MSG_A_FMT("Unknown Element Size: {}", Op->Header.ElementSize); break;

const auto OpSize = IROp->Size;
const auto ElementSize = Op->Header.ElementSize;
const auto Elements = OpSize / ElementSize;

const auto Dst = GetDst(Node);
const auto Vector = GetSrc(Op->Vector.ID());

if (HostSupportsSVE) {
LOGMAN_THROW_AA_FMT(OpSize == 16 || OpSize == 32,
"Unsupported vector length: {}", OpSize);

if (OpSize == 16) {
ptrue(p0.VnB(), SVE_VL16);
} else {
ptrue(p0.VnB(), SVE_VL32);
}

switch (ElementSize) {
case 1:
uminv(Dst.B(), p0, Vector.Z().VnB());
break;
case 2:
uminv(Dst.H(), p0, Vector.Z().VnH());
break;
case 4:
uminv(Dst.S(), p0, Vector.Z().VnS());
break;
case 8:
uminv(Dst.D(), p0, Vector.Z().VnD());
break;
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
return;
}
} else {
// Vector
switch (ElementSize) {
case 1:
case 2:
case 4:
uminv(Dst.VCast(ElementSize * 8, 1), Vector.VCast(OpSize * 8, Elements));
break;
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
}
}

Expand Down
34 changes: 28 additions & 6 deletions External/FEXCore/Source/Interface/Core/JIT/x86_64/VectorOps.cpp
Expand Up @@ -453,17 +453,39 @@ DEF_OP(VAddV) {
DEF_OP(VUMinV) {
auto Op = IROp->C<IR::IROp_VUMinV>();

auto Src = GetSrc(Op->Vector.ID());
auto Dest = GetDst(Node);
switch (Op->Header.ElementSize) {
const auto OpSize = Op->Header.Size;
const auto ElementSize = Op->Header.ElementSize;

LOGMAN_THROW_AA_FMT(OpSize == 16 || OpSize == 32,
"Can't handle a vector of size: {}", OpSize);

const auto Src = GetSrc(Op->Vector.ID());
const auto Dest = GetDst(Node);

switch (ElementSize) {
case 2: {
phminposuw(Dest, Src);
if (OpSize == 32) {
// vphminposuw, unfortunately, doesn't traverse the entire
// 256-bit ymm register (it just sets the top 128 bits to zero)
// so we pull the top 128 bits down into its own vector,
// get the horizontal minimum in both vectors, then
// take the minimum between the two.
vextractf128(xmm15, ToYMM(Src), 1);
vphminposuw(xmm15, xmm15);
vphminposuw(xmm14, Src);
vpminuw(Dest, xmm14, xmm15);
} else {
vphminposuw(Dest, Src);
}

// Extract the upper bits which are zero, overwriting position
pextrw(eax, Dest, 2);
pinsrw(Dest, eax, 1);
break;
break;
}
default: LOGMAN_MSG_A_FMT("Unknown Element Size: {}", Op->Header.ElementSize); break;
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
}

Expand Down

0 comments on commit 0261ed3

Please sign in to comment.