Merge pull request #3173 from CallumDev/x87f64-fabs

X87F64: Implement FABS with vector instruction
This commit is contained in:
Ryan Houdek authored and GitHub committed 2023-10-01 01:54:11 -07:00
commit 3a25dd6d2b
6 files changed
+53 -27

No files matched your search

@@ -969,6 +969,7 @@ CPUBackend::CompiledCode Arm64JITCore::CompileCode(uint64_t Entry,
REGISTER_OP(VUMINV, VUMinV);
REGISTER_OP(VURAVG, VURAvg);
REGISTER_OP(VABS, VAbs);
REGISTER_OP(VFABS, VFAbs);
REGISTER_OP(VPOPCOUNT, VPopcount);
REGISTER_OP(VFADD, VFAdd);
REGISTER_OP(VFADDP, VFAddP);
@@ -399,6 +399,7 @@ private:
DEF_OP(VUMinV);
DEF_OP(VURAvg);
DEF_OP(VAbs);
DEF_OP(VFAbs);
DEF_OP(VPopcount);
DEF_OP(VFAdd);
DEF_OP(VFAddP);
@@ -609,6 +609,49 @@ DEF_OP(VAbs) {
}
}
DEF_OP(VFAbs) {
const auto Op = IROp->C<IR::IROp_VFAbs>();
const auto OpSize = IROp->Size;
const auto ElementSize = Op->Header.ElementSize;
const auto Is256Bit = OpSize == Core::CPUState::XMM_AVX_REG_SIZE;
const auto Dst = GetVReg(Node);
const auto Src = GetVReg(Op->Vector.ID());
LOGMAN_THROW_AA_FMT(ElementSize == 2 || ElementSize == 4 || ElementSize == 8, "Invalid size");
const auto SubRegSize =
ElementSize == 2 ? ARMEmitter::SubRegSize::i16Bit :
ElementSize == 4 ? ARMEmitter::SubRegSize::i32Bit :
ElementSize == 8 ? ARMEmitter::SubRegSize::i64Bit : ARMEmitter::SubRegSize::i8Bit;
if (HostSupportsSVE256 && Is256Bit) {
fabs(SubRegSize, Dst.Z(), PRED_TMP_32B.Merging(), Src.Z());
} else {
if (ElementSize == OpSize) {
switch (ElementSize) {
case 2: {
fabs(Dst.H(), Src.H());
break;
}
case 4: {
fabs(Dst.S(), Src.S());
break;
}
case 8: {
fabs(Dst.D(), Src.D());
break;
}
default:
break;
}
} else {
// Vector
fabs(SubRegSize, Dst.Q(), Src.Q());
}
}
}
DEF_OP(VPopcount) {
const auto Op = IROp->C<IR::IROp_VPopcount>();
const auto OpSize = IROp->Size;
@@ -676,7 +719,6 @@ DEF_OP(VFAdd) {
break;
}
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -759,7 +801,6 @@ DEF_OP(VFSub) {
break;
}
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -804,7 +845,6 @@ DEF_OP(VFMul) {
break;
}
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -861,7 +901,6 @@ DEF_OP(VFDiv) {
break;
}
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -940,7 +979,6 @@ DEF_OP(VFMin) {
break;
}
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -1020,7 +1058,6 @@ DEF_OP(VFMax) {
break;
}
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -1084,7 +1121,6 @@ DEF_OP(VFRecp) {
break;
}
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -1131,7 +1167,6 @@ DEF_OP(VFSqrt) {
break;
}
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -1182,7 +1217,6 @@ DEF_OP(VFRSqrt) {
break;
}
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -1304,7 +1338,6 @@ DEF_OP(VUMin) {
break;
}
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
}
@@ -1356,7 +1389,6 @@ DEF_OP(VSMin) {
break;
}
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
}
@@ -1408,7 +1440,6 @@ DEF_OP(VUMax) {
break;
}
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
}
@@ -1460,7 +1491,6 @@ DEF_OP(VSMax) {
break;
}
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
}
@@ -1938,7 +1968,6 @@ DEF_OP(VFCMPEQ) {
fcmeq(SubRegSize.Scalar, Dst, Vector1, Vector2);
break;
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -1985,7 +2014,6 @@ DEF_OP(VFCMPNEQ) {
fcmeq(SubRegSize.Scalar, Dst, Vector1, Vector2);
break;
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
mvn(ARMEmitter::SubRegSize::i8Bit, Dst.D(), Dst.D());
@@ -2034,7 +2062,6 @@ DEF_OP(VFCMPLT) {
fcmgt(SubRegSize.Scalar, Dst, Vector2, Vector1);
break;
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -2081,7 +2108,6 @@ DEF_OP(VFCMPGT) {
fcmgt(SubRegSize.Scalar, Dst, Vector1, Vector2);
break;
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -2128,7 +2154,6 @@ DEF_OP(VFCMPLE) {
fcmge(SubRegSize.Scalar, Dst, Vector2, Vector1);
break;
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -2184,7 +2209,6 @@ DEF_OP(VFCMPORD) {
orr(Dst.D(), VTMP1.D(), VTMP2.D());
break;
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -2240,7 +2264,6 @@ DEF_OP(VFCMPUNO) {
mvn(ARMEmitter::SubRegSize::i8Bit, Dst.D(), Dst.D());
break;
default:
LOGMAN_MSG_A_FMT("Unknown Element Size: {}", ElementSize);
break;
}
} else {
@@ -589,9 +589,7 @@ void OpDispatchBuilder::FCHSF64(OpcodeArgs) {
void OpDispatchBuilder::FABSF64(OpcodeArgs) {
auto top = GetX87Top();
auto a = _LoadContextIndexed(top, 8, MMBaseOffset(), 16, FPRClass);
auto b = _VCastFromGPR(8, 8, _Constant(0x7fffffffffffffff));
auto result = _VAnd(8, 8, a, b);
auto result = _VFAbs(8, 8, a);
// Write to ST[TOP]
_StoreContextIndexed(result, top, 8, MMBaseOffset(), 16, FPRClass);
}
+5
View File
@@ -1331,6 +1331,11 @@
"DestSize": "RegisterSize",
"NumElements": "RegisterSize / ElementSize"
},
"FPR = VFAbs u8:#RegisterSize, u8:#ElementSize, FPR:$Vector": {
"DestSize": "RegisterSize",
"NumElements": "RegisterSize / ElementSize"
},
"FPR = VFNeg u8:#RegisterSize, u8:#ElementSize, FPR:$Vector": {
"DestSize": "RegisterSize",
+2 -4
View File
@@ -2285,7 +2285,7 @@
]
},
"fabs": {
"ExpectedInstructionCount": 8,
"ExpectedInstructionCount": 6,
"Optimal": "No",
"Comment": [
"0xd9 11b 0xe1 /4"
@@ -2294,9 +2294,7 @@
"ldrb w20, [x28, #747]",
"add x0, x28, x20, lsl #4",
"ldr d2, [x0, #752]",
"orr x21, xzr, #0x7fffffffffffffff",
"fmov d3, x21",
"and v2.16b, v2.16b, v3.16b",
"fabs d2, d2",
"add x0, x28, x20, lsl #4",
"str d2, [x0, #752]"
]