mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-27 23:40:39 +00:00
Fix bugs and issues in ARM64 static alloc. Thanks unknown for finding the problem.
This commit is contained in:
parent
a0bf934796
commit
844a3f19a9
@ -94,18 +94,27 @@ namespace MIPSComp {
|
||||
using namespace Arm64JitConstants;
|
||||
|
||||
void Arm64Jit::GenerateFixedCode(const JitOptions &jo) {
|
||||
saveStaticRegisters = AlignCode16();
|
||||
const u8 *start = saveStaticRegisters;
|
||||
STR(INDEX_UNSIGNED, DOWNCOUNTREG, CTXREG, offsetof(MIPSState, downcount));
|
||||
gpr.EmitSaveStaticAllocs();
|
||||
RET();
|
||||
const u8 *start = nullptr;
|
||||
if (jo.useStaticAlloc) {
|
||||
saveStaticRegisters = AlignCode16();
|
||||
STR(INDEX_UNSIGNED, DOWNCOUNTREG, CTXREG, offsetof(MIPSState, downcount));
|
||||
gpr.EmitSaveStaticAllocs();
|
||||
RET();
|
||||
|
||||
loadStaticRegisters = AlignCode16();
|
||||
gpr.EmitLoadStaticAllocs();
|
||||
LDR(INDEX_UNSIGNED, DOWNCOUNTREG, CTXREG, offsetof(MIPSState, downcount));
|
||||
RET();
|
||||
loadStaticRegisters = AlignCode16();
|
||||
gpr.EmitLoadStaticAllocs();
|
||||
LDR(INDEX_UNSIGNED, DOWNCOUNTREG, CTXREG, offsetof(MIPSState, downcount));
|
||||
RET();
|
||||
|
||||
start = saveStaticRegisters;
|
||||
} else {
|
||||
saveStaticRegisters = nullptr;
|
||||
loadStaticRegisters = nullptr;
|
||||
}
|
||||
|
||||
enterCode = AlignCode16();
|
||||
if (!start)
|
||||
start = enterCode;
|
||||
|
||||
BitSet32 regs_to_save(Arm64Gen::ALL_CALLEE_SAVED);
|
||||
BitSet32 regs_to_save_fp(Arm64Gen::ALL_CALLEE_SAVED_FP);
|
||||
@ -219,7 +228,7 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) {
|
||||
}
|
||||
|
||||
// Leave this at the end, add more stuff above.
|
||||
if (true) {
|
||||
if (false) {
|
||||
std::vector<std::string> lines = DisassembleArm64(start, GetCodePtr() - start);
|
||||
for (auto s : lines) {
|
||||
INFO_LOG(JIT, "%s", s.c_str());
|
||||
|
@ -485,11 +485,20 @@ void Arm64Jit::MovToPC(ARM64Reg r) {
|
||||
|
||||
// Should not really be necessary except when entering Advance
|
||||
void Arm64Jit::SaveStaticRegisters() {
|
||||
QuickCallFunction(SCRATCH2_64, saveStaticRegisters);
|
||||
if (jo.useStaticAlloc) {
|
||||
QuickCallFunction(SCRATCH2_64, saveStaticRegisters);
|
||||
} else {
|
||||
// Inline the single operation
|
||||
STR(INDEX_UNSIGNED, DOWNCOUNTREG, CTXREG, offsetof(MIPSState, downcount));
|
||||
}
|
||||
}
|
||||
|
||||
void Arm64Jit::LoadStaticRegisters() {
|
||||
QuickCallFunction(SCRATCH2_64, loadStaticRegisters);
|
||||
if (jo.useStaticAlloc) {
|
||||
QuickCallFunction(SCRATCH2_64, loadStaticRegisters);
|
||||
} else {
|
||||
LDR(INDEX_UNSIGNED, DOWNCOUNTREG, CTXREG, offsetof(MIPSState, downcount));
|
||||
}
|
||||
}
|
||||
|
||||
void Arm64Jit::WriteDownCount(int offset) {
|
||||
|
@ -66,20 +66,36 @@ const ARM64Reg *Arm64RegCache::GetMIPSAllocationOrder(int &count) {
|
||||
|
||||
// W19-W22 are most suitable for static allocation. Those that are chosen for static allocation
|
||||
// should be omitted here and added in GetStaticAllocations.
|
||||
|
||||
static const ARM64Reg allocationOrder[] = {
|
||||
W19, W20, W21, W22, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15,
|
||||
};
|
||||
static const ARM64Reg allocationOrderStaticAlloc[] = {
|
||||
W20, W21, W22, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15,
|
||||
};
|
||||
count = ARRAY_SIZE(allocationOrder);
|
||||
return allocationOrder;
|
||||
|
||||
if (jo_->useStaticAlloc) {
|
||||
count = ARRAY_SIZE(allocationOrderStaticAlloc);
|
||||
return allocationOrderStaticAlloc;
|
||||
} else {
|
||||
count = ARRAY_SIZE(allocationOrder);
|
||||
return allocationOrder;
|
||||
}
|
||||
}
|
||||
|
||||
const Arm64RegCache::StaticAllocation *Arm64RegCache::GetStaticAllocations(int &count) {
|
||||
static const StaticAllocation none[] = {
|
||||
};
|
||||
static const StaticAllocation allocs[] = {
|
||||
{MIPS_REG_V0, W19},
|
||||
};
|
||||
count = ARRAY_SIZE(allocs);
|
||||
return allocs;
|
||||
|
||||
if (jo_->useStaticAlloc) {
|
||||
count = ARRAY_SIZE(allocs);
|
||||
return allocs;
|
||||
} else {
|
||||
count = 0;
|
||||
return none;
|
||||
}
|
||||
}
|
||||
|
||||
void Arm64RegCache::EmitLoadStaticAllocs() {
|
||||
@ -194,8 +210,8 @@ ARM64Reg Arm64RegCache::FindBestToSpill(bool unusedOnly, bool *clobbered) {
|
||||
ARM64Reg reg = allocOrder[i];
|
||||
if (ar[reg].mipsReg != MIPS_REG_INVALID && mr[ar[reg].mipsReg].spillLock)
|
||||
continue;
|
||||
if (mr[ar[reg].mipsReg].isStatic)
|
||||
continue;
|
||||
|
||||
// As it's in alloc-order, we know it's not static so we don't need to check for that.
|
||||
|
||||
// Awesome, a clobbered reg. Let's use it.
|
||||
if (MIPSAnalyst::IsRegisterClobbered(ar[reg].mipsReg, compilerPC_, UNUSED_LOOKAHEAD_OPS)) {
|
||||
@ -222,8 +238,20 @@ ARM64Reg Arm64RegCache::MapReg(MIPSGPReg mipsReg, int mapFlags) {
|
||||
return INVALID_REG;
|
||||
}
|
||||
|
||||
if (mipsReg == MIPS_REG_INVALID) {
|
||||
ERROR_LOG(JIT, "Cannot map invalid register");
|
||||
return INVALID_REG;
|
||||
}
|
||||
|
||||
ARM64Reg armReg = mr[mipsReg].reg;
|
||||
|
||||
if (mr[mipsReg].isStatic) {
|
||||
// Dirty or not doesn't matter as it's a fixed register.
|
||||
// Erasing the imm on dirty (necessary since otherwise we will still think it's ML_ARMREG_IMM and return
|
||||
// true for IsImm and calculate crazily wrong things). /unknown
|
||||
if (mapFlags & MAP_DIRTY) {
|
||||
mr[mipsReg].loc = ML_ARMREG;
|
||||
ar[armReg].pointerified = false;
|
||||
}
|
||||
return mr[mipsReg].reg;
|
||||
}
|
||||
|
||||
@ -231,7 +259,6 @@ ARM64Reg Arm64RegCache::MapReg(MIPSGPReg mipsReg, int mapFlags) {
|
||||
// We don't need to check for ML_NOINIT because we assume that anyone who maps
|
||||
// with that flag immediately writes a "known" value to the register.
|
||||
if (mr[mipsReg].loc == ML_ARMREG || mr[mipsReg].loc == ML_ARMREG_IMM) {
|
||||
ARM64Reg armReg = mr[mipsReg].reg;
|
||||
if (ar[armReg].mipsReg != mipsReg) {
|
||||
ERROR_LOG_REPORT(JIT, "Register mapping out of sync! %i", mipsReg);
|
||||
}
|
||||
@ -369,7 +396,6 @@ void Arm64RegCache::FlushArmReg(ARM64Reg r) {
|
||||
ELOG("Cannot FlushArmReg a statically mapped register");
|
||||
return;
|
||||
}
|
||||
|
||||
auto &mreg = mr[ar[r].mipsReg];
|
||||
if (mreg.loc == ML_ARMREG_IMM || ar[r].mipsReg == MIPS_REG_ZERO) {
|
||||
// We know its immedate value, no need to STR now.
|
||||
@ -384,7 +410,6 @@ void Arm64RegCache::FlushArmReg(ARM64Reg r) {
|
||||
mreg.reg = INVALID_REG;
|
||||
mreg.imm = 0;
|
||||
}
|
||||
|
||||
ar[r].isDirty = false;
|
||||
ar[r].mipsReg = MIPS_REG_INVALID;
|
||||
ar[r].pointerified = false;
|
||||
@ -566,7 +591,6 @@ void Arm64RegCache::FlushAll() {
|
||||
ELOG("ARM reg of static %i is invalid", i);
|
||||
continue;
|
||||
}
|
||||
ar[mr[i].reg].mipsReg = MIPS_REG_INVALID; // make the sanity check happy
|
||||
continue;
|
||||
}
|
||||
FlushR(mipsReg);
|
||||
@ -574,7 +598,7 @@ void Arm64RegCache::FlushAll() {
|
||||
|
||||
// Sanity check
|
||||
for (int i = 0; i < NUM_ARMREG; i++) {
|
||||
if (ar[i].mipsReg != MIPS_REG_INVALID) {
|
||||
if (ar[i].mipsReg != MIPS_REG_INVALID && mr[ar[i].mipsReg].isStatic == false) {
|
||||
ERROR_LOG_REPORT(JIT, "Flush fail: ar[%i].mipsReg=%i", i, ar[i].mipsReg);
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +118,7 @@ public:
|
||||
void FlushArmReg(Arm64Gen::ARM64Reg r);
|
||||
void FlushBeforeCall();
|
||||
void FlushAll();
|
||||
void FlushR(MIPSGPReg r);
|
||||
void DiscardR(MIPSGPReg r);
|
||||
|
||||
Arm64Gen::ARM64Reg R(MIPSGPReg preg); // Returns a cached register, while checking that it's NOT mapped as a pointer
|
||||
@ -144,7 +145,6 @@ private:
|
||||
void MapRegTo(Arm64Gen::ARM64Reg reg, MIPSGPReg mipsReg, int mapFlags);
|
||||
Arm64Gen::ARM64Reg FindBestToSpill(bool unusedOnly, bool *clobbered);
|
||||
Arm64Gen::ARM64Reg ARM64RegForFlush(MIPSGPReg r);
|
||||
void FlushR(MIPSGPReg r);
|
||||
|
||||
MIPSState *mips_;
|
||||
Arm64Gen::ARM64XEmitter *emit_;
|
||||
|
@ -45,5 +45,10 @@ namespace MIPSComp {
|
||||
continueBranches = false;
|
||||
continueJumps = false;
|
||||
continueMaxInstructions = 300;
|
||||
|
||||
useStaticAlloc = false;
|
||||
#ifdef ARM64
|
||||
useStaticAlloc = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user