From c24e3ef83106bbb3b00a5334ccf7a97743981445 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 29 Jul 2023 17:53:15 -0700 Subject: [PATCH] riscv: Implement ll/sc. --- Core/MIPS/IR/IRInst.h | 1 + Core/MIPS/RiscV/RiscVCompLoadStore.cpp | 40 ++++++++++++++++++++++++-- Core/MIPS/RiscV/RiscVRegCache.cpp | 3 +- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/Core/MIPS/IR/IRInst.h b/Core/MIPS/IR/IRInst.h index 5a2a2e25a1..795dc75233 100644 --- a/Core/MIPS/IR/IRInst.h +++ b/Core/MIPS/IR/IRInst.h @@ -315,6 +315,7 @@ enum : IRReg { IRREG_HI = 243, IRREG_FCR31 = 244, IRREG_FPCOND = 245, + IRREG_LLBIT = 250, }; enum IRFlags { diff --git a/Core/MIPS/RiscV/RiscVCompLoadStore.cpp b/Core/MIPS/RiscV/RiscVCompLoadStore.cpp index 8cc8af74de..d6a49e6f13 100644 --- a/Core/MIPS/RiscV/RiscVCompLoadStore.cpp +++ b/Core/MIPS/RiscV/RiscVCompLoadStore.cpp @@ -113,7 +113,9 @@ void RiscVJit::CompIR_Load(IRInst inst) { break; case IROp::Load32Linked: - CompIR_Generic(inst); + if (inst.dest != MIPS_REG_ZERO) + LW(gpr.R(inst.dest), addrReg, imm); + gpr.SetImm(IRREG_LLBIT, 1); break; default: @@ -258,7 +260,41 @@ void RiscVJit::CompIR_CondStore(IRInst inst) { if (inst.op != IROp::Store32Conditional) INVALIDOP; - CompIR_Generic(inst); + gpr.SpillLock(IRREG_LLBIT, inst.src3, inst.src1); + RiscVReg addrReg = INVALID_REG; + if (inst.src1 == MIPS_REG_ZERO) { + // This will get changed by AdjustForAddressOffset. + addrReg = MEMBASEREG; +#ifdef MASKED_PSP_MEMORY + inst.constant &= Memory::MEMVIEW32_MASK; +#endif + } else if ((jo.cachePointers || gpr.IsMappedAsPointer(inst.src1)) && inst.src3 != inst.src1) { + addrReg = gpr.MapRegAsPointer(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.ReleaseSpillLock(IRREG_LLBIT, inst.src3, inst.src1); + + s32 imm = AdjustForAddressOffset(&addrReg, inst.constant); + + // TODO: Safe memory? Or enough to have crash handler + validate? + + FixupBranch condFailed = BEQ(gpr.R(IRREG_LLBIT), R_ZERO); + SW(gpr.R(inst.src3), addrReg, imm); + + if (inst.dest != MIPS_REG_ZERO) { + LI(gpr.R(inst.dest), 1); + FixupBranch finish = J(); + + SetJumpTarget(condFailed); + LI(gpr.R(inst.dest), 0); + SetJumpTarget(finish); + } else { + SetJumpTarget(condFailed); + } } void RiscVJit::CompIR_StoreShift(IRInst inst) { diff --git a/Core/MIPS/RiscV/RiscVRegCache.cpp b/Core/MIPS/RiscV/RiscVRegCache.cpp index 639c11843a..25f7b5db59 100644 --- a/Core/MIPS/RiscV/RiscVRegCache.cpp +++ b/Core/MIPS/RiscV/RiscVRegCache.cpp @@ -20,6 +20,7 @@ #endif #include "Common/CPUDetect.h" +#include "Core/MIPS/IR/IRInst.h" #include "Core/MIPS/RiscV/RiscVRegCache.h" #include "Core/MIPS/JitCommon/JitState.h" #include "Core/Reporting.h" @@ -998,7 +999,7 @@ bool RiscVRegCache::IsValidReg(IRRegIndex r) const { if (r >= 224 && r < 224 + 16) return false; // Don't allow nextPC, etc. since it's probably a mistake. - if (r > 245) + if (r > IRREG_FPCOND && r != IRREG_LLBIT) return false; // Don't allow PC either. if (r == 241)