diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index 38e6ae8ed3..fe6acaa28e 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -144,8 +144,8 @@ void JitArm64::Shutdown() void JitArm64::FallBackToInterpreter(UGeckoInstruction inst) { FlushCarry(); - gpr.Flush(FlushMode::FLUSH_ALL, js.op); - fpr.Flush(FlushMode::FLUSH_ALL, js.op); + gpr.Flush(FlushMode::All, js.op); + fpr.Flush(FlushMode::All, js.op); if (js.op->opinfo->flags & FL_ENDBLOCK) { @@ -198,8 +198,8 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst) SwitchToFarCode(); SetJumpTarget(handleException); - gpr.Flush(FLUSH_MAINTAIN_STATE); - fpr.Flush(FLUSH_MAINTAIN_STATE); + gpr.Flush(FlushMode::MaintainState); + fpr.Flush(FlushMode::MaintainState); WriteExceptionExit(js.compilerPC); @@ -212,8 +212,8 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst) void JitArm64::HLEFunction(u32 hook_index) { FlushCarry(); - gpr.Flush(FlushMode::FLUSH_ALL); - fpr.Flush(FlushMode::FLUSH_ALL); + gpr.Flush(FlushMode::All); + fpr.Flush(FlushMode::All); MOVI2R(W0, js.compilerPC); MOVI2R(W1, hook_index); @@ -731,8 +731,8 @@ void JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) TST(W30, 23, 2); B(CC_EQ, done_here); - gpr.Flush(FLUSH_MAINTAIN_STATE); - fpr.Flush(FLUSH_MAINTAIN_STATE); + gpr.Flush(FlushMode::MaintainState); + fpr.Flush(FlushMode::MaintainState); WriteExceptionExit(js.compilerPC, true); SwitchToNearCode(); SetJumpTarget(exit); @@ -763,8 +763,8 @@ void JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) B(CC_EQ, done_here); gpr.Unlock(WA); - gpr.Flush(FLUSH_MAINTAIN_STATE); - fpr.Flush(FLUSH_MAINTAIN_STATE); + gpr.Flush(FlushMode::MaintainState); + fpr.Flush(FlushMode::MaintainState); WriteExceptionExit(js.compilerPC, true); SwitchToNearCode(); SetJumpTarget(NoExtException); @@ -787,8 +787,8 @@ void JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) SwitchToFarCode(); SetJumpTarget(far_addr); - gpr.Flush(FLUSH_MAINTAIN_STATE); - fpr.Flush(FLUSH_MAINTAIN_STATE); + gpr.Flush(FlushMode::MaintainState); + fpr.Flush(FlushMode::MaintainState); LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(Exceptions)); ORR(WA, WA, 26, 0); // EXCEPTION_FPU_UNAVAILABLE @@ -807,8 +807,8 @@ void JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) if (SConfig::GetInstance().bJITRegisterCacheOff) { - gpr.Flush(FLUSH_ALL); - fpr.Flush(FLUSH_ALL); + gpr.Flush(FlushMode::All); + fpr.Flush(FlushMode::All); FlushCarry(); } @@ -833,8 +833,8 @@ void JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) if (code_block.m_broken) { - gpr.Flush(FLUSH_ALL); - fpr.Flush(FLUSH_ALL); + gpr.Flush(FlushMode::All); + fpr.Flush(FlushMode::All); WriteExit(nextPC); } diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp index a4150d86d7..e256042f41 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp @@ -19,8 +19,8 @@ void JitArm64::sc(UGeckoInstruction inst) INSTRUCTION_START JITDISABLE(bJITBranchOff); - gpr.Flush(FlushMode::FLUSH_ALL); - fpr.Flush(FlushMode::FLUSH_ALL); + gpr.Flush(FlushMode::All); + fpr.Flush(FlushMode::All); ARM64Reg WA = gpr.GetReg(); @@ -38,8 +38,8 @@ void JitArm64::rfi(UGeckoInstruction inst) INSTRUCTION_START JITDISABLE(bJITBranchOff); - gpr.Flush(FlushMode::FLUSH_ALL); - fpr.Flush(FlushMode::FLUSH_ALL); + gpr.Flush(FlushMode::All); + fpr.Flush(FlushMode::All); // See Interpreter rfi for details const u32 mask = 0x87C0FFFF; @@ -96,8 +96,8 @@ void JitArm64::bx(UGeckoInstruction inst) return; } - gpr.Flush(FlushMode::FLUSH_ALL); - fpr.Flush(FlushMode::FLUSH_ALL); + gpr.Flush(FlushMode::All); + fpr.Flush(FlushMode::All); if (js.op->branchIsIdleLoop) { @@ -154,8 +154,8 @@ void JitArm64::bcx(UGeckoInstruction inst) } gpr.Unlock(WA); - gpr.Flush(FlushMode::FLUSH_MAINTAIN_STATE); - fpr.Flush(FlushMode::FLUSH_MAINTAIN_STATE); + gpr.Flush(FlushMode::MaintainState); + fpr.Flush(FlushMode::MaintainState); if (js.op->branchIsIdleLoop) { @@ -183,8 +183,8 @@ void JitArm64::bcx(UGeckoInstruction inst) if (!analyzer.HasOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE)) { - gpr.Flush(FlushMode::FLUSH_ALL); - fpr.Flush(FlushMode::FLUSH_ALL); + gpr.Flush(FlushMode::All); + fpr.Flush(FlushMode::All); WriteExit(js.compilerPC + 4); } } @@ -206,8 +206,8 @@ void JitArm64::bcctrx(UGeckoInstruction inst) // BO_2 == 1z1zz -> b always // NPC = CTR & 0xfffffffc; - gpr.Flush(FlushMode::FLUSH_ALL); - fpr.Flush(FlushMode::FLUSH_ALL); + gpr.Flush(FlushMode::All); + fpr.Flush(FlushMode::All); if (inst.LK_3) { @@ -275,8 +275,8 @@ void JitArm64::bclrx(UGeckoInstruction inst) gpr.Unlock(WB); } - gpr.Flush(conditional ? FlushMode::FLUSH_MAINTAIN_STATE : FlushMode::FLUSH_ALL); - fpr.Flush(conditional ? FlushMode::FLUSH_MAINTAIN_STATE : FlushMode::FLUSH_ALL); + gpr.Flush(conditional ? FlushMode::MaintainState : FlushMode::All); + fpr.Flush(conditional ? FlushMode::MaintainState : FlushMode::All); if (js.op->branchIsIdleLoop) { @@ -305,8 +305,8 @@ void JitArm64::bclrx(UGeckoInstruction inst) if (!analyzer.HasOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE)) { - gpr.Flush(FlushMode::FLUSH_ALL); - fpr.Flush(FlushMode::FLUSH_ALL); + gpr.Flush(FlushMode::All); + fpr.Flush(FlushMode::All); WriteExit(js.compilerPC + 4); } } diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp index 1b3c7d9d55..8a4eddaf5e 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp @@ -39,9 +39,9 @@ void JitArm64::fp_arith(UGeckoInstruction inst) if (packed) { - RegType type = inputs_are_singles ? REG_REG_SINGLE : REG_REG; - u8 size = inputs_are_singles ? 32 : 64; - ARM64Reg (*reg_encoder)(ARM64Reg) = inputs_are_singles ? EncodeRegToDouble : EncodeRegToQuad; + const RegType type = inputs_are_singles ? RegType::Single : RegType::Register; + const u8 size = inputs_are_singles ? 32 : 64; + const auto reg_encoder = inputs_are_singles ? EncodeRegToDouble : EncodeRegToQuad; VA = reg_encoder(fpr.R(a, type)); if (use_b) @@ -71,10 +71,12 @@ void JitArm64::fp_arith(UGeckoInstruction inst) } else { - RegType type = (inputs_are_singles && single) ? REG_LOWER_PAIR_SINGLE : REG_LOWER_PAIR; - RegType type_out = single ? (inputs_are_singles ? REG_DUP_SINGLE : REG_DUP) : REG_LOWER_PAIR; - ARM64Reg (*reg_encoder)(ARM64Reg) = - (inputs_are_singles && single) ? EncodeRegToSingle : EncodeRegToDouble; + const RegType type = + (inputs_are_singles && single) ? RegType::LowerPairSingle : RegType::LowerPair; + const RegType type_out = + single ? (inputs_are_singles ? RegType::DuplicatedSingle : RegType::Duplicated) : + RegType::LowerPair; + const auto reg_encoder = (inputs_are_singles && single) ? EncodeRegToSingle : EncodeRegToDouble; VA = reg_encoder(fpr.R(a, type)); if (use_b) @@ -125,8 +127,9 @@ void JitArm64::fp_logic(UGeckoInstruction inst) JITDISABLE(bJITFloatingPointOff); FALLBACK_IF(inst.Rc); - u32 b = inst.FB, d = inst.FD; - u32 op10 = inst.SUBOP10; + const u32 b = inst.FB; + const u32 d = inst.FD; + const u32 op10 = inst.SUBOP10; bool packed = inst.OPCD == 4; @@ -134,16 +137,16 @@ void JitArm64::fp_logic(UGeckoInstruction inst) if (op10 == 72 && b == d) return; - bool single = fpr.IsSingle(b, !packed); - u8 size = single ? 32 : 64; + const bool single = fpr.IsSingle(b, !packed); + const u8 size = single ? 32 : 64; if (packed) { - RegType type = single ? REG_REG_SINGLE : REG_REG; - ARM64Reg (*reg_encoder)(ARM64Reg) = single ? EncodeRegToDouble : EncodeRegToQuad; + const RegType type = single ? RegType::Single : RegType::Register; + const auto reg_encoder = single ? EncodeRegToDouble : EncodeRegToQuad; - ARM64Reg VB = reg_encoder(fpr.R(b, type)); - ARM64Reg VD = reg_encoder(fpr.RW(d, type)); + const ARM64Reg VB = reg_encoder(fpr.R(b, type)); + const ARM64Reg VD = reg_encoder(fpr.RW(d, type)); switch (op10) { @@ -167,11 +170,11 @@ void JitArm64::fp_logic(UGeckoInstruction inst) } else { - RegType type = single ? REG_LOWER_PAIR_SINGLE : REG_LOWER_PAIR; - ARM64Reg (*reg_encoder)(ARM64Reg) = single ? EncodeRegToSingle : EncodeRegToDouble; + const RegType type = single ? RegType::LowerPairSingle : RegType::LowerPair; + const auto reg_encoder = single ? EncodeRegToSingle : EncodeRegToDouble; - ARM64Reg VB = fpr.R(b, type); - ARM64Reg VD = fpr.RW(d, type); + const ARM64Reg VB = fpr.R(b, type); + const ARM64Reg VD = fpr.RW(d, type); switch (op10) { @@ -201,26 +204,29 @@ void JitArm64::fselx(UGeckoInstruction inst) JITDISABLE(bJITFloatingPointOff); FALLBACK_IF(inst.Rc); - u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD; + const u32 a = inst.FA; + const u32 b = inst.FB; + const u32 c = inst.FC; + const u32 d = inst.FD; if (fpr.IsSingle(a, true)) { - ARM64Reg VA = fpr.R(a, REG_LOWER_PAIR_SINGLE); + const ARM64Reg VA = fpr.R(a, RegType::LowerPairSingle); m_float_emit.FCMPE(EncodeRegToSingle(VA)); } else { - ARM64Reg VA = fpr.R(a, REG_LOWER_PAIR); + const ARM64Reg VA = fpr.R(a, RegType::LowerPair); m_float_emit.FCMPE(EncodeRegToDouble(VA)); } - bool single = fpr.IsSingle(b, true) && fpr.IsSingle(c, true); - RegType type = single ? REG_LOWER_PAIR_SINGLE : REG_LOWER_PAIR; - ARM64Reg (*reg_encoder)(ARM64Reg) = single ? EncodeRegToSingle : EncodeRegToDouble; + const bool single = fpr.IsSingle(b, true) && fpr.IsSingle(c, true); + const RegType type = single ? RegType::LowerPairSingle : RegType::LowerPair; + const auto reg_encoder = single ? EncodeRegToSingle : EncodeRegToDouble; - ARM64Reg VB = fpr.R(b, type); - ARM64Reg VC = fpr.R(c, type); - ARM64Reg VD = fpr.RW(d, type); + const ARM64Reg VB = fpr.R(b, type); + const ARM64Reg VC = fpr.R(c, type); + const ARM64Reg VD = fpr.RW(d, type); m_float_emit.FCSEL(reg_encoder(VD), reg_encoder(VC), reg_encoder(VB), CC_GE); } @@ -232,21 +238,22 @@ void JitArm64::frspx(UGeckoInstruction inst) FALLBACK_IF(inst.Rc); FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); - u32 b = inst.FB, d = inst.FD; + const u32 b = inst.FB; + const u32 d = inst.FD; if (fpr.IsSingle(b, true)) { // Source is already in single precision, so no need to do anything but to copy to PSR1. - ARM64Reg VB = fpr.R(b, REG_LOWER_PAIR_SINGLE); - ARM64Reg VD = fpr.RW(d, REG_DUP_SINGLE); + const ARM64Reg VB = fpr.R(b, RegType::LowerPairSingle); + const ARM64Reg VD = fpr.RW(d, RegType::DuplicatedSingle); if (b != d) m_float_emit.FMOV(EncodeRegToSingle(VD), EncodeRegToSingle(VB)); } else { - ARM64Reg VB = fpr.R(b, REG_LOWER_PAIR); - ARM64Reg VD = fpr.RW(d, REG_DUP_SINGLE); + const ARM64Reg VB = fpr.R(b, RegType::LowerPair); + const ARM64Reg VD = fpr.RW(d, RegType::DuplicatedSingle); m_float_emit.FCVT(32, 64, EncodeRegToDouble(VD), EncodeRegToDouble(VB)); } @@ -258,18 +265,19 @@ void JitArm64::fcmpX(UGeckoInstruction inst) JITDISABLE(bJITFloatingPointOff); FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); - u32 a = inst.FA, b = inst.FB; - int crf = inst.CRFD; + const u32 a = inst.FA; + const u32 b = inst.FB; + const int crf = inst.CRFD; - bool singles = fpr.IsSingle(a, true) && fpr.IsSingle(b, true); - RegType type = singles ? REG_LOWER_PAIR_SINGLE : REG_LOWER_PAIR; - ARM64Reg (*reg_encoder)(ARM64Reg) = singles ? EncodeRegToSingle : EncodeRegToDouble; + const bool singles = fpr.IsSingle(a, true) && fpr.IsSingle(b, true); + const RegType type = singles ? RegType::LowerPairSingle : RegType::LowerPair; + const auto reg_encoder = singles ? EncodeRegToSingle : EncodeRegToDouble; - ARM64Reg VA = reg_encoder(fpr.R(a, type)); - ARM64Reg VB = reg_encoder(fpr.R(b, type)); + const ARM64Reg VA = reg_encoder(fpr.R(a, type)); + const ARM64Reg VB = reg_encoder(fpr.R(b, type)); gpr.BindCRToRegister(crf, false); - ARM64Reg XA = gpr.CR(crf); + const ARM64Reg XA = gpr.CR(crf); FixupBranch pNaN, pLesser, pGreater; FixupBranch continue1, continue2, continue3; @@ -320,14 +328,15 @@ void JitArm64::fctiwzx(UGeckoInstruction inst) JITDISABLE(bJITFloatingPointOff); FALLBACK_IF(inst.Rc); - u32 b = inst.FB, d = inst.FD; + const u32 b = inst.FB; + const u32 d = inst.FD; - bool single = fpr.IsSingle(b, true); + const bool single = fpr.IsSingle(b, true); - ARM64Reg VB = fpr.R(b, single ? REG_LOWER_PAIR_SINGLE : REG_LOWER_PAIR); - ARM64Reg VD = fpr.RW(d); + const ARM64Reg VB = fpr.R(b, single ? RegType::LowerPairSingle : RegType::LowerPair); + const ARM64Reg VD = fpr.RW(d); - ARM64Reg V0 = fpr.GetReg(); + const ARM64Reg V0 = fpr.GetReg(); // Generate 0xFFF8000000000000ULL m_float_emit.MOVI(64, EncodeRegToDouble(V0), 0xFFFF000000000000ULL); @@ -339,7 +348,7 @@ void JitArm64::fctiwzx(UGeckoInstruction inst) } else { - ARM64Reg V1 = gpr.GetReg(); + const ARM64Reg V1 = gpr.GetReg(); m_float_emit.FCVTS(V1, EncodeRegToDouble(VB), RoundingMode::Z); m_float_emit.FMOV(EncodeRegToSingle(VD), V1); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp index b158560cb2..7a7f044b94 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp @@ -75,12 +75,13 @@ void JitArm64::lfXX(UGeckoInstruction inst) u32 imm_addr = 0; bool is_immediate = false; - RegType type = !!(flags & BackPatchInfo::FLAG_SIZE_F64) ? REG_LOWER_PAIR : REG_DUP_SINGLE; + const RegType type = + (flags & BackPatchInfo::FLAG_SIZE_F64) != 0 ? RegType::LowerPair : RegType::DuplicatedSingle; gpr.Lock(W0, W30); fpr.Lock(Q0); - ARM64Reg VD = fpr.RW(inst.FD, type); + const ARM64Reg VD = fpr.RW(inst.FD, type); ARM64Reg addr_reg = W0; if (update) @@ -244,9 +245,9 @@ void JitArm64::stfXX(UGeckoInstruction inst) gpr.Lock(W0, W1, W30); fpr.Lock(Q0); - bool single = (flags & BackPatchInfo::FLAG_SIZE_F32) && fpr.IsSingle(inst.FS, true); + const bool single = (flags & BackPatchInfo::FLAG_SIZE_F32) && fpr.IsSingle(inst.FS, true); - ARM64Reg V0 = fpr.R(inst.FS, single ? REG_LOWER_PAIR_SINGLE : REG_LOWER_PAIR); + const ARM64Reg V0 = fpr.R(inst.FS, single ? RegType::LowerPairSingle : RegType::LowerPair); if (single) { diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStorePaired.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStorePaired.cpp index f6a63ee2e6..8f386481fc 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStorePaired.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStorePaired.cpp @@ -31,16 +31,16 @@ void JitArm64::psq_l(UGeckoInstruction inst) // X2 is a temporary // Q0 is the return register // Q1 is a temporary - bool update = inst.OPCD == 57; - s32 offset = inst.SIMM_12; + const bool update = inst.OPCD == 57; + const s32 offset = inst.SIMM_12; gpr.Lock(W0, W1, W2, W30); fpr.Lock(Q0, Q1); - ARM64Reg arm_addr = gpr.R(inst.RA); - ARM64Reg scale_reg = W0; - ARM64Reg addr_reg = W1; - ARM64Reg type_reg = W2; + const ARM64Reg arm_addr = gpr.R(inst.RA); + constexpr ARM64Reg scale_reg = W0; + constexpr ARM64Reg addr_reg = W1; + constexpr ARM64Reg type_reg = W2; ARM64Reg VS; if (inst.RA || update) // Always uses the register on update @@ -57,13 +57,13 @@ void JitArm64::psq_l(UGeckoInstruction inst) if (update) { - gpr.BindToRegister(inst.RA, REG_REG); + gpr.BindToRegister(inst.RA, true); MOV(arm_addr, addr_reg); } if (js.assumeNoPairedQuantize) { - VS = fpr.RW(inst.RS, REG_REG_SINGLE); + VS = fpr.RW(inst.RS, RegType::Single); if (!inst.W) { ADD(EncodeRegTo64(addr_reg), EncodeRegTo64(addr_reg), MEM_REG); @@ -85,7 +85,7 @@ void JitArm64::psq_l(UGeckoInstruction inst) LDR(X30, X30, ArithOption(EncodeRegTo64(type_reg), true)); BLR(X30); - VS = fpr.RW(inst.RS, REG_REG_SINGLE); + VS = fpr.RW(inst.RS, RegType::Single); m_float_emit.ORR(EncodeRegToDouble(VS), D0, D0); } @@ -113,20 +113,20 @@ void JitArm64::psq_st(UGeckoInstruction inst) // X1 is the address // Q0 is the store register - bool update = inst.OPCD == 61; - s32 offset = inst.SIMM_12; + const bool update = inst.OPCD == 61; + const s32 offset = inst.SIMM_12; gpr.Lock(W0, W1, W2, W30); fpr.Lock(Q0, Q1); - bool single = fpr.IsSingle(inst.RS); + const bool single = fpr.IsSingle(inst.RS); - ARM64Reg arm_addr = gpr.R(inst.RA); - ARM64Reg VS = fpr.R(inst.RS, single ? REG_REG_SINGLE : REG_REG); + const ARM64Reg arm_addr = gpr.R(inst.RA); + const ARM64Reg VS = fpr.R(inst.RS, single ? RegType::Single : RegType::Register); - ARM64Reg scale_reg = W0; - ARM64Reg addr_reg = W1; - ARM64Reg type_reg = W2; + constexpr ARM64Reg scale_reg = W0; + constexpr ARM64Reg addr_reg = W1; + constexpr ARM64Reg type_reg = W2; BitSet32 gprs_in_use = gpr.GetCallerSavedUsed(); BitSet32 fprs_in_use = fpr.GetCallerSavedUsed(); @@ -149,7 +149,7 @@ void JitArm64::psq_st(UGeckoInstruction inst) if (update) { - gpr.BindToRegister(inst.RA, REG_REG); + gpr.BindToRegister(inst.RA, true); MOV(arm_addr, addr_reg); } diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Paired.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Paired.cpp index 2c5fe6c9f3..faa58e6ad0 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Paired.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Paired.cpp @@ -22,16 +22,18 @@ void JitArm64::ps_mergeXX(UGeckoInstruction inst) JITDISABLE(bJITPairedOff); FALLBACK_IF(inst.Rc); - u32 a = inst.FA, b = inst.FB, d = inst.FD; + const u32 a = inst.FA; + const u32 b = inst.FB; + const u32 d = inst.FD; - bool singles = fpr.IsSingle(a) && fpr.IsSingle(b); - RegType type = singles ? REG_REG_SINGLE : REG_REG; - u8 size = singles ? 32 : 64; - ARM64Reg (*reg_encoder)(ARM64Reg) = singles ? EncodeRegToDouble : EncodeRegToQuad; + const bool singles = fpr.IsSingle(a) && fpr.IsSingle(b); + const RegType type = singles ? RegType::Single : RegType::Register; + const u8 size = singles ? 32 : 64; + const auto reg_encoder = singles ? EncodeRegToDouble : EncodeRegToQuad; - ARM64Reg VA = fpr.R(a, type); - ARM64Reg VB = fpr.R(b, type); - ARM64Reg VD = fpr.RW(d, type); + const ARM64Reg VA = fpr.R(a, type); + const ARM64Reg VB = fpr.R(b, type); + const ARM64Reg VD = fpr.RW(d, type); switch (inst.SUBOP10) { @@ -73,18 +75,20 @@ void JitArm64::ps_mulsX(UGeckoInstruction inst) FALLBACK_IF(inst.Rc); FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); - u32 a = inst.FA, c = inst.FC, d = inst.FD; + const u32 a = inst.FA; + const u32 c = inst.FC; + const u32 d = inst.FD; - bool upper = inst.SUBOP5 == 13; + const bool upper = inst.SUBOP5 == 13; - bool singles = fpr.IsSingle(a) && fpr.IsSingle(c); - RegType type = singles ? REG_REG_SINGLE : REG_REG; - u8 size = singles ? 32 : 64; - ARM64Reg (*reg_encoder)(ARM64Reg) = singles ? EncodeRegToDouble : EncodeRegToQuad; + const bool singles = fpr.IsSingle(a) && fpr.IsSingle(c); + const RegType type = singles ? RegType::Single : RegType::Register; + const u8 size = singles ? 32 : 64; + const auto reg_encoder = singles ? EncodeRegToDouble : EncodeRegToQuad; - ARM64Reg VA = fpr.R(a, type); - ARM64Reg VC = fpr.R(c, type); - ARM64Reg VD = fpr.RW(d, type); + const ARM64Reg VA = fpr.R(a, type); + const ARM64Reg VC = fpr.R(c, type); + const ARM64Reg VD = fpr.RW(d, type); m_float_emit.FMUL(size, reg_encoder(VD), reg_encoder(VA), reg_encoder(VC), upper ? 1 : 0); @@ -98,18 +102,21 @@ void JitArm64::ps_maddXX(UGeckoInstruction inst) FALLBACK_IF(inst.Rc); FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); - u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD; - u32 op5 = inst.SUBOP5; + const u32 a = inst.FA; + const u32 b = inst.FB; + const u32 c = inst.FC; + const u32 d = inst.FD; + const u32 op5 = inst.SUBOP5; - bool singles = fpr.IsSingle(a) && fpr.IsSingle(b) && fpr.IsSingle(c); - RegType type = singles ? REG_REG_SINGLE : REG_REG; - u8 size = singles ? 32 : 64; - ARM64Reg (*reg_encoder)(ARM64Reg) = singles ? EncodeRegToDouble : EncodeRegToQuad; + const bool singles = fpr.IsSingle(a) && fpr.IsSingle(b) && fpr.IsSingle(c); + const RegType type = singles ? RegType::Single : RegType::Register; + const u8 size = singles ? 32 : 64; + const auto reg_encoder = singles ? EncodeRegToDouble : EncodeRegToQuad; - ARM64Reg VA = reg_encoder(fpr.R(a, type)); - ARM64Reg VB = reg_encoder(fpr.R(b, type)); - ARM64Reg VC = reg_encoder(fpr.R(c, type)); - ARM64Reg VD = reg_encoder(fpr.RW(d, type)); + const ARM64Reg VA = reg_encoder(fpr.R(a, type)); + const ARM64Reg VB = reg_encoder(fpr.R(b, type)); + const ARM64Reg VC = reg_encoder(fpr.R(c, type)); + const ARM64Reg VD = reg_encoder(fpr.RW(d, type)); ARM64Reg V0Q = INVALID_REG; ARM64Reg V0 = INVALID_REG; if (d != b && (d == a || d == c)) @@ -255,17 +262,20 @@ void JitArm64::ps_sel(UGeckoInstruction inst) JITDISABLE(bJITPairedOff); FALLBACK_IF(inst.Rc); - u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD; + const u32 a = inst.FA; + const u32 b = inst.FB; + const u32 c = inst.FC; + const u32 d = inst.FD; - bool singles = fpr.IsSingle(a) && fpr.IsSingle(b) && fpr.IsSingle(c); - RegType type = singles ? REG_REG_SINGLE : REG_REG; - u8 size = singles ? 32 : 64; - ARM64Reg (*reg_encoder)(ARM64Reg) = singles ? EncodeRegToDouble : EncodeRegToQuad; + const bool singles = fpr.IsSingle(a) && fpr.IsSingle(b) && fpr.IsSingle(c); + const RegType type = singles ? RegType::Single : RegType::Register; + const u8 size = singles ? 32 : 64; + const auto reg_encoder = singles ? EncodeRegToDouble : EncodeRegToQuad; - ARM64Reg VA = reg_encoder(fpr.R(a, type)); - ARM64Reg VB = reg_encoder(fpr.R(b, type)); - ARM64Reg VC = reg_encoder(fpr.R(c, type)); - ARM64Reg VD = reg_encoder(fpr.RW(d, type)); + const ARM64Reg VA = reg_encoder(fpr.R(a, type)); + const ARM64Reg VB = reg_encoder(fpr.R(b, type)); + const ARM64Reg VC = reg_encoder(fpr.R(c, type)); + const ARM64Reg VD = reg_encoder(fpr.RW(d, type)); if (d != b && d != c) { @@ -274,8 +284,8 @@ void JitArm64::ps_sel(UGeckoInstruction inst) } else { - ARM64Reg V0Q = fpr.GetReg(); - ARM64Reg V0 = reg_encoder(V0Q); + const ARM64Reg V0Q = fpr.GetReg(); + const ARM64Reg V0 = reg_encoder(V0Q); m_float_emit.FCMGE(size, V0, VA); m_float_emit.BSL(V0, VC, VB); m_float_emit.MOV(VD, V0); @@ -290,20 +300,23 @@ void JitArm64::ps_sumX(UGeckoInstruction inst) FALLBACK_IF(inst.Rc); FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); - u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD; + const u32 a = inst.FA; + const u32 b = inst.FB; + const u32 c = inst.FC; + const u32 d = inst.FD; - bool upper = inst.SUBOP5 == 11; + const bool upper = inst.SUBOP5 == 11; - bool singles = fpr.IsSingle(a) && fpr.IsSingle(b) && fpr.IsSingle(c); - RegType type = singles ? REG_REG_SINGLE : REG_REG; - u8 size = singles ? 32 : 64; - ARM64Reg (*reg_encoder)(ARM64Reg) = singles ? EncodeRegToDouble : EncodeRegToQuad; + const bool singles = fpr.IsSingle(a) && fpr.IsSingle(b) && fpr.IsSingle(c); + const RegType type = singles ? RegType::Single : RegType::Register; + const u8 size = singles ? 32 : 64; + const auto reg_encoder = singles ? EncodeRegToDouble : EncodeRegToQuad; - ARM64Reg VA = fpr.R(a, type); - ARM64Reg VB = fpr.R(b, type); - ARM64Reg VC = fpr.R(c, type); - ARM64Reg VD = fpr.RW(d, type); - ARM64Reg V0 = fpr.GetReg(); + const ARM64Reg VA = fpr.R(a, type); + const ARM64Reg VB = fpr.R(b, type); + const ARM64Reg VC = fpr.R(c, type); + const ARM64Reg VD = fpr.RW(d, type); + const ARM64Reg V0 = fpr.GetReg(); m_float_emit.DUP(size, reg_encoder(V0), reg_encoder(upper ? VA : VB), upper ? 0 : 1); if (d != c) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp index 4e786f5027..8c87da78ff 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp @@ -27,7 +27,7 @@ void Arm64RegCache::Init(ARM64XEmitter* emitter) ARM64Reg Arm64RegCache::GetReg() { // If we have no registers left, dump the most stale register first - if (!GetUnlockedRegisterCount()) + if (GetUnlockedRegisterCount() == 0) FlushMostStaleRegister(); for (auto& it : m_host_registers) @@ -45,12 +45,14 @@ ARM64Reg Arm64RegCache::GetReg() return INVALID_REG; } -u32 Arm64RegCache::GetUnlockedRegisterCount() +u32 Arm64RegCache::GetUnlockedRegisterCount() const { u32 unlocked_registers = 0; - for (auto& it : m_host_registers) + for (const auto& it : m_host_registers) + { if (!it.IsLocked()) ++unlocked_registers; + } return unlocked_registers; } @@ -81,7 +83,7 @@ void Arm64RegCache::FlushMostStaleRegister() const u32 last_used = reg.GetLastUsed(); if (last_used > most_stale_amount && - (reg.GetType() != REG_NOTLOADED && reg.GetType() != REG_IMM)) + (reg.GetType() != RegType::NotLoaded && reg.GetType() != RegType::Immediate)) { most_stale_preg = i; most_stale_amount = last_used; @@ -105,7 +107,7 @@ void Arm64GPRCache::Start(PPCAnalyst::BlockRegStats& stats) { } -bool Arm64GPRCache::IsCalleeSaved(ARM64Reg reg) +bool Arm64GPRCache::IsCalleeSaved(ARM64Reg reg) const { static constexpr std::array callee_regs{{ X28, @@ -158,7 +160,7 @@ void Arm64GPRCache::FlushRegister(size_t index, bool maintain_state) OpArg& reg = guest_reg.reg; size_t bitsize = guest_reg.bitsize; - if (reg.GetType() == REG_REG) + if (reg.GetType() == RegType::Register) { ARM64Reg host_reg = reg.GetReg(); if (reg.IsDirty()) @@ -170,7 +172,7 @@ void Arm64GPRCache::FlushRegister(size_t index, bool maintain_state) reg.Flush(); } } - else if (reg.GetType() == REG_IMM) + else if (reg.GetType() == RegType::Immediate) { if (!reg.GetImm()) { @@ -202,8 +204,8 @@ void Arm64GPRCache::FlushRegisters(BitSet32 regs, bool maintain_state) // We've got two guest registers in a row to store OpArg& reg1 = m_guest_registers[i]; OpArg& reg2 = m_guest_registers[i + 1]; - if (reg1.IsDirty() && reg2.IsDirty() && reg1.GetType() == REG_REG && - reg2.GetType() == REG_REG) + if (reg1.IsDirty() && reg2.IsDirty() && reg1.GetType() == RegType::Register && + reg2.GetType() == RegType::Register) { size_t ppc_offset = GetGuestByIndex(i).ppc_offset; ARM64Reg RX1 = R(GetGuestByIndex(i)); @@ -239,8 +241,8 @@ void Arm64GPRCache::FlushCRRegisters(BitSet32 regs, bool maintain_state) void Arm64GPRCache::Flush(FlushMode mode, PPCAnalyst::CodeOp* op) { - FlushRegisters(BitSet32(~0U), mode == FLUSH_MAINTAIN_STATE); - FlushCRRegisters(BitSet32(~0U), mode == FLUSH_MAINTAIN_STATE); + FlushRegisters(BitSet32(~0U), mode == FlushMode::MaintainState); + FlushCRRegisters(BitSet32(~0U), mode == FlushMode::MaintainState); } ARM64Reg Arm64GPRCache::R(const GuestRegInfo& guest_reg) @@ -253,10 +255,9 @@ ARM64Reg Arm64GPRCache::R(const GuestRegInfo& guest_reg) switch (reg.GetType()) { - case REG_REG: // already in a reg + case RegType::Register: // already in a reg return reg.GetReg(); - break; - case REG_IMM: // Is an immediate + case RegType::Immediate: // Is an immediate { ARM64Reg host_reg = bitsize != 64 ? GetReg() : EncodeRegTo64(GetReg()); m_emit->MOVI2R(host_reg, reg.GetImm()); @@ -265,7 +266,7 @@ ARM64Reg Arm64GPRCache::R(const GuestRegInfo& guest_reg) return host_reg; } break; - case REG_NOTLOADED: // Register isn't loaded at /all/ + case RegType::NotLoaded: // Register isn't loaded at /all/ { // This is a bit annoying. We try to keep these preloaded as much as possible // This can also happen on cases where PPCAnalyst isn't feeing us proper register usage @@ -288,7 +289,7 @@ ARM64Reg Arm64GPRCache::R(const GuestRegInfo& guest_reg) void Arm64GPRCache::SetImmediate(const GuestRegInfo& guest_reg, u32 imm) { OpArg& reg = guest_reg.reg; - if (reg.GetType() == REG_REG) + if (reg.GetType() == RegType::Register) UnlockRegister(DecodeReg(reg.GetReg())); reg.LoadToImm(imm); } @@ -296,14 +297,14 @@ void Arm64GPRCache::SetImmediate(const GuestRegInfo& guest_reg, u32 imm) void Arm64GPRCache::BindToRegister(const GuestRegInfo& guest_reg, bool do_load) { OpArg& reg = guest_reg.reg; - size_t bitsize = guest_reg.bitsize; + const size_t bitsize = guest_reg.bitsize; reg.ResetLastUsed(); reg.SetDirty(true); - if (reg.GetType() == REG_NOTLOADED) + if (reg.GetType() == RegType::NotLoaded) { - ARM64Reg host_reg = bitsize != 64 ? GetReg() : EncodeRegTo64(GetReg()); + const ARM64Reg host_reg = bitsize != 64 ? GetReg() : EncodeRegTo64(GetReg()); reg.Load(host_reg); if (do_load) m_emit->LDR(INDEX_UNSIGNED, host_reg, PPC_REG, u32(guest_reg.ppc_offset)); @@ -351,12 +352,14 @@ void Arm64GPRCache::GetAllocationOrder() m_host_registers.push_back(HostReg(reg)); } -BitSet32 Arm64GPRCache::GetCallerSavedUsed() +BitSet32 Arm64GPRCache::GetCallerSavedUsed() const { BitSet32 registers(0); - for (auto& it : m_host_registers) + for (const auto& it : m_host_registers) + { if (it.IsLocked() && !IsCalleeSaved(it.GetReg())) - registers[DecodeReg(it.GetReg())] = 1; + registers[DecodeReg(it.GetReg())] = true; + } return registers; } @@ -366,7 +369,7 @@ void Arm64GPRCache::FlushByHost(ARM64Reg host_reg) for (size_t i = 0; i < m_guest_registers.size(); ++i) { const OpArg& reg = m_guest_registers[i]; - if (reg.GetType() == REG_REG && DecodeReg(reg.GetReg()) == host_reg) + if (reg.GetType() == RegType::Register && DecodeReg(reg.GetReg()) == host_reg) { FlushRegister(i, false); return; @@ -387,11 +390,11 @@ void Arm64FPRCache::Flush(FlushMode mode, PPCAnalyst::CodeOp* op) { const RegType reg_type = m_guest_registers[i].GetType(); - if (reg_type != REG_NOTLOADED && reg_type != REG_IMM) + if (reg_type != RegType::NotLoaded && reg_type != RegType::Immediate) { // XXX: Determine if we can keep a register in the lower 64bits // Which will allow it to be callee saved. - FlushRegister(i, mode == FLUSH_MAINTAIN_STATE); + FlushRegister(i, mode == FlushMode::MaintainState); } } } @@ -405,90 +408,90 @@ ARM64Reg Arm64FPRCache::R(size_t preg, RegType type) switch (reg.GetType()) { - case REG_REG_SINGLE: + case RegType::Single: { // We're asked for singles, so just return the register. - if (type == REG_REG_SINGLE || type == REG_LOWER_PAIR_SINGLE) + if (type == RegType::Single || type == RegType::LowerPairSingle) return host_reg; // Else convert this register back to doubles. m_float_emit->FCVTL(64, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg)); - reg.Load(host_reg, REG_REG); + reg.Load(host_reg, RegType::Register); [[fallthrough]]; } - case REG_REG: // already in a reg + case RegType::Register: // already in a reg { return host_reg; } - case REG_LOWER_PAIR_SINGLE: + case RegType::LowerPairSingle: { // We're asked for the lower single, so just return the register. - if (type == REG_LOWER_PAIR_SINGLE) + if (type == RegType::LowerPairSingle) return host_reg; // Else convert this register back to a double. m_float_emit->FCVT(64, 32, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg)); - reg.Load(host_reg, REG_LOWER_PAIR); + reg.Load(host_reg, RegType::LowerPair); [[fallthrough]]; } - case REG_LOWER_PAIR: + case RegType::LowerPair: { - if (type == REG_REG) + if (type == RegType::Register) { // Load the high 64bits from the file and insert them in to the high 64bits of the host // register - ARM64Reg tmp_reg = GetReg(); + const ARM64Reg tmp_reg = GetReg(); m_float_emit->LDR(64, INDEX_UNSIGNED, tmp_reg, PPC_REG, u32(PPCSTATE_OFF(ps[preg].ps1))); m_float_emit->INS(64, host_reg, 1, tmp_reg, 0); UnlockRegister(tmp_reg); // Change it over to a full 128bit register - reg.Load(host_reg, REG_REG); + reg.Load(host_reg, RegType::Register); } return host_reg; } - case REG_DUP_SINGLE: + case RegType::DuplicatedSingle: { - if (type == REG_LOWER_PAIR_SINGLE) + if (type == RegType::LowerPairSingle) return host_reg; - if (type == REG_REG_SINGLE) + if (type == RegType::Single) { // Duplicate to the top and change over m_float_emit->INS(32, host_reg, 1, host_reg, 0); - reg.Load(host_reg, REG_REG_SINGLE); + reg.Load(host_reg, RegType::Single); return host_reg; } m_float_emit->FCVT(64, 32, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg)); - reg.Load(host_reg, REG_DUP); + reg.Load(host_reg, RegType::Duplicated); [[fallthrough]]; } - case REG_DUP: + case RegType::Duplicated: { - if (type == REG_REG) + if (type == RegType::Register) { // We are requesting a full 128bit register // but we are only available in the lower 64bits // Duplicate to the top and change over m_float_emit->INS(64, host_reg, 1, host_reg, 0); - reg.Load(host_reg, REG_REG); + reg.Load(host_reg, RegType::Register); } return host_reg; } - case REG_NOTLOADED: // Register isn't loaded at /all/ + case RegType::NotLoaded: // Register isn't loaded at /all/ { host_reg = GetReg(); u32 load_size; - if (type == REG_REG) + if (type == RegType::Register) { load_size = 128; - reg.Load(host_reg, REG_REG); + reg.Load(host_reg, RegType::Register); } else { load_size = 64; - reg.Load(host_reg, REG_LOWER_PAIR); + reg.Load(host_reg, RegType::LowerPair); } reg.SetDirty(false); m_float_emit->LDR(load_size, INDEX_UNSIGNED, host_reg, PPC_REG, @@ -515,14 +518,14 @@ ARM64Reg Arm64FPRCache::RW(size_t preg, RegType type) reg.SetDirty(true); // If not loaded at all, just alloc a new one. - if (reg.GetType() == REG_NOTLOADED) + if (reg.GetType() == RegType::NotLoaded) { reg.Load(GetReg(), type); return reg.GetReg(); } // Only the lower value will be overwritten, so we must be extra careful to store PSR1 if dirty. - if ((type == REG_LOWER_PAIR || type == REG_LOWER_PAIR_SINGLE) && was_dirty) + if ((type == RegType::LowerPair || type == RegType::LowerPairSingle) && was_dirty) { // We must *not* change host_reg as this register might still be in use. So it's fine to // store this register, but it's *not* fine to convert it to double. So for double convertion, @@ -532,21 +535,21 @@ ARM64Reg Arm64FPRCache::RW(size_t preg, RegType type) switch (reg.GetType()) { - case REG_REG_SINGLE: + case RegType::Single: flush_reg = GetReg(); m_float_emit->FCVTL(64, EncodeRegToDouble(flush_reg), EncodeRegToDouble(host_reg)); [[fallthrough]]; - case REG_REG: + case RegType::Register: // We are doing a full 128bit store because it takes 2 cycles on a Cortex-A57 to do a 128bit // store. // It would take longer to do an insert to a temporary and a 64bit store than to just do this. m_float_emit->STR(128, INDEX_UNSIGNED, flush_reg, PPC_REG, u32(PPCSTATE_OFF(ps[preg].ps0))); break; - case REG_DUP_SINGLE: + case RegType::DuplicatedSingle: flush_reg = GetReg(); m_float_emit->FCVT(64, 32, EncodeRegToDouble(flush_reg), EncodeRegToDouble(host_reg)); [[fallthrough]]; - case REG_DUP: + case RegType::Duplicated: // Store PSR1 (which is equal to PSR0) in memory. m_float_emit->STR(64, INDEX_UNSIGNED, flush_reg, PPC_REG, u32(PPCSTATE_OFF(ps[preg].ps1))); break; @@ -614,7 +617,8 @@ void Arm64FPRCache::FlushByHost(ARM64Reg host_reg) const OpArg& reg = m_guest_registers[i]; const RegType reg_type = reg.GetType(); - if ((reg_type != REG_NOTLOADED && reg_type != REG_IMM) && reg.GetReg() == host_reg) + if ((reg_type != RegType::NotLoaded && reg_type != RegType::Immediate) && + reg.GetReg() == host_reg) { FlushRegister(i, false); return; @@ -622,7 +626,7 @@ void Arm64FPRCache::FlushByHost(ARM64Reg host_reg) } } -bool Arm64FPRCache::IsCalleeSaved(ARM64Reg reg) +bool Arm64FPRCache::IsCalleeSaved(ARM64Reg reg) const { static constexpr std::array callee_regs{{ Q8, @@ -642,32 +646,32 @@ bool Arm64FPRCache::IsCalleeSaved(ARM64Reg reg) void Arm64FPRCache::FlushRegister(size_t preg, bool maintain_state) { OpArg& reg = m_guest_registers[preg]; - ARM64Reg host_reg = reg.GetReg(); + const ARM64Reg host_reg = reg.GetReg(); + const bool dirty = reg.IsDirty(); RegType type = reg.GetType(); - bool dirty = reg.IsDirty(); // If we're in single mode, just convert it back to a double. - if (type == REG_REG_SINGLE) + if (type == RegType::Single) { if (dirty) m_float_emit->FCVTL(64, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg)); - type = REG_REG; + type = RegType::Register; } - if (type == REG_DUP_SINGLE || type == REG_LOWER_PAIR_SINGLE) + if (type == RegType::DuplicatedSingle || type == RegType::LowerPairSingle) { if (dirty) m_float_emit->FCVT(64, 32, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg)); - if (type == REG_DUP_SINGLE) - type = REG_DUP; + if (type == RegType::DuplicatedSingle) + type = RegType::Duplicated; else - type = REG_LOWER_PAIR; + type = RegType::LowerPair; } - if (type == REG_REG || type == REG_LOWER_PAIR) + if (type == RegType::Register || type == RegType::LowerPair) { u32 store_size; - if (type == REG_REG) + if (type == RegType::Register) store_size = 128; else store_size = 64; @@ -684,7 +688,7 @@ void Arm64FPRCache::FlushRegister(size_t preg, bool maintain_state) reg.Flush(); } } - else if (type == REG_DUP) + else if (type == RegType::Duplicated) { if (dirty) { @@ -710,20 +714,22 @@ void Arm64FPRCache::FlushRegisters(BitSet32 regs, bool maintain_state) FlushRegister(j, maintain_state); } -BitSet32 Arm64FPRCache::GetCallerSavedUsed() +BitSet32 Arm64FPRCache::GetCallerSavedUsed() const { BitSet32 registers(0); - for (auto& it : m_host_registers) + for (const auto& it : m_host_registers) + { if (it.IsLocked()) - registers[it.GetReg() - Q0] = 1; + registers[it.GetReg() - Q0] = true; + } return registers; } -bool Arm64FPRCache::IsSingle(size_t preg, bool lower_only) +bool Arm64FPRCache::IsSingle(size_t preg, bool lower_only) const { - RegType type = m_guest_registers[preg].GetType(); - return type == REG_REG_SINGLE || type == REG_DUP_SINGLE || - (lower_only && type == REG_LOWER_PAIR_SINGLE); + const RegType type = m_guest_registers[preg].GetType(); + return type == RegType::Single || type == RegType::DuplicatedSingle || + (lower_only && type == RegType::LowerPairSingle); } void Arm64FPRCache::FixSinglePrecision(size_t preg) @@ -732,13 +738,13 @@ void Arm64FPRCache::FixSinglePrecision(size_t preg) ARM64Reg host_reg = reg.GetReg(); switch (reg.GetType()) { - case REG_DUP: // only PS0 needs to be converted + case RegType::Duplicated: // only PS0 needs to be converted m_float_emit->FCVT(32, 64, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg)); - reg.Load(host_reg, REG_DUP_SINGLE); + reg.Load(host_reg, RegType::DuplicatedSingle); break; - case REG_REG: // PS0 and PS1 needs to be converted + case RegType::Register: // PS0 and PS1 needs to be converted m_float_emit->FCVTN(32, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg)); - reg.Load(host_reg, REG_REG_SINGLE); + reg.Load(host_reg, RegType::Single); break; default: break; diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h index 9860e4843e..b074001830 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h @@ -15,10 +15,13 @@ #include "Core/PowerPC/PowerPC.h" // Dedicated host registers -static const Arm64Gen::ARM64Reg MEM_REG = Arm64Gen::X28; // memory base register -static const Arm64Gen::ARM64Reg PPC_REG = Arm64Gen::X29; // ppcState pointer -static const Arm64Gen::ARM64Reg DISPATCHER_PC = - Arm64Gen::W26; // PC register when calling the dispatcher + +// memory base register +constexpr Arm64Gen::ARM64Reg MEM_REG = Arm64Gen::X28; +// ppcState pointer +constexpr Arm64Gen::ARM64Reg PPC_REG = Arm64Gen::X29; +// PC register when calling the dispatcher +constexpr Arm64Gen::ARM64Reg DISPATCHER_PC = Arm64Gen::W26; #define PPCSTATE_OFF(elem) (offsetof(PowerPC::PowerPCState, elem)) @@ -29,43 +32,44 @@ static_assert((PPCSTATE_OFF(ps[0].ps0) % 8) == 0, static_assert(PPCSTATE_OFF(xer_ca) < 4096, "STRB can't store xer_ca!"); static_assert(PPCSTATE_OFF(xer_so_ov) < 4096, "STRB can't store xer_so_ov!"); -enum RegType +enum class RegType { - REG_NOTLOADED = 0, - REG_REG, // Reg type is register - REG_IMM, // Reg is really a IMM - REG_LOWER_PAIR, // Only the lower pair of a paired register - REG_DUP, // The lower reg is the same as the upper one (physical upper doesn't actually have the - // duplicated value) - REG_REG_SINGLE, // Both registers are loaded as single - REG_LOWER_PAIR_SINGLE, // Only the lower pair of a paired register, as single - REG_DUP_SINGLE, // The lower one contains both registers, as single + NotLoaded, + Register, // Reg type is register + Immediate, // Reg is really a IMM + LowerPair, // Only the lower pair of a paired register + Duplicated, // The lower reg is the same as the upper one (physical upper doesn't actually have + // the duplicated value) + Single, // Both registers are loaded as single + LowerPairSingle, // Only the lower pair of a paired register, as single + DuplicatedSingle, // The lower one contains both registers, as single }; -enum FlushMode +enum class FlushMode { // Flushes all registers, no exceptions - FLUSH_ALL = 0, + All, // Flushes registers in a conditional branch // Doesn't wipe the state of the registers from the cache - FLUSH_MAINTAIN_STATE, + MaintainState, }; class OpArg { public: - OpArg() : m_type(REG_NOTLOADED), m_reg(Arm64Gen::INVALID_REG), m_value(0), m_last_used(0) {} + OpArg() = default; + RegType GetType() const { return m_type; } Arm64Gen::ARM64Reg GetReg() const { return m_reg; } u32 GetImm() const { return m_value; } - void Load(Arm64Gen::ARM64Reg reg, RegType type = REG_REG) + void Load(Arm64Gen::ARM64Reg reg, RegType type = RegType::Register) { m_type = type; m_reg = reg; } void LoadToImm(u32 imm) { - m_type = REG_IMM; + m_type = RegType::Immediate; m_value = imm; m_reg = Arm64Gen::INVALID_REG; @@ -73,7 +77,7 @@ public: void Flush() { // Invalidate any previous information - m_type = REG_NOTLOADED; + m_type = RegType::NotLoaded; m_reg = Arm64Gen::INVALID_REG; // Arbitrarily large value that won't roll over on a lot of increments @@ -88,40 +92,41 @@ public: private: // For REG_REG - RegType m_type; // store type - Arm64Gen::ARM64Reg m_reg; // host register we are in + RegType m_type = RegType::NotLoaded; // store type + Arm64Gen::ARM64Reg m_reg = Arm64Gen::INVALID_REG; // host register we are in // For REG_IMM - u32 m_value; // IMM value + u32 m_value = 0; // IMM value - u32 m_last_used; + u32 m_last_used = 0; - bool m_dirty; + bool m_dirty = false; }; class HostReg { public: - HostReg() : m_reg(Arm64Gen::INVALID_REG), m_locked(false) {} - HostReg(Arm64Gen::ARM64Reg reg) : m_reg(reg), m_locked(false) {} + HostReg() = default; + HostReg(Arm64Gen::ARM64Reg reg) : m_reg(reg) {} + bool IsLocked() const { return m_locked; } void Lock() { m_locked = true; } void Unlock() { m_locked = false; } Arm64Gen::ARM64Reg GetReg() const { return m_reg; } - bool operator==(const Arm64Gen::ARM64Reg& reg) { return reg == m_reg; } + + bool operator==(Arm64Gen::ARM64Reg reg) const { return reg == m_reg; } + bool operator!=(Arm64Gen::ARM64Reg reg) const { return !operator==(reg); } private: - Arm64Gen::ARM64Reg m_reg; - bool m_locked; + Arm64Gen::ARM64Reg m_reg = Arm64Gen::INVALID_REG; + bool m_locked = false; }; class Arm64RegCache { public: - explicit Arm64RegCache(size_t guest_reg_count) - : m_emit(nullptr), m_float_emit(nullptr), m_guest_registers(guest_reg_count), - m_reg_stats(nullptr){}; - virtual ~Arm64RegCache(){}; + explicit Arm64RegCache(size_t guest_reg_count) : m_guest_registers(guest_reg_count) {} + virtual ~Arm64RegCache() = default; void Init(Arm64Gen::ARM64XEmitter* emitter); @@ -129,7 +134,7 @@ public: // Flushes the register cache in different ways depending on the mode virtual void Flush(FlushMode mode, PPCAnalyst::CodeOp* op) = 0; - virtual BitSet32 GetCallerSavedUsed() = 0; + virtual BitSet32 GetCallerSavedUsed() const = 0; // Returns a temporary register for use // Requires unlocking after done @@ -178,7 +183,7 @@ protected: virtual void FlushRegister(size_t preg, bool maintain_state) = 0; // Get available host registers - u32 GetUnlockedRegisterCount(); + u32 GetUnlockedRegisterCount() const; void IncrementAllUsed() { @@ -187,7 +192,7 @@ protected: } // Code emitter - Arm64Gen::ARM64XEmitter* m_emit; + Arm64Gen::ARM64XEmitter* m_emit = nullptr; // Float emitter std::unique_ptr m_float_emit; @@ -201,14 +206,14 @@ protected: std::vector m_guest_registers; // Register stats for the current block - PPCAnalyst::BlockRegStats* m_reg_stats; + PPCAnalyst::BlockRegStats* m_reg_stats = nullptr; }; class Arm64GPRCache : public Arm64RegCache { public: Arm64GPRCache(); - ~Arm64GPRCache() {} + void Start(PPCAnalyst::BlockRegStats& stats) override; // Flushes the register cache in different ways depending on the mode @@ -222,14 +227,14 @@ public: // Set a register to an immediate, only valid for guest GPRs void SetImmediate(size_t preg, u32 imm) { SetImmediate(GetGuestGPR(preg), imm); } // Returns if a register is set as an immediate, only valid for guest GPRs - bool IsImm(size_t preg) const { return GetGuestGPROpArg(preg).GetType() == REG_IMM; } + bool IsImm(size_t preg) const { return GetGuestGPROpArg(preg).GetType() == RegType::Immediate; } // Gets the immediate that a register is set to, only valid for guest GPRs u32 GetImm(size_t preg) const { return GetGuestGPROpArg(preg).GetImm(); } // Binds a guest GPR to a host register, optionally loading its value void BindToRegister(size_t preg, bool do_load) { BindToRegister(GetGuestGPR(preg), do_load); } // Binds a guest CR to a host register, optionally loading its value void BindCRToRegister(size_t preg, bool do_load) { BindToRegister(GetGuestCR(preg), do_load); } - BitSet32 GetCallerSavedUsed() override; + BitSet32 GetCallerSavedUsed() const override; void StoreRegisters(BitSet32 regs) { FlushRegisters(regs, false); } void StoreCRRegisters(BitSet32 regs) { FlushCRRegisters(regs, false); } @@ -244,7 +249,7 @@ protected: void FlushRegister(size_t index, bool maintain_state) override; private: - bool IsCalleeSaved(Arm64Gen::ARM64Reg reg); + bool IsCalleeSaved(Arm64Gen::ARM64Reg reg) const; struct GuestRegInfo { @@ -270,19 +275,19 @@ class Arm64FPRCache : public Arm64RegCache { public: Arm64FPRCache(); - ~Arm64FPRCache() {} + // Flushes the register cache in different ways depending on the mode void Flush(FlushMode mode, PPCAnalyst::CodeOp* op = nullptr) override; // Returns a guest register inside of a host register // Will dump an immediate to the host register as well - Arm64Gen::ARM64Reg R(size_t preg, RegType type = REG_LOWER_PAIR); + Arm64Gen::ARM64Reg R(size_t preg, RegType type = RegType::LowerPair); - Arm64Gen::ARM64Reg RW(size_t preg, RegType type = REG_LOWER_PAIR); + Arm64Gen::ARM64Reg RW(size_t preg, RegType type = RegType::LowerPair); - BitSet32 GetCallerSavedUsed() override; + BitSet32 GetCallerSavedUsed() const override; - bool IsSingle(size_t preg, bool lower_only = false); + bool IsSingle(size_t preg, bool lower_only = false) const; void FixSinglePrecision(size_t preg); @@ -298,7 +303,7 @@ protected: void FlushRegister(size_t preg, bool maintain_state) override; private: - bool IsCalleeSaved(Arm64Gen::ARM64Reg reg); + bool IsCalleeSaved(Arm64Gen::ARM64Reg reg) const; void FlushRegisters(BitSet32 regs, bool maintain_state); }; diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp index 9e921d181b..59ebcf48d0 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp @@ -44,8 +44,8 @@ void JitArm64::mtmsr(UGeckoInstruction inst) gpr.BindToRegister(inst.RS, true); STR(INDEX_UNSIGNED, gpr.R(inst.RS), PPC_REG, PPCSTATE_OFF(msr)); - gpr.Flush(FlushMode::FLUSH_ALL); - fpr.Flush(FlushMode::FLUSH_ALL); + gpr.Flush(FlushMode::All); + fpr.Flush(FlushMode::All); // Our jit cache also stores some MSR bits, as they have changed, we either // have to validate them in the BLR/RET check, or just flush the stack here. @@ -201,8 +201,8 @@ void JitArm64::twx(UGeckoInstruction inst) SwitchToFarCode(); SetJumpTarget(far_addr); - gpr.Flush(FlushMode::FLUSH_MAINTAIN_STATE); - fpr.Flush(FlushMode::FLUSH_MAINTAIN_STATE); + gpr.Flush(FlushMode::MaintainState); + fpr.Flush(FlushMode::MaintainState); LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(Exceptions)); ORR(WA, WA, 24, 0); // Same as WA | EXCEPTION_PROGRAM @@ -217,8 +217,8 @@ void JitArm64::twx(UGeckoInstruction inst) if (!analyzer.HasOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE)) { - gpr.Flush(FlushMode::FLUSH_ALL); - fpr.Flush(FlushMode::FLUSH_ALL); + gpr.Flush(FlushMode::All); + fpr.Flush(FlushMode::All); WriteExit(js.compilerPC + 4); } }