mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-27 12:18:35 +01:00
riscv: Mark normalized32 after mapping.
It's less confusing to separate it.
This commit is contained in:
1 parent
f9bf7de701
commit
e40ae60029
8 files changed
+37
-28
No files matched your search
@@ -844,7 +844,7 @@ void IRNativeRegCacheBase::MapNativeReg(MIPSLoc type, IRNativeReg nreg, IRReg fi
|
||||
if (mr[first].nReg != nreg) {
|
||||
nr[nreg].isDirty = markDirty;
|
||||
nr[nreg].pointerified = false;
|
||||
nr[nreg].normalized32 = (flags & MIPSMap::MARK_NORM32) == MIPSMap::MARK_NORM32;
|
||||
nr[nreg].normalized32 = false;
|
||||
}
|
||||
|
||||
// Alright, now to actually map.
|
||||
@@ -920,10 +920,8 @@ void IRNativeRegCacheBase::MapNativeReg(MIPSLoc type, IRNativeReg nreg, IRReg fi
|
||||
if (markDirty) {
|
||||
nr[nreg].isDirty = true;
|
||||
nr[nreg].pointerified = false;
|
||||
nr[nreg].normalized32 = (flags & MIPSMap::MARK_NORM32) == MIPSMap::MARK_NORM32;
|
||||
nr[nreg].normalized32 = false;
|
||||
_assert_(first != MIPS_REG_ZERO);
|
||||
} else if ((flags & MIPSMap::MARK_NORM32) == MIPSMap::MARK_NORM32) {
|
||||
nr[nreg].normalized32 = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,6 @@ enum class MIPSMap {
|
||||
INIT = 0,
|
||||
DIRTY = 1,
|
||||
NOINIT = 2 | DIRTY,
|
||||
MARK_NORM32 = 4,
|
||||
};
|
||||
static inline MIPSMap operator |(const MIPSMap &lhs, const MIPSMap &rhs) {
|
||||
return MIPSMap((int)lhs | (int)rhs);
|
||||
|
||||
@@ -697,7 +697,7 @@ void RiscVJitBackend::CompIR_Div(IRInst inst) {
|
||||
RiscVReg numReg, denomReg;
|
||||
switch (inst.op) {
|
||||
case IROp::Div:
|
||||
regs_.MapGPRDirtyDirtyInIn(IRREG_LO, IRREG_HI, inst.src1, inst.src2, MapType::AVOID_LOAD_MARK_NORM32);
|
||||
regs_.MapGPRDirtyDirtyInIn(IRREG_LO, IRREG_HI, inst.src1, inst.src2);
|
||||
// We have to do this because of the divide by zero and overflow checks below.
|
||||
NormalizeSrc12(inst, &numReg, &denomReg, SCRATCH1, SCRATCH2, true);
|
||||
DIVW(regs_.R(IRREG_LO), numReg, denomReg);
|
||||
@@ -722,10 +722,12 @@ void RiscVJitBackend::CompIR_Div(IRInst inst) {
|
||||
SetJumpTarget(notNegativeOne);
|
||||
SetJumpTarget(notMostNegative);
|
||||
}
|
||||
regs_.MarkGPRDirty(IRREG_LO, true);
|
||||
regs_.MarkGPRDirty(IRREG_HI, true);
|
||||
break;
|
||||
|
||||
case IROp::DivU:
|
||||
regs_.MapGPRDirtyDirtyInIn(IRREG_LO, IRREG_HI, inst.src1, inst.src2, MapType::AVOID_LOAD_MARK_NORM32);
|
||||
regs_.MapGPRDirtyDirtyInIn(IRREG_LO, IRREG_HI, inst.src1, inst.src2);
|
||||
// We have to do this because of the divide by zero check below.
|
||||
NormalizeSrc12(inst, &numReg, &denomReg, SCRATCH1, SCRATCH2, true);
|
||||
DIVUW(regs_.R(IRREG_LO), numReg, denomReg);
|
||||
@@ -741,6 +743,8 @@ void RiscVJitBackend::CompIR_Div(IRInst inst) {
|
||||
SetJumpTarget(keepNegOne);
|
||||
SetJumpTarget(skipNonZero);
|
||||
}
|
||||
regs_.MarkGPRDirty(IRREG_LO, true);
|
||||
regs_.MarkGPRDirty(IRREG_HI, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -351,24 +351,26 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) {
|
||||
|
||||
case IRFpCompareMode::EitherUnordered:
|
||||
regs_.Map(inst);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT);
|
||||
FCLASS(32, SCRATCH1, regs_.F(inst.src1));
|
||||
FCLASS(32, SCRATCH2, regs_.F(inst.src2));
|
||||
OR(SCRATCH1, SCRATCH1, SCRATCH2);
|
||||
// NAN is 0x100 or 0x200.
|
||||
ANDI(SCRATCH1, SCRATCH1, 0x300);
|
||||
SNEZ(regs_.R(IRREG_FPCOND), SCRATCH1);
|
||||
regs_.MarkGPRDirty(IRREG_FPCOND, true);
|
||||
break;
|
||||
|
||||
case IRFpCompareMode::EqualOrdered:
|
||||
regs_.Map(inst);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT);
|
||||
FEQ(32, regs_.R(IRREG_FPCOND), regs_.F(inst.src1), regs_.F(inst.src2));
|
||||
regs_.MarkGPRDirty(IRREG_FPCOND, true);
|
||||
break;
|
||||
|
||||
case IRFpCompareMode::EqualUnordered:
|
||||
regs_.Map(inst);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT);
|
||||
FEQ(32, regs_.R(IRREG_FPCOND), regs_.F(inst.src1), regs_.F(inst.src2));
|
||||
|
||||
// Now let's just OR in the unordered check.
|
||||
@@ -379,32 +381,37 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) {
|
||||
ANDI(SCRATCH1, SCRATCH1, 0x300);
|
||||
SNEZ(SCRATCH1, SCRATCH1);
|
||||
OR(regs_.R(IRREG_FPCOND), regs_.R(IRREG_FPCOND), SCRATCH1);
|
||||
regs_.MarkGPRDirty(IRREG_FPCOND, true);
|
||||
break;
|
||||
|
||||
case IRFpCompareMode::LessEqualOrdered:
|
||||
regs_.Map(inst);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT);
|
||||
FLE(32, regs_.R(IRREG_FPCOND), regs_.F(inst.src1), regs_.F(inst.src2));
|
||||
regs_.MarkGPRDirty(IRREG_FPCOND, true);
|
||||
break;
|
||||
|
||||
case IRFpCompareMode::LessEqualUnordered:
|
||||
regs_.Map(inst);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT);
|
||||
FLT(32, regs_.R(IRREG_FPCOND), regs_.F(inst.src2), regs_.F(inst.src1));
|
||||
SEQZ(regs_.R(IRREG_FPCOND), regs_.R(IRREG_FPCOND));
|
||||
regs_.MarkGPRDirty(IRREG_FPCOND, true);
|
||||
break;
|
||||
|
||||
case IRFpCompareMode::LessOrdered:
|
||||
regs_.Map(inst);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT);
|
||||
FLT(32, regs_.R(IRREG_FPCOND), regs_.F(inst.src1), regs_.F(inst.src2));
|
||||
regs_.MarkGPRDirty(IRREG_FPCOND, true);
|
||||
break;
|
||||
|
||||
case IRFpCompareMode::LessUnordered:
|
||||
regs_.Map(inst);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT);
|
||||
FLE(32, regs_.R(IRREG_FPCOND), regs_.F(inst.src2), regs_.F(inst.src1));
|
||||
SEQZ(regs_.R(IRREG_FPCOND), regs_.R(IRREG_FPCOND));
|
||||
regs_.MarkGPRDirty(IRREG_FPCOND, true);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -81,7 +81,8 @@ void RiscVJitBackend::CompIR_Load(IRInst inst) {
|
||||
addrReg = SCRATCH1;
|
||||
}
|
||||
// With NOINIT, MapReg won't subtract MEMBASEREG even if dest == src1.
|
||||
regs_.MapGPR(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32);
|
||||
regs_.MapGPR(inst.dest, MIPSMap::NOINIT);
|
||||
regs_.MarkGPRDirty(inst.dest, true);
|
||||
|
||||
s32 imm = AdjustForAddressOffset(&addrReg, inst.constant);
|
||||
|
||||
|
||||
@@ -100,9 +100,10 @@ void RiscVJitBackend::CompIR_Transfer(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::SetCtrlVFPUFReg:
|
||||
regs_.MapGPR(IRREG_VFPU_CTRL_BASE + inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32);
|
||||
regs_.MapGPR(IRREG_VFPU_CTRL_BASE + inst.dest, MIPSMap::NOINIT);
|
||||
regs_.MapFPR(inst.src1);
|
||||
FMV(FMv::X, FMv::W, regs_.R(IRREG_VFPU_CTRL_BASE + inst.dest), regs_.F(inst.src1));
|
||||
regs_.MarkGPRDirty(IRREG_VFPU_CTRL_BASE + inst.dest, true);
|
||||
break;
|
||||
|
||||
case IROp::FpCondFromReg:
|
||||
@@ -117,7 +118,7 @@ void RiscVJitBackend::CompIR_Transfer(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::FpCtrlFromReg:
|
||||
regs_.MapGPRDirtyIn(IRREG_FPCOND, inst.src1, MapType::AVOID_LOAD_MARK_NORM32);
|
||||
regs_.MapGPRDirtyIn(IRREG_FPCOND, inst.src1);
|
||||
LI(SCRATCH1, 0x0181FFFF);
|
||||
AND(SCRATCH1, regs_.R(inst.src1), SCRATCH1);
|
||||
// Extract the new fpcond value.
|
||||
@@ -128,10 +129,11 @@ void RiscVJitBackend::CompIR_Transfer(IRInst inst) {
|
||||
ANDI(regs_.R(IRREG_FPCOND), regs_.R(IRREG_FPCOND), 1);
|
||||
}
|
||||
SW(SCRATCH1, CTXREG, IRREG_FCR31 * 4);
|
||||
regs_.MarkGPRDirty(IRREG_FPCOND, true);
|
||||
break;
|
||||
|
||||
case IROp::FpCtrlToReg:
|
||||
regs_.MapGPRDirtyIn(inst.dest, IRREG_FPCOND, MapType::AVOID_LOAD_MARK_NORM32);
|
||||
regs_.MapGPRDirtyIn(inst.dest, IRREG_FPCOND);
|
||||
// Load fcr31 and clear the fpcond bit.
|
||||
LW(SCRATCH1, CTXREG, IRREG_FCR31 * 4);
|
||||
if (cpu_info.RiscV_Zbs) {
|
||||
@@ -148,6 +150,7 @@ void RiscVJitBackend::CompIR_Transfer(IRInst inst) {
|
||||
|
||||
// Also update mips->fcr31 while we're here.
|
||||
SW(regs_.R(inst.dest), CTXREG, IRREG_FCR31 * 4);
|
||||
regs_.MarkGPRDirty(inst.dest, true);
|
||||
break;
|
||||
|
||||
case IROp::VfpuCtrlToReg:
|
||||
@@ -157,19 +160,19 @@ void RiscVJitBackend::CompIR_Transfer(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::FMovFromGPR:
|
||||
regs_.MapFPR(inst.dest, MIPSMap::NOINIT);
|
||||
if (regs_.IsGPRImm(inst.src1) && regs_.GetGPRImm(inst.src1) == 0) {
|
||||
regs_.MapFPR(inst.dest, MIPSMap::NOINIT);
|
||||
FCVT(FConv::S, FConv::W, regs_.F(inst.dest), R_ZERO);
|
||||
} else {
|
||||
regs_.MapGPR(inst.src1);
|
||||
regs_.Map(inst);
|
||||
FMV(FMv::W, FMv::X, regs_.F(inst.dest), regs_.R(inst.src1));
|
||||
}
|
||||
break;
|
||||
|
||||
case IROp::FMovToGPR:
|
||||
regs_.MapGPR(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32);
|
||||
regs_.MapFPR(inst.src1);
|
||||
regs_.Map(inst);
|
||||
FMV(FMv::X, FMv::W, regs_.R(inst.dest), regs_.F(inst.src1));
|
||||
regs_.MarkGPRDirty(inst.dest, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -258,8 +258,7 @@ RiscVReg RiscVRegCache::MapGPRAsPointer(IRReg reg) {
|
||||
void RiscVRegCache::MapGPRDirtyIn(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;
|
||||
MapGPR(rd, (load ? MIPSMap::DIRTY : MIPSMap::NOINIT) | norm32);
|
||||
MapGPR(rd, load ? MIPSMap::DIRTY : MIPSMap::NOINIT);
|
||||
MapGPR(rs);
|
||||
ReleaseSpillLockGPR(rd, rs);
|
||||
}
|
||||
@@ -268,9 +267,8 @@ void RiscVRegCache::MapGPRDirtyDirtyInIn(IRReg rd1, IRReg rd2, IRReg rs, IRReg r
|
||||
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;
|
||||
MapGPR(rd1, (load1 ? MIPSMap::DIRTY : MIPSMap::NOINIT) | norm32);
|
||||
MapGPR(rd2, (load2 ? MIPSMap::DIRTY : MIPSMap::NOINIT) | norm32);
|
||||
MapGPR(rd1, load1 ? MIPSMap::DIRTY : MIPSMap::NOINIT);
|
||||
MapGPR(rd2, load2 ? MIPSMap::DIRTY : MIPSMap::NOINIT);
|
||||
MapGPR(rt);
|
||||
MapGPR(rs);
|
||||
ReleaseSpillLockGPR(rd1, rd2, rs, rt);
|
||||
|
||||
@@ -37,7 +37,6 @@ const RiscVGen::RiscVReg SCRATCH2 = RiscVGen::X11;
|
||||
|
||||
enum class MapType {
|
||||
AVOID_LOAD,
|
||||
AVOID_LOAD_MARK_NORM32,
|
||||
ALWAYS_LOAD,
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user