Skip to content

Commit

Permalink
Merge pull request #1982 from lioncash/vadd
Browse files Browse the repository at this point in the history
VectorOps: Extend VAdd/VSub
  • Loading branch information
Sonicadvance1 authored Sep 13, 2022
2 parents 8d69f53 + b60a26f commit 0ad52b7
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 40 deletions.
22 changes: 14 additions & 8 deletions External/FEXCore/Source/Interface/Core/Interpreter/VectorOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,20 @@ DEF_OP(VAdd) {

void *Src1 = GetSrc<void*>(Data->SSAData, Op->Vector1);
void *Src2 = GetSrc<void*>(Data->SSAData, Op->Vector2);
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 a, auto b) { return a + b; };
switch (Op->Header.ElementSize) {
switch (ElementSize) {
DO_VECTOR_OP(1, uint8_t, Func)
DO_VECTOR_OP(2, uint16_t, Func)
DO_VECTOR_OP(4, uint32_t, Func)
DO_VECTOR_OP(8, uint64_t, Func)
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);
}
Expand All @@ -146,17 +149,20 @@ DEF_OP(VSub) {

void *Src1 = GetSrc<void*>(Data->SSAData, Op->Vector1);
void *Src2 = GetSrc<void*>(Data->SSAData, Op->Vector2);
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 a, auto b) { return a - b; };
switch (Op->Header.ElementSize) {
switch (ElementSize) {
DO_VECTOR_OP(1, uint8_t, Func)
DO_VECTOR_OP(2, uint16_t, Func)
DO_VECTOR_OP(4, uint32_t, Func)
DO_VECTOR_OP(8, uint64_t, Func)
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);
}
Expand Down
90 changes: 70 additions & 20 deletions External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,47 +258,97 @@ DEF_OP(VXor) {

DEF_OP(VAdd) {
auto Op = IROp->C<IR::IROp_VAdd>();
switch (Op->Header.ElementSize) {

const auto ElementSize = Op->Header.ElementSize;

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

switch (ElementSize) {
case 1: {
add(GetDst(Node).V16B(), GetSrc(Op->Vector1.ID()).V16B(), GetSrc(Op->Vector2.ID()).V16B());
break;
if (HostSupportsSVE) {
add(Dst.Z().VnB(), Vector1.Z().VnB(), Vector2.Z().VnB());
} else {
add(Dst.V16B(), Vector1.V16B(), Vector2.V16B());
}
break;
}
case 2: {
add(GetDst(Node).V8H(), GetSrc(Op->Vector1.ID()).V8H(), GetSrc(Op->Vector2.ID()).V8H());
break;
if (HostSupportsSVE) {
add(Dst.Z().VnH(), Vector1.Z().VnH(), Vector2.Z().VnH());
} else {
add(Dst.V8H(), Vector1.V8H(), Vector2.V8H());
}
break;
}
case 4: {
add(GetDst(Node).V4S(), GetSrc(Op->Vector1.ID()).V4S(), GetSrc(Op->Vector2.ID()).V4S());
break;
if (HostSupportsSVE) {
add(Dst.Z().VnS(), Vector1.Z().VnS(), Vector2.Z().VnS());
} else {
add(Dst.V4S(), Vector1.V4S(), Vector2.V4S());
}
break;
}
case 8: {
add(GetDst(Node).V2D(), GetSrc(Op->Vector1.ID()).V2D(), GetSrc(Op->Vector2.ID()).V2D());
break;
if (HostSupportsSVE) {
add(Dst.Z().VnD(), Vector1.Z().VnD(), Vector2.Z().VnD());
} else {
add(Dst.V2D(), Vector1.V2D(), Vector2.V2D());
}
break;
}
default: LOGMAN_MSG_A_FMT("Unknown Element Size: {}", Op->Header.ElementSize); break;
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
}

DEF_OP(VSub) {
auto Op = IROp->C<IR::IROp_VSub>();
switch (Op->Header.ElementSize) {

const auto ElementSize = Op->Header.ElementSize;

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

switch (ElementSize) {
case 1: {
sub(GetDst(Node).V16B(), GetSrc(Op->Vector1.ID()).V16B(), GetSrc(Op->Vector2.ID()).V16B());
break;
if (HostSupportsSVE) {
sub(Dst.Z().VnB(), Vector1.Z().VnB(), Vector2.Z().VnB());
} else {
sub(Dst.V16B(), Vector1.V16B(), Vector2.V16B());
}
break;
}
case 2: {
sub(GetDst(Node).V8H(), GetSrc(Op->Vector1.ID()).V8H(), GetSrc(Op->Vector2.ID()).V8H());
break;
if (HostSupportsSVE) {
sub(Dst.Z().VnH(), Vector1.Z().VnH(), Vector2.Z().VnH());
} else {
sub(Dst.V8H(), Vector1.V8H(), Vector2.V8H());
}
break;
}
case 4: {
sub(GetDst(Node).V4S(), GetSrc(Op->Vector1.ID()).V4S(), GetSrc(Op->Vector2.ID()).V4S());
break;
if (HostSupportsSVE) {
sub(Dst.Z().VnS(), Vector1.Z().VnS(), Vector2.Z().VnS());
} else {
sub(Dst.V4S(), Vector1.V4S(), Vector2.V4S());
}
break;
}
case 8: {
sub(GetDst(Node).V2D(), GetSrc(Op->Vector1.ID()).V2D(), GetSrc(Op->Vector2.ID()).V2D());
break;
if (HostSupportsSVE) {
sub(Dst.Z().VnD(), Vector1.Z().VnD(), Vector2.Z().VnD());
} else {
sub(Dst.V2D(), Vector1.V2D(), Vector2.V2D());
}
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
42 changes: 30 additions & 12 deletions External/FEXCore/Source/Interface/Core/JIT/x86_64/VectorOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,47 +191,65 @@ DEF_OP(VXor) {

DEF_OP(VAdd) {
auto Op = IROp->C<IR::IROp_VAdd>();
switch (Op->Header.ElementSize) {

const auto ElementSize = Op->Header.ElementSize;

const auto Dst = ToYMM(GetDst(Node));
const auto Vector1 = ToYMM(GetSrc(Op->Vector1.ID()));
const auto Vector2 = ToYMM(GetSrc(Op->Vector2.ID()));

switch (ElementSize) {
case 1: {
vpaddb(GetDst(Node), GetSrc(Op->Vector1.ID()), GetSrc(Op->Vector2.ID()));
vpaddb(Dst, Vector1, Vector2);
break;
}
case 2: {
vpaddw(GetDst(Node), GetSrc(Op->Vector1.ID()), GetSrc(Op->Vector2.ID()));
vpaddw(Dst, Vector1, Vector2);
break;
}
case 4: {
vpaddd(GetDst(Node), GetSrc(Op->Vector1.ID()), GetSrc(Op->Vector2.ID()));
vpaddd(Dst, Vector1, Vector2);
break;
}
case 8: {
vpaddq(GetDst(Node), GetSrc(Op->Vector1.ID()), GetSrc(Op->Vector2.ID()));
vpaddq(Dst, Vector1, Vector2);
break;
}
default: LOGMAN_MSG_A_FMT("Unknown Element Size: {}", Op->Header.ElementSize); break;
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
}

DEF_OP(VSub) {
auto Op = IROp->C<IR::IROp_VSub>();
switch (Op->Header.ElementSize) {

const auto ElementSize = Op->Header.ElementSize;

const auto Dst = ToYMM(GetDst(Node));
const auto Vector1 = ToYMM(GetSrc(Op->Vector1.ID()));
const auto Vector2 = ToYMM(GetSrc(Op->Vector2.ID()));

switch (ElementSize) {
case 1: {
vpsubb(GetDst(Node), GetSrc(Op->Vector1.ID()), GetSrc(Op->Vector2.ID()));
vpsubb(Dst, Vector1, Vector2);
break;
}
case 2: {
vpsubw(GetDst(Node), GetSrc(Op->Vector1.ID()), GetSrc(Op->Vector2.ID()));
vpsubw(Dst, Vector1, Vector2);
break;
}
case 4: {
vpsubd(GetDst(Node), GetSrc(Op->Vector1.ID()), GetSrc(Op->Vector2.ID()));
vpsubd(Dst, Vector1, Vector2);
break;
}
case 8: {
vpsubq(GetDst(Node), GetSrc(Op->Vector1.ID()), GetSrc(Op->Vector2.ID()));
vpsubq(Dst, Vector1, Vector2);
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 0ad52b7

Please sign in to comment.