From a23ade8f75549f2cd4346fcace218eeb95970735 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 20 Aug 2023 00:04:37 -0700 Subject: [PATCH] riscv: Map IR regs based on metadata. Only doing this in places without GPR/FPR mix or FPR/Vec overlap for now. --- Core/MIPS/IR/IRRegCache.cpp | 115 +++++++++++++++++++- Core/MIPS/IR/IRRegCache.h | 8 +- Core/MIPS/RiscV/RiscVCompALU.cpp | 141 +++++++++++++------------ Core/MIPS/RiscV/RiscVCompBranch.cpp | 6 +- Core/MIPS/RiscV/RiscVCompFPU.cpp | 102 +++++++++--------- Core/MIPS/RiscV/RiscVCompLoadStore.cpp | 32 +++--- Core/MIPS/RiscV/RiscVCompSystem.cpp | 16 +-- Core/MIPS/RiscV/RiscVCompVec.cpp | 47 ++++----- Core/MIPS/RiscV/RiscVRegCache.cpp | 50 ++------- Core/MIPS/RiscV/RiscVRegCache.h | 10 +- Core/MIPS/RiscV/RiscVRegCacheFPU.cpp | 54 +++------- Core/MIPS/RiscV/RiscVRegCacheFPU.h | 5 +- 12 files changed, 319 insertions(+), 267 deletions(-) diff --git a/Core/MIPS/IR/IRRegCache.cpp b/Core/MIPS/IR/IRRegCache.cpp index f3b45bef71..9f45e1e7b2 100644 --- a/Core/MIPS/IR/IRRegCache.cpp +++ b/Core/MIPS/IR/IRRegCache.cpp @@ -102,7 +102,7 @@ void IRNativeRegCacheBase::Start(MIPSComp::IRBlock *irBlock) { initialReady_ = true; } - memcpy(nr, nrInitial_, sizeof(nr[0]) * totalNativeRegs_); + memcpy(nr, nrInitial_, sizeof(nr[0]) * config_.totalNativeRegs); memcpy(mr, mrInitial_, sizeof(mr)); int numStatics; @@ -123,7 +123,7 @@ void IRNativeRegCacheBase::Start(MIPSComp::IRBlock *irBlock) { } void IRNativeRegCacheBase::SetupInitialRegs() { - _assert_msg_(totalNativeRegs_ > 0, "totalNativeRegs_ was never set by backend"); + _assert_msg_(config_.totalNativeRegs > 0, "totalNativeRegs was never set by backend"); // Everything else is initialized in the struct. mrInitial_[MIPS_REG_ZERO].loc = MIPSLoc::IMM; @@ -421,7 +421,7 @@ IRNativeReg IRNativeRegCacheBase::FindBestToSpill(MIPSLoc type, bool unusedOnly, } void IRNativeRegCacheBase::DiscardNativeReg(IRNativeReg nreg) { - _assert_msg_(nreg >= 0 && nreg < totalNativeRegs_, "DiscardNativeReg on invalid register %d", nreg); + _assert_msg_(nreg >= 0 && nreg < config_.totalNativeRegs, "DiscardNativeReg on invalid register %d", nreg); if (nr[nreg].mipsReg != IRREG_INVALID) { _assert_(nr[nreg].mipsReg != MIPS_REG_ZERO); int8_t lanes = 0; @@ -460,7 +460,7 @@ void IRNativeRegCacheBase::DiscardNativeReg(IRNativeReg nreg) { } void IRNativeRegCacheBase::FlushNativeReg(IRNativeReg nreg) { - _assert_msg_(nreg >= 0 && nreg < totalNativeRegs_, "FlushNativeReg on invalid register %d", nreg); + _assert_msg_(nreg >= 0 && nreg < config_.totalNativeRegs, "FlushNativeReg on invalid register %d", nreg); if (nr[nreg].mipsReg == IRREG_INVALID || nr[nreg].mipsReg == MIPS_REG_ZERO) { // Nothing to do, reg not mapped or mapped to fixed zero. _dbg_assert_(!nr[nreg].isDirty); @@ -614,13 +614,118 @@ void IRNativeRegCacheBase::FlushAll() { } } // Sanity check - for (int i = 0; i < totalNativeRegs_; i++) { + for (int i = 0; i < config_.totalNativeRegs; i++) { if (nr[i].mipsReg != IRREG_INVALID && !mr[nr[i].mipsReg].isStatic) { ERROR_LOG_REPORT(JIT, "Flush fail: nr[%i].mipsReg=%i", i, nr[i].mipsReg); } } } +void IRNativeRegCacheBase::Map(const IRInst &inst) { + const IRMeta *m = GetIRMeta(inst.op); + IRReg regs[3]{ inst.dest, inst.src1, inst.src2 }; + MIPSLoc regTypes[3]{ MIPSLoc::MEM, MIPSLoc::MEM, MIPSLoc::MEM }; + int regLanes[3]{ 1, 1, 1 }; + for (int i = 0; i < 3; ++i) { + switch (m->types[i]) { + case 'G': + regTypes[i] = MIPSLoc::REG; + _assert_msg_(IsValidGPR(regs[i]), "G was not valid GPR?"); + break; + + case 'F': + regs[i] += 32; + regTypes[i] = MIPSLoc::FREG; + _assert_msg_(IsValidFPR(regs[i] - 32), "F was not valid FPR?"); + break; + + case 'V': + case '2': + regs[i] += 32; + regTypes[i] = config_.mapUseVRegs ? MIPSLoc::VREG : MIPSLoc::FREG; + regLanes[i] = m->types[i] == 'V' ? 4 : (m->types[i] == '2' ? 2 : 1); + _assert_msg_(IsValidFPR(regs[i] - 32), "%c was not valid FPR?", m->types[i]); + break; + + case 'T': + regTypes[i] = MIPSLoc::REG; + _assert_msg_(regs[i] < VFPU_CTRL_MAX, "T was not valid VFPU CTRL?"); + regs[i] += IRREG_VFPU_CTRL_BASE; + break; + + case '\0': + case '_': + case 'C': + case 'I': + case 'v': + case 's': + case 'm': + regs[i] = IRREG_INVALID; + regLanes[i] = 0; + break; + + default: + _assert_msg_(regs[i] == IRREG_INVALID, "Unexpected register type %c", m->types[i]); + break; + } + } + + SetSpillLockIRIndex(regs[0], regs[1], regs[2], IRREG_INVALID, 0, irIndex_); + for (int i = 0; i < 3 && !config_.mapSIMD; ++i) { + for (int j = 1; j < regLanes[i]; ++j) + SetSpillLockIRIndex(regs[i] + j, IRREG_INVALID, IRREG_INVALID, IRREG_INVALID, 0, irIndex_); + } + + auto mapRegs = [&](int i, MIPSMap flags) { + if (config_.mapSIMD) { + MapNativeReg(regTypes[i], regs[i], regLanes[i], flags); + return; + } + + for (int j = 0; j < regLanes[i]; ++j) + MapNativeReg(regTypes[i], regs[i] + j, 1, flags); + }; + + if (regs[1] != IRREG_INVALID) + mapRegs(1, MIPSMap::INIT); + if (regs[2] != IRREG_INVALID) + mapRegs(2, MIPSMap::INIT); + if (regs[0] != IRREG_INVALID) { + MIPSMap flags = MIPSMap::NOINIT; + if ((m->flags & IRFLAG_SRC3DST) != 0) + flags = MIPSMap::DIRTY; + else if ((m->flags & IRFLAG_SRC3) != 0) + flags = MIPSMap::INIT; + + mapRegs(0, flags); + } + + SetSpillLockIRIndex(regs[0], regs[1], regs[2], IRREG_INVALID, 0, -1); + for (int i = 0; i < 3 && !config_.mapSIMD; ++i) { + for (int j = 1; j < regLanes[i]; ++j) + SetSpillLockIRIndex(regs[i] + j, IRREG_INVALID, IRREG_INVALID, IRREG_INVALID, 0, -1); + } + + // Sanity check. If these don't pass, we may have Vec overlap issues or etc. + for (int i = 0; i < 3; ++i) { + if (regs[i] != IRREG_INVALID) { + _dbg_assert_(mr[regs[i]].nReg != -1); + if (regTypes[i] == MIPSLoc::REG) { + _dbg_assert_(mr[regs[i]].loc == MIPSLoc::REG || mr[regs[i]].loc == MIPSLoc::REG_AS_PTR || mr[regs[i]].loc == MIPSLoc::REG_IMM); + } else { + _dbg_assert_(mr[regs[i]].loc == regTypes[i]); + } + if (regLanes[i] != 1 && config_.mapSIMD) { + _dbg_assert_(mr[regs[i]].lane == 0); + _dbg_assert_(mr[regs[i] + regLanes[i] - 1].lane == regLanes[i] - 1); + _dbg_assert_(mr[regs[i]].nReg == mr[regs[i] + regLanes[i] - 1].nReg); + } else { + _dbg_assert_(mr[regs[i]].lane == -1); + } + } + } +} + IRNativeReg IRNativeRegCacheBase::MapNativeReg(MIPSLoc type, IRReg first, int lanes, MIPSMap flags) { _assert_msg_(first != IRREG_INVALID, "Cannot map invalid register"); _assert_msg_(lanes >= 1 && lanes <= 4, "Cannot map %d lanes", lanes); diff --git a/Core/MIPS/IR/IRRegCache.h b/Core/MIPS/IR/IRRegCache.h index 33779b701a..7bc0460f6e 100644 --- a/Core/MIPS/IR/IRRegCache.h +++ b/Core/MIPS/IR/IRRegCache.h @@ -183,6 +183,7 @@ public: void MarkGPRDirty(IRReg gpr, bool andNormalized32 = false); void MarkGPRAsPointerDirty(IRReg gpr); + virtual void Map(const IRInst &inst); virtual void FlushAll(); protected: @@ -224,7 +225,12 @@ protected: MIPSComp::JitOptions *jo_; const MIPSComp::IRBlock *irBlock_ = nullptr; int irIndex_ = 0; - int totalNativeRegs_ = 0; + + struct { + int totalNativeRegs = 0; + bool mapSIMD = false; + bool mapUseVRegs = false; + } config_; RegStatusNative nr[TOTAL_POSSIBLE_NATIVEREGS]; RegStatusMIPS mr[TOTAL_MAPPABLE_IRREGS]; diff --git a/Core/MIPS/RiscV/RiscVCompALU.cpp b/Core/MIPS/RiscV/RiscVCompALU.cpp index 69e4a47ee5..fbaf45c0af 100644 --- a/Core/MIPS/RiscV/RiscVCompALU.cpp +++ b/Core/MIPS/RiscV/RiscVCompALU.cpp @@ -53,13 +53,15 @@ void RiscVJitBackend::CompIR_Arith(IRInst inst) { switch (inst.op) { case IROp::Add: - gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); ADDW(gpr.R(inst.dest), gpr.R(inst.src1), gpr.R(inst.src2)); + gpr.MarkGPRDirty(inst.dest, true); break; case IROp::Sub: - gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); SUBW(gpr.R(inst.dest), gpr.R(inst.src1), gpr.R(inst.src2)); + gpr.MarkGPRDirty(inst.dest, true); break; case IROp::AddConst: @@ -69,25 +71,29 @@ void RiscVJitBackend::CompIR_Arith(IRInst inst) { gpr.MarkGPRAsPointerDirty(inst.dest); ADDI(gpr.RPtr(inst.dest), gpr.RPtr(inst.dest), inst.constant); } else { - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); ADDIW(gpr.R(inst.dest), gpr.R(inst.src1), inst.constant); + gpr.MarkGPRDirty(inst.dest, true); } } else { - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); LI(SCRATCH1, (int32_t)inst.constant); ADDW(gpr.R(inst.dest), gpr.R(inst.src1), SCRATCH1); + gpr.MarkGPRDirty(inst.dest, true); } break; case IROp::SubConst: - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); LI(SCRATCH1, (int32_t)inst.constant); SUBW(gpr.R(inst.dest), gpr.R(inst.src1), SCRATCH1); + gpr.MarkGPRDirty(inst.dest, true); break; case IROp::Neg: - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); SUBW(gpr.R(inst.dest), R_ZERO, gpr.R(inst.src1)); + gpr.MarkGPRDirty(inst.dest, true); break; default: @@ -99,13 +105,14 @@ void RiscVJitBackend::CompIR_Arith(IRInst inst) { void RiscVJitBackend::CompIR_Logic(IRInst inst) { CONDITIONAL_DISABLE; + bool resultNormalized = false; switch (inst.op) { case IROp::And: if (inst.src1 != inst.src2) { - gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + gpr.Map(inst); AND(gpr.R(inst.dest), gpr.R(inst.src1), gpr.R(inst.src2)); } else if (inst.src1 != inst.dest) { - gpr.MapDirtyIn(inst.dest, inst.src1); + gpr.Map(inst); MV(gpr.R(inst.dest), gpr.R(inst.src1)); gpr.MarkGPRDirty(inst.dest, gpr.IsNormalized32(inst.src1)); } @@ -113,13 +120,13 @@ void RiscVJitBackend::CompIR_Logic(IRInst inst) { case IROp::Or: if (inst.src1 != inst.src2) { - gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); - OR(gpr.R(inst.dest), gpr.R(inst.src1), gpr.R(inst.src2)); // If both were normalized before, the result is normalized. - if (gpr.IsNormalized32(inst.src1) && gpr.IsNormalized32(inst.src2)) - gpr.MarkGPRDirty(inst.dest, true); + resultNormalized = gpr.IsNormalized32(inst.src1) && gpr.IsNormalized32(inst.src2); + gpr.Map(inst); + OR(gpr.R(inst.dest), gpr.R(inst.src1), gpr.R(inst.src2)); + gpr.MarkGPRDirty(inst.dest, resultNormalized); } else if (inst.src1 != inst.dest) { - gpr.MapDirtyIn(inst.dest, inst.src1); + gpr.Map(inst); MV(gpr.R(inst.dest), gpr.R(inst.src1)); gpr.MarkGPRDirty(inst.dest, gpr.IsNormalized32(inst.src1)); } @@ -129,22 +136,22 @@ void RiscVJitBackend::CompIR_Logic(IRInst inst) { if (inst.src1 == inst.src2) { gpr.SetGPRImm(inst.dest, 0); } else { - gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + gpr.Map(inst); XOR(gpr.R(inst.dest), gpr.R(inst.src1), gpr.R(inst.src2)); } break; case IROp::AndConst: + resultNormalized = gpr.IsNormalized32(inst.src1); + gpr.Map(inst); if ((int32_t)inst.constant >= -2048 && (int32_t)inst.constant <= 2047) { - gpr.MapDirtyIn(inst.dest, inst.src1); ANDI(gpr.R(inst.dest), gpr.R(inst.src1), inst.constant); } else { - gpr.MapDirtyIn(inst.dest, inst.src1); LI(SCRATCH1, (int32_t)inst.constant); AND(gpr.R(inst.dest), gpr.R(inst.src1), SCRATCH1); } // If the sign bits aren't cleared, and it was normalized before - it still is. - if ((inst.constant & 0x80000000) != 0 && gpr.IsNormalized32(inst.src1)) + if ((inst.constant & 0x80000000) != 0 && resultNormalized) gpr.MarkGPRDirty(inst.dest, true); // Otherwise, if we cleared the sign bits, it's naturally normalized. else if ((inst.constant & 0x80000000) == 0) @@ -152,32 +159,30 @@ void RiscVJitBackend::CompIR_Logic(IRInst inst) { break; case IROp::OrConst: + resultNormalized = gpr.IsNormalized32(inst.src1); + gpr.Map(inst); if ((int32_t)inst.constant >= -2048 && (int32_t)inst.constant <= 2047) { - gpr.MapDirtyIn(inst.dest, inst.src1); ORI(gpr.R(inst.dest), gpr.R(inst.src1), inst.constant); } else { - gpr.MapDirtyIn(inst.dest, inst.src1); LI(SCRATCH1, (int32_t)inst.constant); OR(gpr.R(inst.dest), gpr.R(inst.src1), SCRATCH1); } // Since our constant is normalized, oring its bits in won't hurt normalization. - if (gpr.IsNormalized32(inst.src1)) - gpr.MarkGPRDirty(inst.dest, true); + gpr.MarkGPRDirty(inst.dest, resultNormalized); break; case IROp::XorConst: + gpr.Map(inst); if ((int32_t)inst.constant >= -2048 && (int32_t)inst.constant <= 2047) { - gpr.MapDirtyIn(inst.dest, inst.src1); XORI(gpr.R(inst.dest), gpr.R(inst.src1), inst.constant); } else { - gpr.MapDirtyIn(inst.dest, inst.src1); LI(SCRATCH1, (int32_t)inst.constant); XOR(gpr.R(inst.dest), gpr.R(inst.src1), SCRATCH1); } break; case IROp::Not: - gpr.MapDirtyIn(inst.dest, inst.src1); + gpr.Map(inst); NOT(gpr.R(inst.dest), gpr.R(inst.src1)); break; @@ -193,32 +198,32 @@ void RiscVJitBackend::CompIR_Assign(IRInst inst) { switch (inst.op) { case IROp::Mov: if (inst.dest != inst.src1) { - gpr.MapDirtyIn(inst.dest, inst.src1); + gpr.Map(inst); MV(gpr.R(inst.dest), gpr.R(inst.src1)); gpr.MarkGPRDirty(inst.dest, gpr.IsNormalized32(inst.src1)); } break; case IROp::Ext8to32: + gpr.Map(inst); if (cpu_info.RiscV_Zbb) { - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); SEXT_B(gpr.R(inst.dest), gpr.R(inst.src1)); } else { - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); SLLI(gpr.R(inst.dest), gpr.R(inst.src1), 24); SRAIW(gpr.R(inst.dest), gpr.R(inst.dest), 24); } + gpr.MarkGPRDirty(inst.dest, true); break; case IROp::Ext16to32: + gpr.Map(inst); if (cpu_info.RiscV_Zbb) { - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); SEXT_H(gpr.R(inst.dest), gpr.R(inst.src1)); } else { - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); SLLI(gpr.R(inst.dest), gpr.R(inst.src1), 16); SRAIW(gpr.R(inst.dest), gpr.R(inst.dest), 16); } + gpr.MarkGPRDirty(inst.dest, true); break; default: @@ -233,7 +238,7 @@ void RiscVJitBackend::CompIR_Bits(IRInst inst) { switch (inst.op) { case IROp::ReverseBits: if (cpu_info.RiscV_Zbb) { - gpr.MapDirtyIn(inst.dest, inst.src1); + gpr.Map(inst); // Start by reversing bytes (note: this puts in upper 32 of XLEN.) REV8(gpr.R(inst.dest), gpr.R(inst.src1)); @@ -275,7 +280,7 @@ void RiscVJitBackend::CompIR_Bits(IRInst inst) { case IROp::BSwap32: if (cpu_info.RiscV_Zbb) { - gpr.MapDirtyIn(inst.dest, inst.src1); + gpr.Map(inst); REV8(gpr.R(inst.dest), gpr.R(inst.src1)); if (XLEN >= 64) { // REV8 swaps the entire register, so get the 32 highest bits. @@ -289,9 +294,10 @@ void RiscVJitBackend::CompIR_Bits(IRInst inst) { case IROp::Clz: if (cpu_info.RiscV_Zbb) { - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); // This even sets to 32 when zero, perfect. CLZW(gpr.R(inst.dest), gpr.R(inst.src1)); + gpr.MarkGPRDirty(inst.dest, true); } else { CompIR_Generic(inst); } @@ -308,24 +314,28 @@ void RiscVJitBackend::CompIR_Shift(IRInst inst) { switch (inst.op) { case IROp::Shl: - gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); SLLW(gpr.R(inst.dest), gpr.R(inst.src1), gpr.R(inst.src2)); + gpr.MarkGPRDirty(inst.dest, true); break; case IROp::Shr: - gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); SRLW(gpr.R(inst.dest), gpr.R(inst.src1), gpr.R(inst.src2)); + gpr.MarkGPRDirty(inst.dest, true); break; case IROp::Sar: - gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); SRAW(gpr.R(inst.dest), gpr.R(inst.src1), gpr.R(inst.src2)); + gpr.MarkGPRDirty(inst.dest, true); break; case IROp::Ror: if (cpu_info.RiscV_Zbb) { - gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); RORW(gpr.R(inst.dest), gpr.R(inst.src1), gpr.R(inst.src2)); + gpr.MarkGPRDirty(inst.dest, true); } else { CompIR_Generic(inst); } @@ -337,13 +347,14 @@ void RiscVJitBackend::CompIR_Shift(IRInst inst) { gpr.SetGPRImm(inst.dest, 0); } else if (inst.src2 == 0) { if (inst.dest != inst.src1) { - gpr.MapDirtyIn(inst.dest, inst.src1); + gpr.Map(inst); MV(gpr.R(inst.dest), gpr.R(inst.src1)); gpr.MarkGPRDirty(inst.dest, gpr.IsNormalized32(inst.src1)); } } else { - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); SLLIW(gpr.R(inst.dest), gpr.R(inst.src1), inst.src2); + gpr.MarkGPRDirty(inst.dest, true); } break; @@ -353,43 +364,47 @@ void RiscVJitBackend::CompIR_Shift(IRInst inst) { gpr.SetGPRImm(inst.dest, 0); } else if (inst.src2 == 0) { if (inst.dest != inst.src1) { - gpr.MapDirtyIn(inst.dest, inst.src1); + gpr.Map(inst); MV(gpr.R(inst.dest), gpr.R(inst.src1)); gpr.MarkGPRDirty(inst.dest, gpr.IsNormalized32(inst.src1)); } } else { - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); SRLIW(gpr.R(inst.dest), gpr.R(inst.src1), inst.src2); + gpr.MarkGPRDirty(inst.dest, true); } break; case IROp::SarImm: // Shouldn't happen, but let's be safe of any passes that modify the ops. if (inst.src2 >= 32) { - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); SRAIW(gpr.R(inst.dest), gpr.R(inst.src1), 31); + gpr.MarkGPRDirty(inst.dest, true); } else if (inst.src2 == 0) { if (inst.dest != inst.src1) { - gpr.MapDirtyIn(inst.dest, inst.src1); + gpr.Map(inst); MV(gpr.R(inst.dest), gpr.R(inst.src1)); gpr.MarkGPRDirty(inst.dest, gpr.IsNormalized32(inst.src1)); } } else { - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); SRAIW(gpr.R(inst.dest), gpr.R(inst.src1), inst.src2); + gpr.MarkGPRDirty(inst.dest, true); } break; case IROp::RorImm: if (inst.src2 == 0) { if (inst.dest != inst.src1) { - gpr.MapDirtyIn(inst.dest, inst.src1); + gpr.Map(inst); MV(gpr.R(inst.dest), gpr.R(inst.src1)); gpr.MarkGPRDirty(inst.dest, gpr.IsNormalized32(inst.src1)); } } else if (cpu_info.RiscV_Zbb) { - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); RORIW(gpr.R(inst.dest), gpr.R(inst.src1), inst.src2 & 31); + gpr.MarkGPRDirty(inst.dest, true); } else { CompIR_Generic(inst); } @@ -408,25 +423,22 @@ void RiscVJitBackend::CompIR_Compare(IRInst inst) { RiscVReg rhs = INVALID_REG; switch (inst.op) { case IROp::Slt: - gpr.SpillLockGPR(inst.dest, inst.src1, inst.src2); - gpr.MapReg(inst.src1); - gpr.MapReg(inst.src2); + gpr.Map(inst); NormalizeSrc12(inst, &lhs, &rhs, SCRATCH1, SCRATCH2, true); - gpr.MapReg(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); SLT(gpr.R(inst.dest), lhs, rhs); + gpr.MarkGPRDirty(inst.dest, true); break; case IROp::SltConst: if (inst.constant == 0) { // Basically, getting the sign bit. Let's shift instead. - gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); + gpr.Map(inst); SRLIW(gpr.R(inst.dest), gpr.R(inst.src1), 31); + gpr.MarkGPRDirty(inst.dest, true); } else { - gpr.SpillLockGPR(inst.dest, inst.src1); - gpr.MapReg(inst.src1); + gpr.Map(inst); NormalizeSrc1(inst, &lhs, SCRATCH1, false); - gpr.MapReg(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); if ((int32_t)inst.constant >= -2048 && (int32_t)inst.constant <= 2047) { SLTI(gpr.R(inst.dest), lhs, (int32_t)inst.constant); @@ -439,24 +451,20 @@ void RiscVJitBackend::CompIR_Compare(IRInst inst) { break; case IROp::SltU: - gpr.SpillLockGPR(inst.dest, inst.src1, inst.src2); - gpr.MapReg(inst.src1); - gpr.MapReg(inst.src2); + gpr.Map(inst); // It's still fine to sign extend, the biggest just get even bigger. NormalizeSrc12(inst, &lhs, &rhs, SCRATCH1, SCRATCH2, true); - gpr.MapReg(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); SLTU(gpr.R(inst.dest), lhs, rhs); + gpr.MarkGPRDirty(inst.dest, true); break; case IROp::SltUConst: if (inst.constant == 0) { gpr.SetGPRImm(inst.dest, 0); } else { - gpr.SpillLockGPR(inst.dest, inst.src1); - gpr.MapReg(inst.src1); + gpr.Map(inst); NormalizeSrc1(inst, &lhs, SCRATCH1, false); - gpr.MapReg(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); // We sign extend because we're comparing against something normalized. // It's also the most efficient to set. @@ -466,6 +474,7 @@ void RiscVJitBackend::CompIR_Compare(IRInst inst) { LI(SCRATCH2, (int32_t)inst.constant); SLTU(gpr.R(inst.dest), lhs, SCRATCH2); } + gpr.MarkGPRDirty(inst.dest, true); } break; @@ -487,8 +496,8 @@ void RiscVJitBackend::CompIR_CondAssign(IRInst inst) { if (inst.dest == inst.src2) return; - // We could have a "zero" that with wrong upper due to XOR, so we have to normalize. - gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2, MapType::ALWAYS_LOAD); + // We could have a "zero" with wrong upper due to XOR, so we have to normalize. + gpr.Map(inst); NormalizeSrc1(inst, &lhs, SCRATCH1, true); switch (inst.op) { @@ -510,7 +519,7 @@ void RiscVJitBackend::CompIR_CondAssign(IRInst inst) { case IROp::Max: if (inst.src1 != inst.src2) { if (cpu_info.RiscV_Zbb) { - gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + gpr.Map(inst); NormalizeSrc12(inst, &lhs, &rhs, SCRATCH1, SCRATCH2, true); MAX(gpr.R(inst.dest), lhs, rhs); // Because we had to normalize the inputs, the output is normalized. @@ -519,7 +528,7 @@ void RiscVJitBackend::CompIR_CondAssign(IRInst inst) { CompIR_Generic(inst); } } else if (inst.dest != inst.src1) { - gpr.MapDirtyIn(inst.dest, inst.src1); + gpr.Map(inst); MV(gpr.R(inst.dest), gpr.R(inst.src1)); gpr.MarkGPRDirty(inst.dest, gpr.IsNormalized32(inst.src1)); } @@ -528,7 +537,7 @@ void RiscVJitBackend::CompIR_CondAssign(IRInst inst) { case IROp::Min: if (inst.src1 != inst.src2) { if (cpu_info.RiscV_Zbb) { - gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + gpr.Map(inst); NormalizeSrc12(inst, &lhs, &rhs, SCRATCH1, SCRATCH2, true); MIN(gpr.R(inst.dest), lhs, rhs); // Because we had to normalize the inputs, the output is normalized. @@ -537,7 +546,7 @@ void RiscVJitBackend::CompIR_CondAssign(IRInst inst) { CompIR_Generic(inst); } } else if (inst.dest != inst.src1) { - gpr.MapDirtyIn(inst.dest, inst.src1); + gpr.Map(inst); MV(gpr.R(inst.dest), gpr.R(inst.src1)); gpr.MarkGPRDirty(inst.dest, gpr.IsNormalized32(inst.src1)); } diff --git a/Core/MIPS/RiscV/RiscVCompBranch.cpp b/Core/MIPS/RiscV/RiscVCompBranch.cpp index 4b0f141649..f146fdd1ee 100644 --- a/Core/MIPS/RiscV/RiscVCompBranch.cpp +++ b/Core/MIPS/RiscV/RiscVCompBranch.cpp @@ -45,7 +45,7 @@ void RiscVJitBackend::CompIR_Exit(IRInst inst) { break; case IROp::ExitToReg: - exitReg = gpr.MapReg(inst.src1); + exitReg = gpr.MapGPR(inst.src1); FlushAll(); // TODO: If ever we don't read this back in dispatcherPCInSCRATCH1_, we should zero upper. MV(SCRATCH1, exitReg); @@ -72,7 +72,7 @@ void RiscVJitBackend::CompIR_ExitIf(IRInst inst) { switch (inst.op) { case IROp::ExitToConstIfEq: case IROp::ExitToConstIfNeq: - gpr.MapInIn(inst.src1, inst.src2); + gpr.Map(inst); // We can't use SCRATCH1, which is destroyed by FlushAll()... but cheat and use R_RA. NormalizeSrc12(inst, &lhs, &rhs, R_RA, SCRATCH2, true); FlushAll(); @@ -99,7 +99,7 @@ void RiscVJitBackend::CompIR_ExitIf(IRInst inst) { case IROp::ExitToConstIfGeZ: case IROp::ExitToConstIfLtZ: case IROp::ExitToConstIfLeZ: - gpr.MapReg(inst.src1); + gpr.Map(inst); NormalizeSrc1(inst, &lhs, SCRATCH2, true); FlushAll(); diff --git a/Core/MIPS/RiscV/RiscVCompFPU.cpp b/Core/MIPS/RiscV/RiscVCompFPU.cpp index 7b92468713..5e668ce907 100644 --- a/Core/MIPS/RiscV/RiscVCompFPU.cpp +++ b/Core/MIPS/RiscV/RiscVCompFPU.cpp @@ -39,34 +39,34 @@ void RiscVJitBackend::CompIR_FArith(IRInst inst) { switch (inst.op) { case IROp::FAdd: - fpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + fpr.Map(inst); FADD(32, fpr.R(inst.dest), fpr.R(inst.src1), fpr.R(inst.src2)); break; case IROp::FSub: - fpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + fpr.Map(inst); FSUB(32, fpr.R(inst.dest), fpr.R(inst.src1), fpr.R(inst.src2)); break; case IROp::FMul: - fpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + fpr.Map(inst); // We'll assume everyone will make it such that 0 * infinity = NAN properly. // See blame on this comment if that proves untrue. FMUL(32, fpr.R(inst.dest), fpr.R(inst.src1), fpr.R(inst.src2)); break; case IROp::FDiv: - fpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + fpr.Map(inst); FDIV(32, fpr.R(inst.dest), fpr.R(inst.src1), fpr.R(inst.src2)); break; case IROp::FSqrt: - fpr.MapDirtyIn(inst.dest, inst.src1); + fpr.Map(inst); FSQRT(32, fpr.R(inst.dest), fpr.R(inst.src1)); break; case IROp::FNeg: - fpr.MapDirtyIn(inst.dest, inst.src1); + fpr.Map(inst); FNEG(32, fpr.R(inst.dest), fpr.R(inst.src1)); break; @@ -83,7 +83,7 @@ void RiscVJitBackend::CompIR_FCondAssign(IRInst inst) { bool maxCondition = inst.op == IROp::FMax; // FMin and FMax are used by VFPU and handle NAN/INF as just a larger exponent. - fpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + fpr.Map(inst); FCLASS(32, SCRATCH1, fpr.R(inst.src1)); FCLASS(32, SCRATCH2, fpr.R(inst.src2)); @@ -146,19 +146,19 @@ void RiscVJitBackend::CompIR_FAssign(IRInst inst) { switch (inst.op) { case IROp::FMov: if (inst.dest != inst.src1) { - fpr.MapDirtyIn(inst.dest, inst.src1); + fpr.Map(inst); FMV(32, fpr.R(inst.dest), fpr.R(inst.src1)); } break; case IROp::FAbs: - fpr.MapDirtyIn(inst.dest, inst.src1); + fpr.Map(inst); FABS(32, fpr.R(inst.dest), fpr.R(inst.src1)); break; case IROp::FSign: { - fpr.MapDirtyIn(inst.dest, inst.src1); + fpr.Map(inst); // Check if it's negative zero, either 0x10/0x08 is zero. FCLASS(32, SCRATCH1, fpr.R(inst.src1)); ANDI(SCRATCH1, SCRATCH1, 0x18); @@ -190,7 +190,7 @@ void RiscVJitBackend::CompIR_FRound(IRInst inst) { CONDITIONAL_DISABLE; // TODO: If this is followed by a GPR transfer, might want to combine. - fpr.MapDirtyIn(inst.dest, inst.src1); + fpr.Map(inst); switch (inst.op) { case IROp::FRound: @@ -228,7 +228,7 @@ void RiscVJitBackend::CompIR_FCvt(IRInst inst) { case IROp::FCvtSW: // TODO: This is probably proceeded by a GPR transfer, might be ideal to combine. - fpr.MapDirtyIn(inst.dest, inst.src1); + fpr.Map(inst); FMV(FMv::X, FMv::W, SCRATCH1, fpr.R(inst.src1)); FCVT(FConv::S, FConv::W, fpr.R(inst.dest), SCRATCH1); break; @@ -340,7 +340,7 @@ void RiscVJitBackend::CompIR_FSat(IRInst inst) { void RiscVJitBackend::CompIR_FCompare(IRInst inst) { CONDITIONAL_DISABLE; - constexpr IRReg IRREG_VFPUL_CC = IRREG_VFPU_CTRL_BASE + VFPU_CTRL_CC; + constexpr IRReg IRREG_VFPU_CC = IRREG_VFPU_CTRL_BASE + VFPU_CTRL_CC; switch (inst.op) { case IROp::FCmp: @@ -350,8 +350,8 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) { break; case IRFpCompareMode::EitherUnordered: - fpr.MapInIn(inst.src1, inst.src2); - gpr.MapReg(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + fpr.Map(inst); + gpr.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); FCLASS(32, SCRATCH1, fpr.R(inst.src1)); FCLASS(32, SCRATCH2, fpr.R(inst.src2)); OR(SCRATCH1, SCRATCH1, SCRATCH2); @@ -361,14 +361,14 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) { break; case IRFpCompareMode::EqualOrdered: - fpr.MapInIn(inst.src1, inst.src2); - gpr.MapReg(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + fpr.Map(inst); + gpr.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); FEQ(32, gpr.R(IRREG_FPCOND), fpr.R(inst.src1), fpr.R(inst.src2)); break; case IRFpCompareMode::EqualUnordered: - fpr.MapInIn(inst.src1, inst.src2); - gpr.MapReg(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + fpr.Map(inst); + gpr.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); FEQ(32, gpr.R(IRREG_FPCOND), fpr.R(inst.src1), fpr.R(inst.src2)); // Now let's just OR in the unordered check. @@ -382,27 +382,27 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) { break; case IRFpCompareMode::LessEqualOrdered: - fpr.MapInIn(inst.src1, inst.src2); - gpr.MapReg(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + fpr.Map(inst); + gpr.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); FLE(32, gpr.R(IRREG_FPCOND), fpr.R(inst.src1), fpr.R(inst.src2)); break; case IRFpCompareMode::LessEqualUnordered: - fpr.MapInIn(inst.src1, inst.src2); - gpr.MapReg(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + fpr.Map(inst); + gpr.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); FLT(32, gpr.R(IRREG_FPCOND), fpr.R(inst.src2), fpr.R(inst.src1)); SEQZ(gpr.R(IRREG_FPCOND), gpr.R(IRREG_FPCOND)); break; case IRFpCompareMode::LessOrdered: - fpr.MapInIn(inst.src1, inst.src2); - gpr.MapReg(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + fpr.Map(inst); + gpr.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); FLT(32, gpr.R(IRREG_FPCOND), fpr.R(inst.src1), fpr.R(inst.src2)); break; case IRFpCompareMode::LessUnordered: - fpr.MapInIn(inst.src1, inst.src2); - gpr.MapReg(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + fpr.Map(inst); + gpr.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); FLE(32, gpr.R(IRREG_FPCOND), fpr.R(inst.src2), fpr.R(inst.src1)); SEQZ(gpr.R(IRREG_FPCOND), gpr.R(IRREG_FPCOND)); break; @@ -410,14 +410,14 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) { break; case IROp::FCmovVfpuCC: - gpr.MapReg(IRREG_VFPUL_CC); - fpr.MapDirtyIn(inst.dest, inst.src1, false); + gpr.MapGPR(IRREG_VFPU_CC); + fpr.Map(inst); if ((inst.src2 & 0xF) == 0) { - ANDI(SCRATCH1, gpr.R(IRREG_VFPUL_CC), 1); + ANDI(SCRATCH1, gpr.R(IRREG_VFPU_CC), 1); } else if (cpu_info.RiscV_Zbs) { - BEXTI(SCRATCH1, gpr.R(IRREG_VFPUL_CC), inst.src2 & 0xF); + BEXTI(SCRATCH1, gpr.R(IRREG_VFPU_CC), inst.src2 & 0xF); } else { - SRLI(SCRATCH1, gpr.R(IRREG_VFPUL_CC), inst.src2 & 0xF); + SRLI(SCRATCH1, gpr.R(IRREG_VFPU_CC), inst.src2 & 0xF); ANDI(SCRATCH1, SCRATCH1, 1); } if ((inst.src2 >> 7) & 1) { @@ -432,15 +432,15 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) { break; case IROp::FCmpVfpuBit: - gpr.MapReg(IRREG_VFPUL_CC, MIPSMap::DIRTY); + gpr.MapGPR(IRREG_VFPU_CC, MIPSMap::DIRTY); switch (VCondition(inst.dest & 0xF)) { case VC_EQ: - fpr.MapInIn(inst.src1, inst.src2); + fpr.Map(inst); FEQ(32, SCRATCH1, fpr.R(inst.src1), fpr.R(inst.src2)); break; case VC_NE: - fpr.MapInIn(inst.src1, inst.src2); + fpr.Map(inst); // We could almost negate FEQ, except NAN != NAN. // Anything != NAN is false and NAN != NAN is within that, so we only check one side. FCLASS(32, SCRATCH2, fpr.R(inst.src2)); @@ -454,24 +454,24 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) { OR(SCRATCH1, SCRATCH1, SCRATCH2); break; case VC_LT: - fpr.MapInIn(inst.src1, inst.src2); + fpr.Map(inst); FLT(32, SCRATCH1, fpr.R(inst.src1), fpr.R(inst.src2)); break; case VC_LE: - fpr.MapInIn(inst.src1, inst.src2); + fpr.Map(inst); FLE(32, SCRATCH1, fpr.R(inst.src1), fpr.R(inst.src2)); break; case VC_GT: - fpr.MapInIn(inst.src1, inst.src2); + fpr.Map(inst); FLT(32, SCRATCH1, fpr.R(inst.src2), fpr.R(inst.src1)); break; case VC_GE: - fpr.MapInIn(inst.src1, inst.src2); + fpr.Map(inst); FLE(32, SCRATCH1, fpr.R(inst.src2), fpr.R(inst.src1)); break; case VC_EZ: case VC_NZ: - fpr.MapReg(inst.src1); + fpr.MapFPR(inst.src1); // Zero is either 0x10 or 0x08. FCLASS(32, SCRATCH1, fpr.R(inst.src1)); ANDI(SCRATCH1, SCRATCH1, 0x18); @@ -482,7 +482,7 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) { break; case VC_EN: case VC_NN: - fpr.MapReg(inst.src1); + fpr.MapFPR(inst.src1); // NAN is either 0x100 or 0x200. FCLASS(32, SCRATCH1, fpr.R(inst.src1)); ANDI(SCRATCH1, SCRATCH1, 0x300); @@ -493,7 +493,7 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) { break; case VC_EI: case VC_NI: - fpr.MapReg(inst.src1); + fpr.MapFPR(inst.src1); // Infinity is either 0x80 or 0x01. FCLASS(32, SCRATCH1, fpr.R(inst.src1)); ANDI(SCRATCH1, SCRATCH1, 0x81); @@ -504,7 +504,7 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) { break; case VC_ES: case VC_NS: - fpr.MapReg(inst.src1); + fpr.MapFPR(inst.src1); // Infinity is either 0x80 or 0x01, NAN is either 0x100 or 0x200. FCLASS(32, SCRATCH1, fpr.R(inst.src1)); ANDI(SCRATCH1, SCRATCH1, 0x381); @@ -521,15 +521,15 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) { break; } - ANDI(gpr.R(IRREG_VFPUL_CC), gpr.R(IRREG_VFPUL_CC), ~(1 << (inst.dest >> 4))); + ANDI(gpr.R(IRREG_VFPU_CC), gpr.R(IRREG_VFPU_CC), ~(1 << (inst.dest >> 4))); if ((inst.dest >> 4) != 0) SLLI(SCRATCH1, SCRATCH1, inst.dest >> 4); - OR(gpr.R(IRREG_VFPUL_CC), gpr.R(IRREG_VFPUL_CC), SCRATCH1); + OR(gpr.R(IRREG_VFPU_CC), gpr.R(IRREG_VFPU_CC), SCRATCH1); break; case IROp::FCmpVfpuAggregate: - gpr.MapReg(IRREG_VFPUL_CC, MIPSMap::DIRTY); - ANDI(SCRATCH1, gpr.R(IRREG_VFPUL_CC), inst.dest); + gpr.MapGPR(IRREG_VFPU_CC, MIPSMap::DIRTY); + ANDI(SCRATCH1, gpr.R(IRREG_VFPU_CC), inst.dest); // This is the "any bit", easy. SNEZ(SCRATCH2, SCRATCH1); // To compare to inst.dest for "all", let's simply subtract it and compare to zero. @@ -541,8 +541,8 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) { OR(SCRATCH1, SCRATCH1, SCRATCH2); // Reject those any/all bits and replace them with our own. - ANDI(gpr.R(IRREG_VFPUL_CC), gpr.R(IRREG_VFPUL_CC), ~0x30); - OR(gpr.R(IRREG_VFPUL_CC), gpr.R(IRREG_VFPUL_CC), SCRATCH1); + ANDI(gpr.R(IRREG_VFPU_CC), gpr.R(IRREG_VFPU_CC), ~0x30); + OR(gpr.R(IRREG_VFPU_CC), gpr.R(IRREG_VFPU_CC), SCRATCH1); break; default: @@ -592,7 +592,7 @@ void RiscVJitBackend::CompIR_FSpecial(IRInst inst) { } QuickCallFunction(func, SCRATCH1); - fpr.MapReg(inst.dest, MIPSMap::NOINIT); + fpr.MapFPR(inst.dest, MIPSMap::NOINIT); // If it's already F10, we're done - MapReg doesn't actually overwrite the reg in that case. if (fpr.R(inst.dest) != F10) { FMV(32, fpr.R(inst.dest), F10); @@ -622,7 +622,7 @@ void RiscVJitBackend::CompIR_FSpecial(IRInst inst) { case IROp::FRecip: if (inst.dest != inst.src1) { // This is the easy case. - fpr.MapDirtyIn(inst.dest, inst.src1); + fpr.Map(inst); LI(SCRATCH1, 1.0f); FMV(FMv::W, FMv::X, fpr.R(inst.dest), SCRATCH1); FDIV(32, fpr.R(inst.dest), fpr.R(inst.dest), fpr.R(inst.src1)); diff --git a/Core/MIPS/RiscV/RiscVCompLoadStore.cpp b/Core/MIPS/RiscV/RiscVCompLoadStore.cpp index 348221ef4b..223cb9abe1 100644 --- a/Core/MIPS/RiscV/RiscVCompLoadStore.cpp +++ b/Core/MIPS/RiscV/RiscVCompLoadStore.cpp @@ -35,7 +35,7 @@ using namespace RiscVGen; using namespace RiscVJitConstants; void RiscVJitBackend::SetScratch1ToSrc1Address(IRReg src1) { - gpr.MapReg(src1); + gpr.MapGPR(src1); #ifdef MASKED_PSP_MEMORY SLLIW(SCRATCH1, gpr.R(src1), 2); SRLIW(SCRATCH1, SCRATCH1, 2); @@ -75,13 +75,13 @@ void RiscVJitBackend::CompIR_Load(IRInst inst) { inst.constant &= Memory::MEMVIEW32_MASK; #endif } else if (jo.cachePointers || gpr.IsGPRMappedAsPointer(inst.src1)) { - addrReg = gpr.MapRegAsPointer(inst.src1); + addrReg = gpr.MapGPRAsPointer(inst.src1); } else { SetScratch1ToSrc1Address(inst.src1); addrReg = SCRATCH1; } // With NOINIT, MapReg won't subtract MEMBASEREG even if dest == src1. - gpr.MapReg(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + gpr.MapGPR(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); s32 imm = AdjustForAddressOffset(&addrReg, inst.constant); @@ -147,7 +147,7 @@ void RiscVJitBackend::CompIR_FLoad(IRInst inst) { inst.constant &= Memory::MEMVIEW32_MASK; #endif } else if (jo.cachePointers || gpr.IsGPRMappedAsPointer(inst.src1)) { - addrReg = gpr.MapRegAsPointer(inst.src1); + addrReg = gpr.MapGPRAsPointer(inst.src1); } else { SetScratch1ToSrc1Address(inst.src1); addrReg = SCRATCH1; @@ -159,7 +159,7 @@ void RiscVJitBackend::CompIR_FLoad(IRInst inst) { switch (inst.op) { case IROp::LoadFloat: - fpr.MapReg(inst.dest, MIPSMap::NOINIT); + fpr.MapFPR(inst.dest, MIPSMap::NOINIT); FL(32, fpr.R(inst.dest), addrReg, imm); break; @@ -180,7 +180,7 @@ void RiscVJitBackend::CompIR_VecLoad(IRInst inst) { inst.constant &= Memory::MEMVIEW32_MASK; #endif } else if (jo.cachePointers || gpr.IsGPRMappedAsPointer(inst.src1)) { - addrReg = gpr.MapRegAsPointer(inst.src1); + addrReg = gpr.MapGPRAsPointer(inst.src1); } else { SetScratch1ToSrc1Address(inst.src1); addrReg = SCRATCH1; @@ -195,7 +195,7 @@ void RiscVJitBackend::CompIR_VecLoad(IRInst inst) { case IROp::LoadVec4: for (int i = 0; i < 4; ++i) { // Spilling is okay. - fpr.MapReg(inst.dest + i, MIPSMap::NOINIT); + fpr.MapFPR(inst.dest + i, MIPSMap::NOINIT); FL(32, fpr.R(inst.dest + i), addrReg, imm + 4 * i); } break; @@ -218,14 +218,14 @@ void RiscVJitBackend::CompIR_Store(IRInst inst) { inst.constant &= Memory::MEMVIEW32_MASK; #endif } else if ((jo.cachePointers || gpr.IsGPRMappedAsPointer(inst.src1)) && inst.src3 != inst.src1) { - addrReg = gpr.MapRegAsPointer(inst.src1); + addrReg = gpr.MapGPRAsPointer(inst.src1); } else { SetScratch1ToSrc1Address(inst.src1); addrReg = SCRATCH1; } RiscVReg valueReg = gpr.TryMapTempImm(inst.src3); if (valueReg == INVALID_REG) - valueReg = gpr.MapReg(inst.src3); + valueReg = gpr.MapGPR(inst.src3); s32 imm = AdjustForAddressOffset(&addrReg, inst.constant); @@ -264,13 +264,13 @@ void RiscVJitBackend::CompIR_CondStore(IRInst inst) { inst.constant &= Memory::MEMVIEW32_MASK; #endif } else if ((jo.cachePointers || gpr.IsGPRMappedAsPointer(inst.src1)) && inst.src3 != inst.src1) { - addrReg = gpr.MapRegAsPointer(inst.src1); + addrReg = gpr.MapGPRAsPointer(inst.src1); } else { SetScratch1ToSrc1Address(inst.src1); addrReg = SCRATCH1; } - gpr.MapReg(inst.src3, inst.dest == MIPS_REG_ZERO ? MIPSMap::INIT : MIPSMap::DIRTY); - gpr.MapReg(IRREG_LLBIT); + gpr.MapGPR(inst.src3, inst.dest == MIPS_REG_ZERO ? MIPSMap::INIT : MIPSMap::DIRTY); + gpr.MapGPR(IRREG_LLBIT); s32 imm = AdjustForAddressOffset(&addrReg, inst.constant); @@ -318,7 +318,7 @@ void RiscVJitBackend::CompIR_FStore(IRInst inst) { inst.constant &= Memory::MEMVIEW32_MASK; #endif } else if (jo.cachePointers || gpr.IsGPRMappedAsPointer(inst.src1)) { - addrReg = gpr.MapRegAsPointer(inst.src1); + addrReg = gpr.MapGPRAsPointer(inst.src1); } else { SetScratch1ToSrc1Address(inst.src1); addrReg = SCRATCH1; @@ -330,7 +330,7 @@ void RiscVJitBackend::CompIR_FStore(IRInst inst) { switch (inst.op) { case IROp::StoreFloat: - fpr.MapReg(inst.src3); + fpr.MapFPR(inst.src3); FS(32, fpr.R(inst.src3), addrReg, imm); break; @@ -351,7 +351,7 @@ void RiscVJitBackend::CompIR_VecStore(IRInst inst) { inst.constant &= Memory::MEMVIEW32_MASK; #endif } else if (jo.cachePointers || gpr.IsGPRMappedAsPointer(inst.src1)) { - addrReg = gpr.MapRegAsPointer(inst.src1); + addrReg = gpr.MapGPRAsPointer(inst.src1); } else { SetScratch1ToSrc1Address(inst.src1); addrReg = SCRATCH1; @@ -366,7 +366,7 @@ void RiscVJitBackend::CompIR_VecStore(IRInst inst) { case IROp::StoreVec4: for (int i = 0; i < 4; ++i) { // Spilling is okay, though not ideal. - fpr.MapReg(inst.src3 + i); + fpr.MapFPR(inst.src3 + i); FS(32, fpr.R(inst.src3 + i), addrReg, imm + 4 * i); } break; diff --git a/Core/MIPS/RiscV/RiscVCompSystem.cpp b/Core/MIPS/RiscV/RiscVCompSystem.cpp index ce41e6faf0..b655bbda74 100644 --- a/Core/MIPS/RiscV/RiscVCompSystem.cpp +++ b/Core/MIPS/RiscV/RiscVCompSystem.cpp @@ -49,7 +49,7 @@ void RiscVJitBackend::CompIR_Basic(IRInst inst) { break; case IROp::SetConstF: - fpr.MapReg(inst.dest, MIPSMap::NOINIT); + fpr.Map(inst); if (inst.constant == 0) { FCVT(FConv::S, FConv::W, fpr.R(inst.dest), R_ZERO); } else { @@ -70,7 +70,7 @@ void RiscVJitBackend::CompIR_Basic(IRInst inst) { break; case IROp::SetPC: - gpr.MapIn(inst.src1); + gpr.Map(inst); MovToPC(gpr.R(inst.src1)); break; @@ -100,8 +100,8 @@ void RiscVJitBackend::CompIR_Transfer(IRInst inst) { break; case IROp::SetCtrlVFPUFReg: - gpr.MapReg(IRREG_VFPU_CTRL_BASE + inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); - fpr.MapReg(inst.src1); + gpr.MapGPR(IRREG_VFPU_CTRL_BASE + inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + fpr.MapFPR(inst.src1); FMV(FMv::X, FMv::W, gpr.R(IRREG_VFPU_CTRL_BASE + inst.dest), fpr.R(inst.src1)); break; @@ -157,18 +157,18 @@ void RiscVJitBackend::CompIR_Transfer(IRInst inst) { break; case IROp::FMovFromGPR: - fpr.MapReg(inst.dest, MIPSMap::NOINIT); + fpr.MapFPR(inst.dest, MIPSMap::NOINIT); if (gpr.IsGPRImm(inst.src1) && gpr.GetGPRImm(inst.src1) == 0) { FCVT(FConv::S, FConv::W, fpr.R(inst.dest), R_ZERO); } else { - gpr.MapReg(inst.src1); + gpr.MapGPR(inst.src1); FMV(FMv::W, FMv::X, fpr.R(inst.dest), gpr.R(inst.src1)); } break; case IROp::FMovToGPR: - gpr.MapReg(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); - fpr.MapReg(inst.src1); + gpr.MapGPR(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + fpr.MapFPR(inst.src1); FMV(FMv::X, FMv::W, gpr.R(inst.dest), fpr.R(inst.src1)); break; diff --git a/Core/MIPS/RiscV/RiscVCompVec.cpp b/Core/MIPS/RiscV/RiscVCompVec.cpp index 3e0f5c1d34..c196c3f68b 100644 --- a/Core/MIPS/RiscV/RiscVCompVec.cpp +++ b/Core/MIPS/RiscV/RiscVCompVec.cpp @@ -40,10 +40,7 @@ void RiscVJitBackend::CompIR_VecAssign(IRInst inst) { switch (inst.op) { case IROp::Vec4Init: - for (int i = 0; i < 4; ++i) - fpr.SpillLockFPR(inst.dest + i); - for (int i = 0; i < 4; ++i) - fpr.MapReg(inst.dest + i, MIPSMap::NOINIT); + fpr.Map(inst); // TODO: Check if FCVT/FMV/FL is better. switch ((Vec4Init)inst.src1) { @@ -161,7 +158,7 @@ void RiscVJitBackend::CompIR_VecAssign(IRInst inst) { moveChained({ neededByDepth2, neededBy, i, foundIn }, neededByDepth3 == foundIn); } } else { - fpr.Map4DirtyIn(inst.dest, inst.src1); + fpr.Map(inst); for (int i = 0; i < 4; ++i) { int lane = (inst.src2 >> (i * 2)) & 3; FMV(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + lane)); @@ -170,7 +167,7 @@ void RiscVJitBackend::CompIR_VecAssign(IRInst inst) { break; case IROp::Vec4Blend: - fpr.Map4DirtyInIn(inst.dest, inst.src1, inst.src2); + fpr.Map(inst); for (int i = 0; i < 4; ++i) { int which = (inst.constant >> i) & 1; FMV(32, fpr.R(inst.dest + i), fpr.R((which ? inst.src2 : inst.src1) + i)); @@ -178,7 +175,7 @@ void RiscVJitBackend::CompIR_VecAssign(IRInst inst) { break; case IROp::Vec4Mov: - fpr.Map4DirtyIn(inst.dest, inst.src1); + fpr.Map(inst); for (int i = 0; i < 4; ++i) FMV(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i)); break; @@ -194,45 +191,45 @@ void RiscVJitBackend::CompIR_VecArith(IRInst inst) { switch (inst.op) { case IROp::Vec4Add: - fpr.Map4DirtyInIn(inst.dest, inst.src1, inst.src2); + fpr.Map(inst); for (int i = 0; i < 4; ++i) FADD(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i), fpr.R(inst.src2 + i)); break; case IROp::Vec4Sub: - fpr.Map4DirtyInIn(inst.dest, inst.src1, inst.src2); + fpr.Map(inst); for (int i = 0; i < 4; ++i) FSUB(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i), fpr.R(inst.src2 + i)); break; case IROp::Vec4Mul: - fpr.Map4DirtyInIn(inst.dest, inst.src1, inst.src2); + fpr.Map(inst); for (int i = 0; i < 4; ++i) FMUL(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i), fpr.R(inst.src2 + i)); break; case IROp::Vec4Div: - fpr.Map4DirtyInIn(inst.dest, inst.src1, inst.src2); + fpr.Map(inst); for (int i = 0; i < 4; ++i) FDIV(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i), fpr.R(inst.src2 + i)); break; case IROp::Vec4Scale: fpr.SpillLockFPR(inst.src2); - fpr.MapReg(inst.src2); + fpr.MapFPR(inst.src2); fpr.Map4DirtyIn(inst.dest, inst.src1); for (int i = 0; i < 4; ++i) FMUL(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i), fpr.R(inst.src2)); break; case IROp::Vec4Neg: - fpr.Map4DirtyIn(inst.dest, inst.src1); + fpr.Map(inst); for (int i = 0; i < 4; ++i) FNEG(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i)); break; case IROp::Vec4Abs: - fpr.Map4DirtyIn(inst.dest, inst.src1); + fpr.Map(inst); for (int i = 0; i < 4; ++i) FABS(32, fpr.R(inst.dest + i), fpr.R(inst.src1 + i)); break; @@ -255,10 +252,10 @@ void RiscVJitBackend::CompIR_VecHoriz(IRInst inst) { fpr.SpillLockFPR(inst.src2 + i); } for (int i = 0; i < 4; ++i) { - fpr.MapReg(inst.src1 + i); - fpr.MapReg(inst.src2 + i); + fpr.MapFPR(inst.src1 + i); + fpr.MapFPR(inst.src2 + i); } - fpr.MapReg(inst.dest, MIPSMap::NOINIT); + fpr.MapFPR(inst.dest, MIPSMap::NOINIT); if ((inst.dest < inst.src1 + 4 && inst.dest >= inst.src1) || (inst.dest < inst.src2 + 4 && inst.dest >= inst.src2)) { // This means inst.dest overlaps one of src1 or src2. We have to do that one first. @@ -298,9 +295,9 @@ void RiscVJitBackend::CompIR_VecPack(IRInst inst) { fpr.SpillLockFPR(inst.src1); for (int i = 0; i < 4; ++i) fpr.SpillLockFPR(inst.dest + i); - fpr.MapReg(inst.src1); + fpr.MapFPR(inst.src1); for (int i = 0; i < 4; ++i) - fpr.MapReg(inst.dest + i, MIPSMap::NOINIT); + fpr.MapFPR(inst.dest + i, MIPSMap::NOINIT); FMV(FMv::X, FMv::W, SCRATCH2, fpr.R(inst.src1)); for (int i = 0; i < 4; ++i) { @@ -319,9 +316,9 @@ void RiscVJitBackend::CompIR_VecPack(IRInst inst) { fpr.SpillLockFPR(inst.src1); for (int i = 0; i < 2; ++i) fpr.SpillLockFPR(inst.dest + i); - fpr.MapReg(inst.src1); + fpr.MapFPR(inst.src1); for (int i = 0; i < 2; ++i) - fpr.MapReg(inst.dest + i, MIPSMap::NOINIT); + fpr.MapFPR(inst.dest + i, MIPSMap::NOINIT); FMV(FMv::X, FMv::W, SCRATCH2, fpr.R(inst.src1)); SLLI(SCRATCH1, SCRATCH2, 16); @@ -332,7 +329,7 @@ void RiscVJitBackend::CompIR_VecPack(IRInst inst) { break; case IROp::Vec4DuplicateUpperBitsAndShift1: - fpr.Map4DirtyIn(inst.dest, inst.src1); + fpr.Map(inst); for (int i = 0; i < 4; i++) { FMV(FMv::X, FMv::W, SCRATCH1, fpr.R(inst.src1 + i)); SRLIW(SCRATCH2, SCRATCH1, 8); @@ -348,9 +345,9 @@ void RiscVJitBackend::CompIR_VecPack(IRInst inst) { fpr.SpillLockFPR(inst.dest); for (int i = 0; i < 4; ++i) { fpr.SpillLockFPR(inst.src1 + i); - fpr.MapReg(inst.src1 + i); + fpr.MapFPR(inst.src1 + i); } - fpr.MapReg(inst.dest, MIPSMap::NOINIT); + fpr.MapFPR(inst.dest, MIPSMap::NOINIT); for (int i = 0; i < 4; ++i) { FMV(FMv::X, FMv::W, SCRATCH1, fpr.R(inst.src1 + i)); @@ -394,7 +391,7 @@ void RiscVJitBackend::CompIR_VecClamp(IRInst inst) { switch (inst.op) { case IROp::Vec4ClampToZero: - fpr.Map4DirtyIn(inst.dest, inst.src1); + fpr.Map(inst); for (int i = 0; i < 4; i++) { FMV(FMv::X, FMv::W, SCRATCH1, fpr.R(inst.src1 + i)); SRAIW(SCRATCH2, SCRATCH1, 31); diff --git a/Core/MIPS/RiscV/RiscVRegCache.cpp b/Core/MIPS/RiscV/RiscVRegCache.cpp index e364a2ab97..976c3abaaf 100644 --- a/Core/MIPS/RiscV/RiscVRegCache.cpp +++ b/Core/MIPS/RiscV/RiscVRegCache.cpp @@ -32,7 +32,7 @@ using namespace RiscVJitConstants; RiscVRegCache::RiscVRegCache(MIPSComp::JitOptions *jo) : IRNativeRegCacheBase(jo) { // TODO: Move to using for FPRs and VPRs too? - totalNativeRegs_ = NUM_RVREG; + config_.totalNativeRegs = NUM_RVREG; } void RiscVRegCache::Init(RiscVEmitter *emitter) { @@ -220,7 +220,7 @@ RiscVReg RiscVRegCache::GetAndLockTempR() { return reg; } -RiscVReg RiscVRegCache::MapReg(IRReg mipsReg, MIPSMap mapFlags) { +RiscVReg RiscVRegCache::MapGPR(IRReg mipsReg, MIPSMap mapFlags) { _dbg_assert_(IsValidGPR(mipsReg)); // Okay, not mapped, so we need to allocate an RV register. @@ -228,60 +228,28 @@ RiscVReg RiscVRegCache::MapReg(IRReg mipsReg, MIPSMap mapFlags) { return (RiscVReg)nreg; } -RiscVReg RiscVRegCache::MapRegAsPointer(IRReg reg) { +RiscVReg RiscVRegCache::MapGPRAsPointer(IRReg reg) { return (RiscVReg)MapNativeRegAsPointer(reg); } -void RiscVRegCache::MapIn(IRReg rs) { - MapReg(rs); -} - -void RiscVRegCache::MapInIn(IRReg rd, IRReg rs) { - SpillLockGPR(rd, rs); - MapReg(rd); - MapReg(rs); - ReleaseSpillLockGPR(rd, rs); -} - void RiscVRegCache::MapDirtyIn(IRReg rd, IRReg rs, MapType type) { SpillLockGPR(rd, rs); bool load = type == MapType::ALWAYS_LOAD || rd == rs; MIPSMap norm32 = type == MapType::AVOID_LOAD_MARK_NORM32 ? MIPSMap::MARK_NORM32 : MIPSMap::INIT; - MapReg(rd, (load ? MIPSMap::DIRTY : MIPSMap::NOINIT) | norm32); - MapReg(rs); + MapGPR(rd, (load ? MIPSMap::DIRTY : MIPSMap::NOINIT) | norm32); + MapGPR(rs); ReleaseSpillLockGPR(rd, rs); } -void RiscVRegCache::MapDirtyInIn(IRReg rd, IRReg rs, IRReg rt, MapType type) { - SpillLockGPR(rd, rs, rt); - bool load = type == MapType::ALWAYS_LOAD || (rd == rs || rd == rt); - MIPSMap norm32 = type == MapType::AVOID_LOAD_MARK_NORM32 ? MIPSMap::MARK_NORM32 : MIPSMap::INIT; - MapReg(rd, (load ? MIPSMap::DIRTY : MIPSMap::NOINIT) | norm32); - MapReg(rt); - MapReg(rs); - ReleaseSpillLockGPR(rd, rs, rt); -} - -void RiscVRegCache::MapDirtyDirtyIn(IRReg rd1, IRReg rd2, IRReg rs, MapType type) { - SpillLockGPR(rd1, rd2, rs); - bool load1 = type == MapType::ALWAYS_LOAD || rd1 == rs; - bool load2 = type == MapType::ALWAYS_LOAD || rd2 == rs; - MIPSMap norm32 = type == MapType::AVOID_LOAD_MARK_NORM32 ? MIPSMap::MARK_NORM32 : MIPSMap::INIT; - MapReg(rd1, (load1 ? MIPSMap::DIRTY : MIPSMap::NOINIT) | norm32); - MapReg(rd2, (load2 ? MIPSMap::DIRTY : MIPSMap::NOINIT) | norm32); - MapReg(rs); - ReleaseSpillLockGPR(rd1, rd2, rs); -} - void RiscVRegCache::MapDirtyDirtyInIn(IRReg rd1, IRReg rd2, IRReg rs, IRReg rt, MapType type) { SpillLockGPR(rd1, rd2, rs, rt); bool load1 = type == MapType::ALWAYS_LOAD || (rd1 == rs || rd1 == rt); bool load2 = type == MapType::ALWAYS_LOAD || (rd2 == rs || rd2 == rt); MIPSMap norm32 = type == MapType::AVOID_LOAD_MARK_NORM32 ? MIPSMap::MARK_NORM32 : MIPSMap::INIT; - MapReg(rd1, (load1 ? MIPSMap::DIRTY : MIPSMap::NOINIT) | norm32); - MapReg(rd2, (load2 ? MIPSMap::DIRTY : MIPSMap::NOINIT) | norm32); - MapReg(rt); - MapReg(rs); + MapGPR(rd1, (load1 ? MIPSMap::DIRTY : MIPSMap::NOINIT) | norm32); + MapGPR(rd2, (load2 ? MIPSMap::DIRTY : MIPSMap::NOINIT) | norm32); + MapGPR(rt); + MapGPR(rs); ReleaseSpillLockGPR(rd1, rd2, rs, rt); } diff --git a/Core/MIPS/RiscV/RiscVRegCache.h b/Core/MIPS/RiscV/RiscVRegCache.h index 9080c4c783..2d0619cca5 100644 --- a/Core/MIPS/RiscV/RiscVRegCache.h +++ b/Core/MIPS/RiscV/RiscVRegCache.h @@ -52,19 +52,15 @@ public: // May fail and return INVALID_REG if it needs flushing. RiscVGen::RiscVReg TryMapTempImm(IRReg); - // Returns an ARM register containing the requested MIPS register. - RiscVGen::RiscVReg MapReg(IRReg reg, MIPSMap mapFlags = MIPSMap::INIT); - RiscVGen::RiscVReg MapRegAsPointer(IRReg reg); + // Returns an RV register containing the requested MIPS register. + RiscVGen::RiscVReg MapGPR(IRReg reg, MIPSMap mapFlags = MIPSMap::INIT); + RiscVGen::RiscVReg MapGPRAsPointer(IRReg reg); bool IsNormalized32(IRReg reg); // Copies to another reg if specified, otherwise same reg. RiscVGen::RiscVReg Normalize32(IRReg reg, RiscVGen::RiscVReg destReg = RiscVGen::INVALID_REG); - void MapIn(IRReg rs); - void MapInIn(IRReg rd, IRReg rs); void MapDirtyIn(IRReg rd, IRReg rs, RiscVJitConstants::MapType type = RiscVJitConstants::MapType::AVOID_LOAD); - void MapDirtyInIn(IRReg rd, IRReg rs, IRReg rt, RiscVJitConstants::MapType type = RiscVJitConstants::MapType::AVOID_LOAD); - void MapDirtyDirtyIn(IRReg rd1, IRReg rd2, IRReg rs, RiscVJitConstants::MapType type = RiscVJitConstants::MapType::AVOID_LOAD); void MapDirtyDirtyInIn(IRReg rd1, IRReg rd2, IRReg rs, IRReg rt, RiscVJitConstants::MapType type = RiscVJitConstants::MapType::AVOID_LOAD); void FlushBeforeCall(); void FlushR(IRReg r); diff --git a/Core/MIPS/RiscV/RiscVRegCacheFPU.cpp b/Core/MIPS/RiscV/RiscVRegCacheFPU.cpp index 604cebfdfe..aa9518cde9 100644 --- a/Core/MIPS/RiscV/RiscVRegCacheFPU.cpp +++ b/Core/MIPS/RiscV/RiscVRegCacheFPU.cpp @@ -31,7 +31,10 @@ using namespace RiscVJitConstants; RiscVRegCacheFPU::RiscVRegCacheFPU(MIPSComp::JitOptions *jo) : IRNativeRegCacheBase(jo) { - totalNativeRegs_ = NUM_RVFPUREG; + config_.totalNativeRegs = NUM_RVFPUREG; + // TODO: When using RISC-V V. + config_.mapUseVRegs = false; + config_.mapSIMD = false; } void RiscVRegCacheFPU::Init(RiscVEmitter *emitter) { @@ -53,7 +56,7 @@ const int *RiscVRegCacheFPU::GetAllocationOrder(MIPSLoc type, int &count, int &b return allocationOrder; } -RiscVReg RiscVRegCacheFPU::MapReg(IRReg mipsReg, MIPSMap mapFlags) { +RiscVReg RiscVRegCacheFPU::MapFPR(IRReg mipsReg, MIPSMap mapFlags) { _dbg_assert_(IsValidFPR(mipsReg)); _dbg_assert_(mr[mipsReg + 32].loc == MIPSLoc::MEM || mr[mipsReg + 32].loc == MIPSLoc::FREG); @@ -63,35 +66,20 @@ RiscVReg RiscVRegCacheFPU::MapReg(IRReg mipsReg, MIPSMap mapFlags) { return INVALID_REG; } -void RiscVRegCacheFPU::MapInIn(IRReg rd, IRReg rs) { - SpillLockFPR(rd, rs); - MapReg(rd); - MapReg(rs); - ReleaseSpillLockFPR(rd, rs); -} - -void RiscVRegCacheFPU::MapDirtyIn(IRReg rd, IRReg rs, bool avoidLoad) { - SpillLockFPR(rd, rs); - bool load = !avoidLoad || rd == rs; - MapReg(rd, load ? MIPSMap::DIRTY : MIPSMap::NOINIT); - MapReg(rs); - ReleaseSpillLockFPR(rd, rs); -} - void RiscVRegCacheFPU::MapDirtyInIn(IRReg rd, IRReg rs, IRReg rt, bool avoidLoad) { SpillLockFPR(rd, rs, rt); bool load = !avoidLoad || (rd == rs || rd == rt); - MapReg(rd, load ? MIPSMap::DIRTY : MIPSMap::NOINIT); - MapReg(rt); - MapReg(rs); + MapFPR(rd, load ? MIPSMap::DIRTY : MIPSMap::NOINIT); + MapFPR(rt); + MapFPR(rs); ReleaseSpillLockFPR(rd, rs, rt); } RiscVReg RiscVRegCacheFPU::MapDirtyInTemp(IRReg rd, IRReg rs, bool avoidLoad) { SpillLockFPR(rd, rs); bool load = !avoidLoad || rd == rs; - MapReg(rd, load ? MIPSMap::DIRTY : MIPSMap::NOINIT); - MapReg(rs); + MapFPR(rd, load ? MIPSMap::DIRTY : MIPSMap::NOINIT); + MapFPR(rs); RiscVReg temp = (RiscVReg)(F0 + AllocateReg(MIPSLoc::FREG)); ReleaseSpillLockFPR(rd, rs); return temp; @@ -102,35 +90,21 @@ void RiscVRegCacheFPU::Map4DirtyIn(IRReg rdbase, IRReg rsbase, bool avoidLoad) { SpillLockFPR(rdbase + i, rsbase + i); bool load = !avoidLoad || (rdbase < rsbase + 4 && rdbase + 4 > rsbase); for (int i = 0; i < 4; ++i) - MapReg(rdbase + i, load ? MIPSMap::DIRTY : MIPSMap::NOINIT); + MapFPR(rdbase + i, load ? MIPSMap::DIRTY : MIPSMap::NOINIT); for (int i = 0; i < 4; ++i) - MapReg(rsbase + i); + MapFPR(rsbase + i); for (int i = 0; i < 4; ++i) ReleaseSpillLockFPR(rdbase + i, rsbase + i); } -void RiscVRegCacheFPU::Map4DirtyInIn(IRReg rdbase, IRReg rsbase, IRReg rtbase, bool avoidLoad) { - for (int i = 0; i < 4; ++i) - SpillLockFPR(rdbase + i, rsbase + i, rtbase + i); - bool load = !avoidLoad || (rdbase < rsbase + 4 && rdbase + 4 > rsbase) || (rdbase < rtbase + 4 && rdbase + 4 > rtbase); - for (int i = 0; i < 4; ++i) - MapReg(rdbase + i, load ? MIPSMap::DIRTY : MIPSMap::NOINIT); - for (int i = 0; i < 4; ++i) - MapReg(rsbase + i); - for (int i = 0; i < 4; ++i) - MapReg(rtbase + i); - for (int i = 0; i < 4; ++i) - ReleaseSpillLockFPR(rdbase + i, rsbase + i, rtbase + i); -} - RiscVReg RiscVRegCacheFPU::Map4DirtyInTemp(IRReg rdbase, IRReg rsbase, bool avoidLoad) { for (int i = 0; i < 4; ++i) SpillLockFPR(rdbase + i, rsbase + i); bool load = !avoidLoad || (rdbase < rsbase + 4 && rdbase + 4 > rsbase); for (int i = 0; i < 4; ++i) - MapReg(rdbase + i, load ? MIPSMap::DIRTY : MIPSMap::NOINIT); + MapFPR(rdbase + i, load ? MIPSMap::DIRTY : MIPSMap::NOINIT); for (int i = 0; i < 4; ++i) - MapReg(rsbase + i); + MapFPR(rsbase + i); RiscVReg temp = (RiscVReg)(F0 + AllocateReg(MIPSLoc::FREG)); for (int i = 0; i < 4; ++i) ReleaseSpillLockFPR(rdbase + i, rsbase + i); diff --git a/Core/MIPS/RiscV/RiscVRegCacheFPU.h b/Core/MIPS/RiscV/RiscVRegCacheFPU.h index 6b612053e3..ccef3e36b0 100644 --- a/Core/MIPS/RiscV/RiscVRegCacheFPU.h +++ b/Core/MIPS/RiscV/RiscVRegCacheFPU.h @@ -32,14 +32,11 @@ public: void Init(RiscVGen::RiscVEmitter *emitter); // Returns a RISC-V register containing the requested MIPS register. - RiscVGen::RiscVReg MapReg(IRReg reg, MIPSMap mapFlags = MIPSMap::INIT); + RiscVGen::RiscVReg MapFPR(IRReg reg, MIPSMap mapFlags = MIPSMap::INIT); - void MapInIn(IRReg rd, IRReg rs); - void MapDirtyIn(IRReg rd, IRReg rs, bool avoidLoad = true); void MapDirtyInIn(IRReg rd, IRReg rs, IRReg rt, bool avoidLoad = true); RiscVGen::RiscVReg MapDirtyInTemp(IRReg rd, IRReg rs, bool avoidLoad = true); void Map4DirtyIn(IRReg rdbase, IRReg rsbase, bool avoidLoad = true); - void Map4DirtyInIn(IRReg rdbase, IRReg rsbase, IRReg rtbase, bool avoidLoad = true); RiscVGen::RiscVReg Map4DirtyInTemp(IRReg rdbase, IRReg rsbase, bool avoidLoad = true); void FlushBeforeCall(); void FlushR(IRReg r);