ARMReg ArmRegCache::BindToRegister(u32 preg) { _assert_msg_(DYNA_REC, regs[preg].GetType() == REG_IMM, "Can't BindToRegister with a REG"); u32 lastRegIndex = GetLeastUsedRegister(false); u32 freeRegIndex; if (FindFreeRegister(freeRegIndex)) { emit->MOVI2R(ArmCRegs[freeRegIndex].Reg, regs[preg].GetImm()); ArmCRegs[freeRegIndex].PPCReg = preg; ArmCRegs[freeRegIndex].LastLoad = 0; regs[preg].LoadToReg(freeRegIndex); return ArmCRegs[freeRegIndex].Reg; } else { emit->STR(ArmCRegs[lastRegIndex].Reg, R9, PPCSTATE_OFF(gpr) + ArmCRegs[lastRegIndex].PPCReg * 4); emit->MOVI2R(ArmCRegs[lastRegIndex].Reg, regs[preg].GetImm()); regs[ArmCRegs[lastRegIndex].PPCReg].Flush(); ArmCRegs[lastRegIndex].PPCReg = preg; ArmCRegs[lastRegIndex].LastLoad = 0; regs[preg].LoadToReg(lastRegIndex); return ArmCRegs[lastRegIndex].Reg; } }
ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad) { u32 lastRegIndex = GetLeastUsedRegister(true); if (_regs[preg][PS1].GetType() != REG_NOTLOADED) { u8 a = _regs[preg][PS1].GetRegIndex(); ArmCRegs[a].LastLoad = 0; if (_regs[preg][PS1].GetType() == REG_AWAY && preLoad) { s16 offset = PPCSTATE_OFF(ps) + (preg * 16) + (PS1 ? 8 : 0); emit->VLDR(ArmCRegs[a].Reg, R9, offset); _regs[preg][PS1].LoadToReg(a); } return ArmCRegs[a].Reg; } u32 regindex; if (FindFreeRegister(regindex)) { s16 offset = PPCSTATE_OFF(ps) + (preg * 16) + (PS1 ? 8 : 0); emit->VLDR(ArmCRegs[regindex].Reg, R9, offset); ArmCRegs[regindex].PPCReg = preg; ArmCRegs[regindex].LastLoad = 0; _regs[preg][PS1].LoadToReg(regindex); return ArmCRegs[regindex].Reg; } // Alright, we couldn't get a free space, dump that least used register s16 offsetOld = PPCSTATE_OFF(ps) + (ArmCRegs[lastRegIndex].PPCReg * 16) + (ArmCRegs[lastRegIndex].PS1 ? 8 : 0); s16 offsetNew = PPCSTATE_OFF(ps) + (preg * 16) + (PS1 ? 8 : 0); emit->VSTR(ArmCRegs[lastRegIndex].Reg, R9, offsetOld); emit->VLDR(ArmCRegs[lastRegIndex].Reg, R9, offsetNew); _regs[ArmCRegs[lastRegIndex].PPCReg][PS1].Flush(); ArmCRegs[lastRegIndex].PPCReg = preg; ArmCRegs[lastRegIndex].LastLoad = 0; ArmCRegs[lastRegIndex].PS1 = PS1; _regs[preg][PS1].LoadToReg(lastRegIndex); return ArmCRegs[lastRegIndex].Reg; }
ARMReg ArmRegCache::R(u32 preg) { if (regs[preg].GetType() == REG_IMM) return BindToRegister(preg); u32 lastRegIndex = GetLeastUsedRegister(true); // Check if already Loaded if (regs[preg].GetType() == REG_REG) { u8 a = regs[preg].GetRegIndex(); ArmCRegs[a].LastLoad = 0; return ArmCRegs[a].Reg; } // Check if we have a free register u32 regindex; if (FindFreeRegister(regindex)) { emit->LDR(ArmCRegs[regindex].Reg, R9, PPCSTATE_OFF(gpr) + preg * 4); ArmCRegs[regindex].PPCReg = preg; ArmCRegs[regindex].LastLoad = 0; regs[preg].LoadToReg(regindex); return ArmCRegs[regindex].Reg; } // Alright, we couldn't get a free space, dump that least used register emit->STR(ArmCRegs[lastRegIndex].Reg, R9, PPCSTATE_OFF(gpr) + ArmCRegs[lastRegIndex].PPCReg * 4); emit->LDR(ArmCRegs[lastRegIndex].Reg, R9, PPCSTATE_OFF(gpr) + preg * 4); regs[ArmCRegs[lastRegIndex].PPCReg].Flush(); ArmCRegs[lastRegIndex].PPCReg = preg; ArmCRegs[lastRegIndex].LastLoad = 0; regs[preg].LoadToReg(lastRegIndex); return ArmCRegs[lastRegIndex].Reg; }