mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-12 22:10:29 +02:00
riscv: Use automapping for special cases too.
This commit is contained in:
1 parent
a190793ad2
commit
6a75e6712e
8 files changed
+45
-117
No files matched your search
@@ -643,6 +643,14 @@ void IRNativeRegCacheBase::Map(const IRInst &inst) {
|
||||
CleanupMapping(mapping, 3);
|
||||
}
|
||||
|
||||
void IRNativeRegCacheBase::MapWithExtra(const IRInst &inst, std::vector<Mapping> extra) {
|
||||
extra.resize(extra.size() + 3);
|
||||
MappingFromInst(inst, &extra[extra.size() - 3]);
|
||||
|
||||
ApplyMapping(extra.data(), (int)extra.size());
|
||||
CleanupMapping(extra.data(), (int)extra.size());
|
||||
}
|
||||
|
||||
IRNativeReg IRNativeRegCacheBase::MapWithTemp(const IRInst &inst, MIPSLoc type) {
|
||||
Mapping mapping[3];
|
||||
MappingFromInst(inst, mapping);
|
||||
|
||||
@@ -190,6 +190,7 @@ public:
|
||||
};
|
||||
|
||||
void Map(const IRInst &inst);
|
||||
void MapWithExtra(const IRInst &inst, std::vector<Mapping> extra);
|
||||
virtual void FlushAll(bool gprs = true, bool fprs = true);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -563,25 +563,25 @@ void RiscVJitBackend::CompIR_HiLo(IRInst inst) {
|
||||
|
||||
switch (inst.op) {
|
||||
case IROp::MtLo:
|
||||
regs_.MapGPRDirtyIn(IRREG_LO, inst.src1);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_LO, 1, MIPSMap::NOINIT } });
|
||||
MV(regs_.R(IRREG_LO), regs_.R(inst.src1));
|
||||
regs_.MarkGPRDirty(IRREG_LO, regs_.IsNormalized32(inst.src1));
|
||||
break;
|
||||
|
||||
case IROp::MtHi:
|
||||
regs_.MapGPRDirtyIn(IRREG_HI, inst.src1);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_HI, 1, MIPSMap::NOINIT } });
|
||||
MV(regs_.R(IRREG_HI), regs_.R(inst.src1));
|
||||
regs_.MarkGPRDirty(IRREG_HI, regs_.IsNormalized32(inst.src1));
|
||||
break;
|
||||
|
||||
case IROp::MfLo:
|
||||
regs_.MapGPRDirtyIn(inst.dest, IRREG_LO);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_LO, 1, MIPSMap::INIT } });
|
||||
MV(regs_.R(inst.dest), regs_.R(IRREG_LO));
|
||||
regs_.MarkGPRDirty(inst.dest, regs_.IsNormalized32(IRREG_LO));
|
||||
break;
|
||||
|
||||
case IROp::MfHi:
|
||||
regs_.MapGPRDirtyIn(inst.dest, IRREG_HI);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_HI, 1, MIPSMap::INIT } });
|
||||
MV(regs_.R(inst.dest), regs_.R(IRREG_HI));
|
||||
regs_.MarkGPRDirty(inst.dest, regs_.IsNormalized32(IRREG_HI));
|
||||
break;
|
||||
@@ -630,7 +630,7 @@ void RiscVJitBackend::CompIR_Mult(IRInst inst) {
|
||||
case IROp::Mult:
|
||||
// TODO: Maybe IR could simplify when HI is not needed or clobbered?
|
||||
// TODO: HI/LO merge optimization? Have to be careful of passes that split them...
|
||||
regs_.MapGPRDirtyDirtyInIn(IRREG_LO, IRREG_HI, inst.src1, inst.src2);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_LO, 1, MIPSMap::NOINIT }, { 'G', IRREG_HI, 1, MIPSMap::NOINIT } });
|
||||
NormalizeSrc12(inst, &lhs, &rhs, SCRATCH1, SCRATCH2, true);
|
||||
MUL(regs_.R(IRREG_LO), lhs, rhs);
|
||||
splitMulResult();
|
||||
@@ -639,14 +639,14 @@ void RiscVJitBackend::CompIR_Mult(IRInst inst) {
|
||||
case IROp::MultU:
|
||||
// This is an "anti-norm32" case. Let's just zero always.
|
||||
// TODO: If we could know that LO was only needed, we could use MULW and be done.
|
||||
regs_.MapGPRDirtyDirtyInIn(IRREG_LO, IRREG_HI, inst.src1, inst.src2);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_LO, 1, MIPSMap::NOINIT }, { 'G', IRREG_HI, 1, MIPSMap::NOINIT } });
|
||||
makeArgsUnsigned(&lhs, &rhs);
|
||||
MUL(regs_.R(IRREG_LO), lhs, rhs);
|
||||
splitMulResult();
|
||||
break;
|
||||
|
||||
case IROp::Madd:
|
||||
regs_.MapGPRDirtyDirtyInIn(IRREG_LO, IRREG_HI, inst.src1, inst.src2, false);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_LO, 1, MIPSMap::DIRTY }, { 'G', IRREG_HI, 1, MIPSMap::DIRTY } });
|
||||
NormalizeSrc12(inst, &lhs, &rhs, SCRATCH1, SCRATCH2, true);
|
||||
MUL(SCRATCH1, lhs, rhs);
|
||||
|
||||
@@ -656,7 +656,7 @@ void RiscVJitBackend::CompIR_Mult(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::MaddU:
|
||||
regs_.MapGPRDirtyDirtyInIn(IRREG_LO, IRREG_HI, inst.src1, inst.src2, false);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_LO, 1, MIPSMap::DIRTY }, { 'G', IRREG_HI, 1, MIPSMap::DIRTY } });
|
||||
makeArgsUnsigned(&lhs, &rhs);
|
||||
MUL(SCRATCH1, lhs, rhs);
|
||||
|
||||
@@ -666,7 +666,7 @@ void RiscVJitBackend::CompIR_Mult(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::Msub:
|
||||
regs_.MapGPRDirtyDirtyInIn(IRREG_LO, IRREG_HI, inst.src1, inst.src2, false);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_LO, 1, MIPSMap::DIRTY }, { 'G', IRREG_HI, 1, MIPSMap::DIRTY } });
|
||||
NormalizeSrc12(inst, &lhs, &rhs, SCRATCH1, SCRATCH2, true);
|
||||
MUL(SCRATCH1, lhs, rhs);
|
||||
|
||||
@@ -676,7 +676,7 @@ void RiscVJitBackend::CompIR_Mult(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::MsubU:
|
||||
regs_.MapGPRDirtyDirtyInIn(IRREG_LO, IRREG_HI, inst.src1, inst.src2, false);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_LO, 1, MIPSMap::DIRTY }, { 'G', IRREG_HI, 1, MIPSMap::DIRTY } });
|
||||
makeArgsUnsigned(&lhs, &rhs);
|
||||
MUL(SCRATCH1, lhs, 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);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_LO, 1, MIPSMap::NOINIT }, { 'G', IRREG_HI, 1, MIPSMap::NOINIT } });
|
||||
// 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);
|
||||
@@ -727,7 +727,7 @@ void RiscVJitBackend::CompIR_Div(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::DivU:
|
||||
regs_.MapGPRDirtyDirtyInIn(IRREG_LO, IRREG_HI, inst.src1, inst.src2);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_LO, 1, MIPSMap::NOINIT }, { 'G', IRREG_HI, 1, MIPSMap::NOINIT } });
|
||||
// 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);
|
||||
|
||||
@@ -350,8 +350,7 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IRFpCompareMode::EitherUnordered:
|
||||
regs_.Map(inst);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_FPCOND, 1, MIPSMap::NOINIT } });
|
||||
FCLASS(32, SCRATCH1, regs_.F(inst.src1));
|
||||
FCLASS(32, SCRATCH2, regs_.F(inst.src2));
|
||||
OR(SCRATCH1, SCRATCH1, SCRATCH2);
|
||||
@@ -362,15 +361,13 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IRFpCompareMode::EqualOrdered:
|
||||
regs_.Map(inst);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_FPCOND, 1, 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);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_FPCOND, 1, 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.
|
||||
@@ -385,30 +382,26 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IRFpCompareMode::LessEqualOrdered:
|
||||
regs_.Map(inst);
|
||||
regs_.MapGPR(IRREG_FPCOND, MIPSMap::NOINIT);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_FPCOND, 1, 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);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_FPCOND, 1, 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);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_FPCOND, 1, 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);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_FPCOND, 1, 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);
|
||||
@@ -417,8 +410,7 @@ void RiscVJitBackend::CompIR_FCompare(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::FCmovVfpuCC:
|
||||
regs_.MapGPR(IRREG_VFPU_CC);
|
||||
regs_.Map(inst);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_VFPU_CC, 1, MIPSMap::INIT } });
|
||||
if ((inst.src2 & 0xF) == 0) {
|
||||
ANDI(SCRATCH1, regs_.R(IRREG_VFPU_CC), 1);
|
||||
} else if (cpu_info.RiscV_Zbs) {
|
||||
|
||||
@@ -106,18 +106,18 @@ void RiscVJitBackend::CompIR_Transfer(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::FpCondFromReg:
|
||||
regs_.MapGPRDirtyIn(IRREG_FPCOND, inst.src1);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_FPCOND, 1, MIPSMap::NOINIT } });
|
||||
MV(regs_.R(IRREG_FPCOND), regs_.R(inst.src1));
|
||||
break;
|
||||
|
||||
case IROp::FpCondToReg:
|
||||
regs_.MapGPRDirtyIn(inst.dest, IRREG_FPCOND);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_FPCOND, 1, MIPSMap::INIT } });
|
||||
MV(regs_.R(inst.dest), regs_.R(IRREG_FPCOND));
|
||||
regs_.MarkGPRDirty(inst.dest, regs_.IsNormalized32(IRREG_FPCOND));
|
||||
break;
|
||||
|
||||
case IROp::FpCtrlFromReg:
|
||||
regs_.MapGPRDirtyIn(IRREG_FPCOND, inst.src1);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_FPCOND, 1, MIPSMap::NOINIT } });
|
||||
LI(SCRATCH1, 0x0181FFFF);
|
||||
AND(SCRATCH1, regs_.R(inst.src1), SCRATCH1);
|
||||
// Extract the new fpcond value.
|
||||
@@ -132,7 +132,7 @@ void RiscVJitBackend::CompIR_Transfer(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::FpCtrlToReg:
|
||||
regs_.MapGPRDirtyIn(inst.dest, IRREG_FPCOND);
|
||||
regs_.MapWithExtra(inst, { { 'G', IRREG_FPCOND, 1, MIPSMap::INIT } });
|
||||
// Load fcr31 and clear the fpcond bit.
|
||||
LW(SCRATCH1, CTXREG, IRREG_FCR31 * 4);
|
||||
if (cpu_info.RiscV_Zbs) {
|
||||
|
||||
@@ -215,9 +215,8 @@ void RiscVJitBackend::CompIR_VecArith(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::Vec4Scale:
|
||||
regs_.SpillLockFPR(inst.src2);
|
||||
regs_.MapFPR(inst.src2);
|
||||
regs_.MapFPR4DirtyIn(inst.dest, inst.src1);
|
||||
// TODO: This works for now, but may need to handle aliasing for vectors.
|
||||
regs_.Map(inst);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
FMUL(32, regs_.F(inst.dest + i), regs_.F(inst.src1 + i), regs_.F(inst.src2));
|
||||
break;
|
||||
@@ -245,18 +244,8 @@ void RiscVJitBackend::CompIR_VecHoriz(IRInst inst) {
|
||||
|
||||
switch (inst.op) {
|
||||
case IROp::Vec4Dot:
|
||||
// TODO: Maybe some option to call the slow accurate mode?
|
||||
regs_.SpillLockFPR(inst.dest);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
regs_.SpillLockFPR(inst.src1 + i);
|
||||
regs_.SpillLockFPR(inst.src2 + i);
|
||||
}
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
regs_.MapFPR(inst.src1 + i);
|
||||
regs_.MapFPR(inst.src2 + i);
|
||||
}
|
||||
regs_.MapFPR(inst.dest, MIPSMap::NOINIT);
|
||||
|
||||
// TODO: This works for now, but may need to handle aliasing for vectors.
|
||||
regs_.Map(inst);
|
||||
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.
|
||||
// Technically this may impact -0.0 and such, but dots accurately need to be aligned anyway.
|
||||
@@ -292,13 +281,8 @@ void RiscVJitBackend::CompIR_VecPack(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::Vec4Unpack8To32:
|
||||
regs_.SpillLockFPR(inst.src1);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
regs_.SpillLockFPR(inst.dest + i);
|
||||
regs_.MapFPR(inst.src1);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
regs_.MapFPR(inst.dest + i, MIPSMap::NOINIT);
|
||||
|
||||
// TODO: This works for now, but may need to handle aliasing for vectors.
|
||||
regs_.Map(inst);
|
||||
FMV(FMv::X, FMv::W, SCRATCH2, regs_.F(inst.src1));
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
// Mask using walls.
|
||||
@@ -313,13 +297,8 @@ void RiscVJitBackend::CompIR_VecPack(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::Vec2Unpack16To32:
|
||||
regs_.SpillLockFPR(inst.src1);
|
||||
for (int i = 0; i < 2; ++i)
|
||||
regs_.SpillLockFPR(inst.dest + i);
|
||||
regs_.MapFPR(inst.src1);
|
||||
for (int i = 0; i < 2; ++i)
|
||||
regs_.MapFPR(inst.dest + i, MIPSMap::NOINIT);
|
||||
|
||||
// TODO: This works for now, but may need to handle aliasing for vectors.
|
||||
regs_.Map(inst);
|
||||
FMV(FMv::X, FMv::W, SCRATCH2, regs_.F(inst.src1));
|
||||
SLLI(SCRATCH1, SCRATCH2, 16);
|
||||
FMV(FMv::W, FMv::X, regs_.F(inst.dest), SCRATCH1);
|
||||
@@ -342,13 +321,8 @@ void RiscVJitBackend::CompIR_VecPack(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::Vec4Pack31To8:
|
||||
regs_.SpillLockFPR(inst.dest);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
regs_.SpillLockFPR(inst.src1 + i);
|
||||
regs_.MapFPR(inst.src1 + i);
|
||||
}
|
||||
regs_.MapFPR(inst.dest, MIPSMap::NOINIT);
|
||||
|
||||
// TODO: This works for now, but may need to handle aliasing for vectors.
|
||||
regs_.Map(inst);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
FMV(FMv::X, FMv::W, SCRATCH1, regs_.F(inst.src1 + i));
|
||||
SRLI(SCRATCH1, SCRATCH1, 23);
|
||||
@@ -365,7 +339,8 @@ void RiscVJitBackend::CompIR_VecPack(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::Vec2Pack32To16:
|
||||
regs_.MapFPRDirtyInIn(inst.dest, inst.src1, inst.src1 + 1);
|
||||
// TODO: This works for now, but may need to handle aliasing for vectors.
|
||||
regs_.Map(inst);
|
||||
FMV(FMv::X, FMv::W, SCRATCH1, regs_.F(inst.src1));
|
||||
FMV(FMv::X, FMv::W, SCRATCH2, regs_.F(inst.src1 + 1));
|
||||
// Keep in mind, this was sign-extended, so we have to zero the upper.
|
||||
|
||||
@@ -259,25 +259,6 @@ RiscVReg RiscVRegCache::MapGPRAsPointer(IRReg reg) {
|
||||
return (RiscVReg)MapNativeRegAsPointer(reg);
|
||||
}
|
||||
|
||||
void RiscVRegCache::MapGPRDirtyIn(IRReg rd, IRReg rs, bool avoidLoad) {
|
||||
SpillLockGPR(rd, rs);
|
||||
bool load = !avoidLoad || rd == rs;
|
||||
MapGPR(rd, load ? MIPSMap::DIRTY : MIPSMap::NOINIT);
|
||||
MapGPR(rs);
|
||||
ReleaseSpillLockGPR(rd, rs);
|
||||
}
|
||||
|
||||
void RiscVRegCache::MapGPRDirtyDirtyInIn(IRReg rd1, IRReg rd2, IRReg rs, IRReg rt, bool avoidLoad) {
|
||||
SpillLockGPR(rd1, rd2, rs, rt);
|
||||
bool load1 = !avoidLoad || (rd1 == rs || rd1 == rt);
|
||||
bool load2 = !avoidLoad || (rd2 == rs || rd2 == rt);
|
||||
MapGPR(rd1, load1 ? MIPSMap::DIRTY : MIPSMap::NOINIT);
|
||||
MapGPR(rd2, load2 ? MIPSMap::DIRTY : MIPSMap::NOINIT);
|
||||
MapGPR(rt);
|
||||
MapGPR(rs);
|
||||
ReleaseSpillLockGPR(rd1, rd2, rs, rt);
|
||||
}
|
||||
|
||||
RiscVReg RiscVRegCache::MapFPR(IRReg mipsReg, MIPSMap mapFlags) {
|
||||
_dbg_assert_(IsValidFPR(mipsReg));
|
||||
_dbg_assert_(mr[mipsReg + 32].loc == MIPSLoc::MEM || mr[mipsReg + 32].loc == MIPSLoc::FREG);
|
||||
@@ -288,27 +269,6 @@ RiscVReg RiscVRegCache::MapFPR(IRReg mipsReg, MIPSMap mapFlags) {
|
||||
return INVALID_REG;
|
||||
}
|
||||
|
||||
void RiscVRegCache::MapFPRDirtyInIn(IRReg rd, IRReg rs, IRReg rt, bool avoidLoad) {
|
||||
SpillLockFPR(rd, rs, rt);
|
||||
bool load = !avoidLoad || (rd == rs || rd == rt);
|
||||
MapFPR(rd, load ? MIPSMap::DIRTY : MIPSMap::NOINIT);
|
||||
MapFPR(rt);
|
||||
MapFPR(rs);
|
||||
ReleaseSpillLockFPR(rd, rs, rt);
|
||||
}
|
||||
|
||||
void RiscVRegCache::MapFPR4DirtyIn(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)
|
||||
MapFPR(rdbase + i, load ? MIPSMap::DIRTY : MIPSMap::NOINIT);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
MapFPR(rsbase + i);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
ReleaseSpillLockFPR(rdbase + i, rsbase + i);
|
||||
}
|
||||
|
||||
void RiscVRegCache::AdjustNativeRegAsPtr(IRNativeReg nreg, bool state) {
|
||||
RiscVReg r = (RiscVReg)(X0 + nreg);
|
||||
_assert_(r >= X0 && r <= X31);
|
||||
|
||||
@@ -49,16 +49,8 @@ public:
|
||||
// Returns an RV register containing the requested MIPS register.
|
||||
RiscVGen::RiscVReg MapGPR(IRReg reg, MIPSMap mapFlags = MIPSMap::INIT);
|
||||
RiscVGen::RiscVReg MapGPRAsPointer(IRReg reg);
|
||||
|
||||
void MapGPRDirtyIn(IRReg rd, IRReg rs, bool avoidLoad = true);
|
||||
void MapGPRDirtyDirtyInIn(IRReg rd1, IRReg rd2, IRReg rs, IRReg rt, bool avoidLoad = true);
|
||||
|
||||
// Returns a RISC-V register containing the requested MIPS register.
|
||||
RiscVGen::RiscVReg MapFPR(IRReg reg, MIPSMap mapFlags = MIPSMap::INIT);
|
||||
|
||||
void MapFPRDirtyInIn(IRReg rd, IRReg rs, IRReg rt, bool avoidLoad = true);
|
||||
void MapFPR4DirtyIn(IRReg rdbase, IRReg rsbase, bool avoidLoad = true);
|
||||
|
||||
RiscVGen::RiscVReg MapWithFPRTemp(IRInst &inst);
|
||||
|
||||
bool IsNormalized32(IRReg reg);
|
||||
|
||||
Reference in new issue
Block a user