mirror of
https://github.com/izzy2lost/ppsspp.git
synced 2026-03-10 12:43:04 -07:00
riscv: Add some safety to pointerifying.
We have to clear the upper bits in case of sign extension or other things.
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "Core/MIPS/RiscV/RiscVRegCache.h"
|
||||
#include "Core/MIPS/JitCommon/JitState.h"
|
||||
#include "Core/Reporting.h"
|
||||
@@ -446,16 +447,10 @@ RiscVReg RiscVRegCache::MapRegAsPointer(IRRegIndex reg) {
|
||||
if (!jo_->enablePointerify) {
|
||||
// Convert to a pointer by adding the base and clearing off the top bits.
|
||||
// If SP, we can probably avoid the top bit clear, let's play with that later.
|
||||
#ifdef MASKED_PSP_MEMORY
|
||||
// This destroys the value...
|
||||
_dbg_assert_(!ar[riscvReg].isDirty);
|
||||
emit_->SLLIW(riscvReg, riscvReg, 2);
|
||||
emit_->SRLIW(riscvReg, riscvReg, 2);
|
||||
#endif
|
||||
emit_->ADD(riscvReg, riscvReg, MEMBASEREG);
|
||||
AddMemBase(riscvReg);
|
||||
mr[reg].loc = MIPSLoc::RVREG_AS_PTR;
|
||||
} else if (!ar[riscvReg].pointerified) {
|
||||
emit_->ADD(riscvReg, riscvReg, MEMBASEREG);
|
||||
AddMemBase(riscvReg);
|
||||
ar[riscvReg].pointerified = true;
|
||||
}
|
||||
} else {
|
||||
@@ -464,6 +459,27 @@ RiscVReg RiscVRegCache::MapRegAsPointer(IRRegIndex reg) {
|
||||
return riscvReg;
|
||||
}
|
||||
|
||||
void RiscVRegCache::AddMemBase(RiscVGen::RiscVReg reg) {
|
||||
_assert_(reg >= X0 && reg <= X31);
|
||||
#ifdef MASKED_PSP_MEMORY
|
||||
// This destroys the value...
|
||||
_dbg_assert_(!ar[reg].isDirty);
|
||||
emit_->SLLIW(reg, reg, 2);
|
||||
emit_->SRLIW(reg, reg, 2);
|
||||
emit_->ADD(reg, reg, MEMBASEREG);
|
||||
#else
|
||||
// Clear the top bits to be safe.
|
||||
if (cpu_info.RiscV_Zba) {
|
||||
emit_->ADD_UW(reg, reg, MEMBASEREG);
|
||||
} else {
|
||||
_assert_(XLEN == 64);
|
||||
emit_->SLLI(reg, reg, 32);
|
||||
emit_->SRLI(reg, reg, 32);
|
||||
emit_->ADD(reg, reg, MEMBASEREG);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void RiscVRegCache::MapIn(IRRegIndex rs) {
|
||||
MapReg(rs);
|
||||
}
|
||||
@@ -759,11 +775,11 @@ void RiscVRegCache::FlushAll() {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (allocs[i].pointerified && !ar[allocs[i].ar].pointerified && jo_->enablePointerify) {
|
||||
// Re-pointerify
|
||||
emit_->ADD(allocs[i].ar, allocs[i].ar, MEMBASEREG);
|
||||
AddMemBase(allocs[i].ar);
|
||||
ar[allocs[i].ar].pointerified = true;
|
||||
} else {
|
||||
// If this register got pointerified on the way, mark it as not.
|
||||
// This nis so that after save/reload (like in an interpreter fallback),
|
||||
// This is so that after save/reload (like in an interpreter fallback),
|
||||
// it won't be regarded as such, as it may no longer be.
|
||||
ar[allocs[i].ar].pointerified = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user