From 5e6a3c62808de0b7da92f5947cbff5dbd59838ce Mon Sep 17 00:00:00 2001 From: Lioncache Date: Wed, 1 Mar 2023 22:25:41 -0500 Subject: [PATCH] ARMEmitter: Remove predicate implicit conversion operators Like with the vector registers, we can remove all implicit conversion operators except the ones that convert down to the base PRegister class. With this, all of the registers are now adequately constrained, so we shouldn't have any wonky implicit conversions happening anymore. --- .../Core/ArchHelpers/Arm64Emitter.cpp | 4 +-- .../Core/ArchHelpers/CodeEmitter/Registers.h | 21 -------------- .../Core/ArchHelpers/CodeEmitter/SVEOps.inl | 10 +++---- .../Interface/Core/JIT/Arm64/ALUOps.cpp | 2 +- .../Interface/Core/JIT/Arm64/VectorOps.cpp | 6 ++-- .../FEXCore/unittests/Emitter/SVE_Tests.cpp | 28 +++++++++---------- 6 files changed, 25 insertions(+), 46 deletions(-) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp b/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp index 651eb5044..5a08021a8 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp @@ -274,7 +274,7 @@ void Arm64Emitter::FillStaticRegs(bool FPRs, uint32_t GPRFillMask, uint32_t FPRF const auto Reg = SRAFPR[i]; if (((1U << Reg.Idx()) & FPRFillMask) != 0) { mov(ARMEmitter::Size::i64Bit, TMP4.R(), offsetof(Core::CpuStateFrame, State.xmm.avx.data[i][0])); - ld1b(Reg.Z(), PRED_TMP_32B, STATE.R(), TMP4.R()); + ld1b(Reg.Z(), PRED_TMP_32B.Zeroing(), STATE.R(), TMP4.R()); } } } else { @@ -374,7 +374,7 @@ void Arm64Emitter::PopDynamicRegsAndLR() { const auto Reg2 = RAFPR[i + 1]; const auto Reg3 = RAFPR[i + 2]; const auto Reg4 = RAFPR[i + 3]; - ld4b(Reg1.Z(), Reg2.Z(), Reg3.Z(), Reg4.Z(), PRED_TMP_32B, ARMEmitter::Reg::rsp); + ld4b(Reg1.Z(), Reg2.Z(), Reg3.Z(), Reg4.Z(), PRED_TMP_32B.Zeroing(), ARMEmitter::Reg::rsp); add(ARMEmitter::Size::i64Bit, ARMEmitter::Reg::rsp, ARMEmitter::Reg::rsp, 32 * 4); } } else { diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/Registers.h b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/Registers.h index 7a2edbdc0..74821a32a 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/Registers.h +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/Registers.h @@ -929,9 +929,6 @@ namespace FEXCore::ARMEmitter { return Index; } - operator PRegisterZero() const; - operator PRegisterMerge() const; - PRegisterZero Zeroing() const; PRegisterMerge Merging() const; @@ -956,7 +953,6 @@ namespace FEXCore::ARMEmitter { } operator PRegister() const; - operator PRegisterMerge() const; PRegister P() const; PRegisterMerge Merging() const; @@ -982,7 +978,6 @@ namespace FEXCore::ARMEmitter { } operator PRegister() const; - operator PRegisterZero() const; PRegister P() const; PRegisterZero Zeroing() const; @@ -996,14 +991,6 @@ namespace FEXCore::ARMEmitter { // PRegister - inline PRegister::operator PRegisterZero() const { - return PRegisterZero(Index); - } - - inline PRegister::operator PRegisterMerge() const { - return PRegisterMerge(Index); - } - inline PRegisterZero PRegister::Zeroing() const { return PRegisterZero(Idx()); } @@ -1017,10 +1004,6 @@ namespace FEXCore::ARMEmitter { return PRegister(Index); } - inline PRegisterZero::operator PRegisterMerge() const { - return PRegisterMerge(Index); - } - inline PRegister PRegisterZero::P() const { return PRegister(Idx()); } @@ -1034,10 +1017,6 @@ namespace FEXCore::ARMEmitter { return PRegisterZero(Index); } - inline PRegisterMerge::operator PRegisterZero() const { - return PRegisterZero(Index); - } - inline PRegister PRegisterMerge::P() const { return PRegister(Idx()); } diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index 52ee9f809..1a949bbfd 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -2602,7 +2602,7 @@ public: } template - void st1b(FEXCore::ARMEmitter::ZRegister zt, FEXCore::ARMEmitter::PRegisterZero pg, FEXCore::ARMEmitter::SVEMemOperand Src) { + void st1b(FEXCore::ARMEmitter::ZRegister zt, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::SVEMemOperand Src) { if (Src.MetaType.Header.MemType == FEXCore::ARMEmitter::SVEMemOperand::Type::TYPE_SCALAR_SCALAR) { st1b(zt, pg, Src.rn, Src.MetaType.ScalarScalarType.rm); } @@ -2621,7 +2621,7 @@ public: } template - void st1h(FEXCore::ARMEmitter::ZRegister zt, FEXCore::ARMEmitter::PRegisterZero pg, FEXCore::ARMEmitter::SVEMemOperand Src) { + void st1h(FEXCore::ARMEmitter::ZRegister zt, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::SVEMemOperand Src) { if (Src.MetaType.Header.MemType == FEXCore::ARMEmitter::SVEMemOperand::Type::TYPE_SCALAR_SCALAR) { st1h(zt, pg, Src.rn, Src.MetaType.ScalarScalarType.rm); } @@ -2640,7 +2640,7 @@ public: } template - void st1w(FEXCore::ARMEmitter::ZRegister zt, FEXCore::ARMEmitter::PRegisterZero pg, FEXCore::ARMEmitter::SVEMemOperand Src) { + void st1w(FEXCore::ARMEmitter::ZRegister zt, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::SVEMemOperand Src) { if (Src.MetaType.Header.MemType == FEXCore::ARMEmitter::SVEMemOperand::Type::TYPE_SCALAR_SCALAR) { st1w(zt, pg, Src.rn, Src.MetaType.ScalarScalarType.rm); } @@ -2658,7 +2658,7 @@ public: } } - void st1d(FEXCore::ARMEmitter::ZRegister zt, FEXCore::ARMEmitter::PRegisterZero pg, FEXCore::ARMEmitter::SVEMemOperand Src) { + void st1d(FEXCore::ARMEmitter::ZRegister zt, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::SVEMemOperand Src) { if (Src.MetaType.Header.MemType == FEXCore::ARMEmitter::SVEMemOperand::Type::TYPE_SCALAR_SCALAR) { st1d(zt, pg, Src.rn, Src.MetaType.ScalarScalarType.rm); } @@ -4092,7 +4092,7 @@ private: dc32(Instr); } - void SVEPropagateBreak(uint32_t opc, uint32_t op2, uint32_t op3, PRegister pd, PRegisterZero pg, PRegister pn, PRegister pm) { + void SVEPropagateBreak(uint32_t opc, uint32_t op2, uint32_t op3, PRegister pd, PRegister pg, PRegister pn, PRegister pm) { uint32_t Instr = 0b0010'0101'0000'0000'0000'0000'0000'0000; Instr |= opc << 20; Instr |= op2 << 14; diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp index c49748d94..278305e38 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp @@ -1173,7 +1173,7 @@ DEF_OP(VExtractToGPR) { // Inverting our dedicated predicate for 128-bit operations selects // all of the top lanes. We can then compact those into a temporary. const auto CompactPred = ARMEmitter::PReg::p0; - not_(CompactPred, PRED_TMP_32B, PRED_TMP_16B); + not_(CompactPred, PRED_TMP_32B.Zeroing(), PRED_TMP_16B); compact(ARMEmitter::SubRegSize::i64Bit, VTMP1.Z(), CompactPred, Vector.Z()); // Sanitize the zero-based index to work on the now-moved diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp index e91a87f4b..c8d3296a0 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp @@ -1112,7 +1112,7 @@ DEF_OP(VNot) { const auto Vector = GetVReg(Op->Vector.ID()); if (HostSupportsSVE && Is256Bit) { - not_(ARMEmitter::SubRegSize::i8Bit, Dst.Z(), PRED_TMP_32B, Vector.Z()); + not_(ARMEmitter::SubRegSize::i8Bit, Dst.Z(), PRED_TMP_32B.Merging(), Vector.Z()); } else { mvn(ARMEmitter::SubRegSize::i8Bit, Dst.Q(), Vector.Q()); } @@ -2288,10 +2288,10 @@ DEF_OP(VInsElement) { dup(SubRegSize, VTMP2.Z(), SrcVector.Z(), SrcIdx); mov(Dst.Z(), Reg.Z()); if (ElementSize == 16) { - mov(ARMEmitter::SubRegSize::i64Bit, Dst.Z(), Predicate, VTMP2.Z()); + mov(ARMEmitter::SubRegSize::i64Bit, Dst.Z(), Predicate.Merging(), VTMP2.Z()); } else { - mov(SubRegSize, Dst.Z(), Predicate, VTMP2.Z()); + mov(SubRegSize, Dst.Z(), Predicate.Merging(), VTMP2.Z()); } // Set up a label to jump over the data we inserted, so we don't try and execute it. diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index cc2f52918..0c092ecb9 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -479,20 +479,20 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer multiply-add writi } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer add/subtract vectors (predicated)") { - TEST_SINGLE(add(SubRegSize::i8Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "add z30.b, p7/m, z30.b, z28.b"); - TEST_SINGLE(add(SubRegSize::i16Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "add z30.h, p7/m, z30.h, z28.h"); - TEST_SINGLE(add(SubRegSize::i32Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "add z30.s, p7/m, z30.s, z28.s"); - TEST_SINGLE(add(SubRegSize::i64Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "add z30.d, p7/m, z30.d, z28.d"); + TEST_SINGLE(add(SubRegSize::i8Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z28), "add z30.b, p7/m, z30.b, z28.b"); + TEST_SINGLE(add(SubRegSize::i16Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z28), "add z30.h, p7/m, z30.h, z28.h"); + TEST_SINGLE(add(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z28), "add z30.s, p7/m, z30.s, z28.s"); + TEST_SINGLE(add(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z28), "add z30.d, p7/m, z30.d, z28.d"); - TEST_SINGLE(sub(SubRegSize::i8Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "sub z30.b, p7/m, z30.b, z28.b"); - TEST_SINGLE(sub(SubRegSize::i16Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "sub z30.h, p7/m, z30.h, z28.h"); - TEST_SINGLE(sub(SubRegSize::i32Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "sub z30.s, p7/m, z30.s, z28.s"); - TEST_SINGLE(sub(SubRegSize::i64Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "sub z30.d, p7/m, z30.d, z28.d"); + TEST_SINGLE(sub(SubRegSize::i8Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z28), "sub z30.b, p7/m, z30.b, z28.b"); + TEST_SINGLE(sub(SubRegSize::i16Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z28), "sub z30.h, p7/m, z30.h, z28.h"); + TEST_SINGLE(sub(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z28), "sub z30.s, p7/m, z30.s, z28.s"); + TEST_SINGLE(sub(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z28), "sub z30.d, p7/m, z30.d, z28.d"); - TEST_SINGLE(subr(SubRegSize::i8Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "subr z30.b, p7/m, z30.b, z28.b"); - TEST_SINGLE(subr(SubRegSize::i16Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "subr z30.h, p7/m, z30.h, z28.h"); - TEST_SINGLE(subr(SubRegSize::i32Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "subr z30.s, p7/m, z30.s, z28.s"); - TEST_SINGLE(subr(SubRegSize::i64Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "subr z30.d, p7/m, z30.d, z28.d"); + TEST_SINGLE(subr(SubRegSize::i8Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z28), "subr z30.b, p7/m, z30.b, z28.b"); + TEST_SINGLE(subr(SubRegSize::i16Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z28), "subr z30.h, p7/m, z30.h, z28.h"); + TEST_SINGLE(subr(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z28), "subr z30.s, p7/m, z30.s, z28.s"); + TEST_SINGLE(subr(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z28), "subr z30.d, p7/m, z30.d, z28.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer min/max/difference (predicated)") { @@ -2422,8 +2422,8 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE2 integer add/subtract narr TEST_SINGLE(rsubhnt(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, ZReg::z28), "rsubhnt z30.s, z29.d, z28.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE2 Histogram Computation") { - TEST_SINGLE(histcnt(SubRegSize::i32Bit, ZReg::z30, PReg::p6.Merging(), ZReg::z29, ZReg::z28), "histcnt z30.s, p6/z, z29.s, z28.s"); - TEST_SINGLE(histcnt(SubRegSize::i64Bit, ZReg::z30, PReg::p6.Merging(), ZReg::z29, ZReg::z28), "histcnt z30.d, p6/z, z29.d, z28.d"); + TEST_SINGLE(histcnt(SubRegSize::i32Bit, ZReg::z30, PReg::p6.Zeroing(), ZReg::z29, ZReg::z28), "histcnt z30.s, p6/z, z29.s, z28.s"); + TEST_SINGLE(histcnt(SubRegSize::i64Bit, ZReg::z30, PReg::p6.Zeroing(), ZReg::z29, ZReg::z28), "histcnt z30.d, p6/z, z29.d, z28.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE2 Histogram Computation - Segment") { TEST_SINGLE(histseg(ZReg::z30, ZReg::z29, ZReg::z28), "histseg z30.b, z29.b, z28.b");