diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp index 41b89700d..81dabe389 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp @@ -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); diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h b/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h index a02710d38..a235e74b8 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h @@ -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); diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp index 380f09217..74e237f91 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp @@ -609,6 +609,49 @@ DEF_OP(VAbs) { } } +DEF_OP(VFAbs) { + 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 = 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(); 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 { diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp index e6b88d124..8680b1722 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp @@ -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); } diff --git a/FEXCore/Source/Interface/IR/IR.json b/FEXCore/Source/Interface/IR/IR.json index 08e1c93c4..563c5e55f 100644 --- a/FEXCore/Source/Interface/IR/IR.json +++ b/FEXCore/Source/Interface/IR/IR.json @@ -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", diff --git a/unittests/InstructionCountCI/x87_f64.json b/unittests/InstructionCountCI/x87_f64.json index 7d7fe6a1f..d38a10b66 100644 --- a/unittests/InstructionCountCI/x87_f64.json +++ b/unittests/InstructionCountCI/x87_f64.json @@ -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]" ]