Пример #1
0
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;
    }
}
Пример #2
0
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;		 
}
Пример #3
0
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;
}