mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-01 22:31:58 +00:00
armjit: Replace MOVI2R with using the regcache.
So that it can optimize the value with existing imms. Not actually optimizing yet.
This commit is contained in:
parent
d092f7dd2d
commit
7e46ee0b0f
@ -61,7 +61,7 @@ namespace MIPSComp
|
||||
if (TryMakeOperand2(uimm, op2)) {
|
||||
(this->*arith)(gpr.R(rt), gpr.R(rs), op2);
|
||||
} else {
|
||||
MOVI2R(R0, (u32)uimm);
|
||||
gpr.SetRegImm(R0, (u32)uimm);
|
||||
(this->*arith)(gpr.R(rt), gpr.R(rs), R0);
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ void Jit::BranchRSZeroComp(MIPSOpcode op, ArmGen::CCFlags cc, bool andLink, bool
|
||||
// Take the branch
|
||||
if (andLink)
|
||||
{
|
||||
MOVI2R(R0, js.compilerPC + 8);
|
||||
gpr.SetRegImm(R0, js.compilerPC + 8);
|
||||
STR(R0, CTXREG, MIPS_REG_RA * 4);
|
||||
}
|
||||
|
||||
@ -356,7 +356,7 @@ void Jit::Comp_Jump(MIPSOpcode op)
|
||||
|
||||
case 3: //jal
|
||||
gpr.MapReg(MIPS_REG_RA, MAP_NOINIT | MAP_DIRTY);
|
||||
MOVI2R(gpr.R(MIPS_REG_RA), js.compilerPC + 8);
|
||||
gpr.SetRegImm(gpr.R(MIPS_REG_RA), js.compilerPC + 8);
|
||||
CompileDelaySlot(DELAYSLOT_NICE);
|
||||
FlushAll();
|
||||
WriteExit(targetAddr, js.nextExit++);
|
||||
@ -419,7 +419,7 @@ void Jit::Comp_JumpReg(MIPSOpcode op)
|
||||
case 8: //jr
|
||||
break;
|
||||
case 9: //jalr
|
||||
MOVI2R(R0, js.compilerPC + 8);
|
||||
gpr.SetRegImm(R0, js.compilerPC + 8);
|
||||
STR(R0, CTXREG, (int)rd * 4);
|
||||
break;
|
||||
default:
|
||||
@ -446,12 +446,12 @@ void Jit::Comp_Syscall(MIPSOpcode op)
|
||||
void *quickFunc = GetQuickSyscallFunc(op);
|
||||
if (quickFunc)
|
||||
{
|
||||
MOVI2R(R0, (u32)(intptr_t)GetSyscallInfo(op));
|
||||
gpr.SetRegImm(R0, (u32)(intptr_t)GetSyscallInfo(op));
|
||||
QuickCallFunction(R1, quickFunc);
|
||||
}
|
||||
else
|
||||
{
|
||||
MOVI2R(R0, op.encoding);
|
||||
gpr.SetRegImm(R0, op.encoding);
|
||||
QuickCallFunction(R1, (void *)&CallSyscall);
|
||||
}
|
||||
RestoreDowncount();
|
||||
|
@ -108,7 +108,7 @@ void Jit::Comp_FPULS(MIPSOpcode op)
|
||||
fpr.MapReg(ft, MAP_NOINIT | MAP_DIRTY);
|
||||
if (gpr.IsImm(rs)) {
|
||||
u32 addr = (offset + gpr.GetImm(rs)) & 0x3FFFFFFF;
|
||||
MOVI2R(R0, addr + (u32)Memory::base);
|
||||
gpr.SetRegImm(R0, addr + (u32)Memory::base);
|
||||
} else {
|
||||
gpr.MapReg(rs);
|
||||
if (g_Config.bFastMemory) {
|
||||
@ -152,7 +152,7 @@ void Jit::Comp_FPULS(MIPSOpcode op)
|
||||
fpr.MapReg(ft);
|
||||
if (gpr.IsImm(rs)) {
|
||||
u32 addr = (offset + gpr.GetImm(rs)) & 0x3FFFFFFF;
|
||||
MOVI2R(R0, addr + (u32)Memory::base);
|
||||
gpr.SetRegImm(R0, addr + (u32)Memory::base);
|
||||
} else {
|
||||
gpr.MapReg(rs);
|
||||
if (g_Config.bFastMemory) {
|
||||
|
@ -78,10 +78,10 @@ namespace MIPSComp
|
||||
} else {
|
||||
// Try to avoid using MOVT
|
||||
if (offset < 0) {
|
||||
MOVI2R(R0, (u32)(-offset));
|
||||
gpr.SetRegImm(R0, (u32)(-offset));
|
||||
SUB(R0, gpr.R(rs), R0);
|
||||
} else {
|
||||
MOVI2R(R0, (u32)offset);
|
||||
gpr.SetRegImm(R0, (u32)offset);
|
||||
ADD(R0, gpr.R(rs), R0);
|
||||
}
|
||||
}
|
||||
@ -156,7 +156,7 @@ namespace MIPSComp
|
||||
u32 addr = iaddr & 0x3FFFFFFF;
|
||||
// Must be OK even if rs == rt since we have the value from imm already.
|
||||
gpr.MapReg(rt, load ? MAP_NOINIT | MAP_DIRTY : 0);
|
||||
MOVI2R(R0, addr & ~3);
|
||||
gpr.SetRegImm(R0, addr & ~3);
|
||||
|
||||
u8 shift = (addr & 3) * 8;
|
||||
|
||||
@ -329,7 +329,7 @@ namespace MIPSComp
|
||||
u32 addr = iaddr & 0x3FFFFFFF;
|
||||
// Must be OK even if rs == rt since we have the value from imm already.
|
||||
gpr.MapReg(rt, load ? MAP_NOINIT | MAP_DIRTY : 0);
|
||||
MOVI2R(R0, addr);
|
||||
gpr.SetRegImm(R0, addr);
|
||||
} else {
|
||||
_dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address? CPU bug?");
|
||||
load ? gpr.MapDirtyIn(rt, rs) : gpr.MapInIn(rt, rs);
|
||||
|
@ -254,7 +254,7 @@ namespace MIPSComp
|
||||
fpr.MapRegV(vt, MAP_DIRTY | MAP_NOINIT);
|
||||
if (gpr.IsImm(rs)) {
|
||||
u32 addr = (imm + gpr.GetImm(rs)) & 0x3FFFFFFF;
|
||||
MOVI2R(R0, addr + (u32)Memory::base);
|
||||
gpr.SetRegImm(R0, addr + (u32)Memory::base);
|
||||
} else {
|
||||
gpr.MapReg(rs);
|
||||
if (g_Config.bFastMemory) {
|
||||
@ -292,7 +292,7 @@ namespace MIPSComp
|
||||
fpr.MapRegV(vt);
|
||||
if (gpr.IsImm(rs)) {
|
||||
u32 addr = (imm + gpr.GetImm(rs)) & 0x3FFFFFFF;
|
||||
MOVI2R(R0, addr + (u32)Memory::base);
|
||||
gpr.SetRegImm(R0, addr + (u32)Memory::base);
|
||||
} else {
|
||||
gpr.MapReg(rs);
|
||||
if (g_Config.bFastMemory) {
|
||||
@ -348,7 +348,7 @@ namespace MIPSComp
|
||||
|
||||
if (gpr.IsImm(rs)) {
|
||||
u32 addr = (imm + gpr.GetImm(rs)) & 0x3FFFFFFF;
|
||||
MOVI2R(R0, addr + (u32)Memory::base);
|
||||
gpr.SetRegImm(R0, addr + (u32)Memory::base);
|
||||
} else {
|
||||
gpr.MapReg(rs);
|
||||
if (g_Config.bFastMemory) {
|
||||
@ -397,7 +397,7 @@ namespace MIPSComp
|
||||
|
||||
if (gpr.IsImm(rs)) {
|
||||
u32 addr = (imm + gpr.GetImm(rs)) & 0x3FFFFFFF;
|
||||
MOVI2R(R0, addr + (u32)Memory::base);
|
||||
gpr.SetRegImm(R0, addr + (u32)Memory::base);
|
||||
} else {
|
||||
gpr.MapReg(rs);
|
||||
if (g_Config.bFastMemory) {
|
||||
@ -1588,7 +1588,7 @@ namespace MIPSComp
|
||||
GetVectorRegsPrefixD(dregs, sz, _VD);
|
||||
fpr.MapRegsAndSpillLockV(dregs, sz, MAP_NOINIT | MAP_DIRTY);
|
||||
|
||||
MOVI2R(R0, (u32)(void *)&cst_constants[conNum]);
|
||||
gpr.SetRegImm(R0, (u32)(void *)&cst_constants[conNum]);
|
||||
VLDR(S0, R0, 0);
|
||||
for (int i = 0; i < n; ++i)
|
||||
VMOV(fpr.V(dregs[i]), S0);
|
||||
@ -1652,7 +1652,7 @@ namespace MIPSComp
|
||||
// We should write a custom pure-asm function instead.
|
||||
VMOV(R0, fpr.V(sreg));
|
||||
QuickCallFunction(R1, negSin ? (void *)&SinCosNegSin : (void *)&SinCos);
|
||||
MOVI2R(R0, (u32)(&sincostemp[0]));
|
||||
gpr.SetRegImm(R0, (u32)(&sincostemp[0]));
|
||||
VLDR(S0, R0, 0);
|
||||
VLDR(S1, R0, 4);
|
||||
|
||||
|
@ -109,19 +109,19 @@ void Jit::FlushAll()
|
||||
void Jit::FlushPrefixV()
|
||||
{
|
||||
if ((js.prefixSFlag & JitState::PREFIX_DIRTY) != 0) {
|
||||
MOVI2R(R0, js.prefixS);
|
||||
gpr.SetRegImm(R0, js.prefixS);
|
||||
STR(R0, CTXREG, offsetof(MIPSState, vfpuCtrl[VFPU_CTRL_SPREFIX]));
|
||||
js.prefixSFlag = (JitState::PrefixState) (js.prefixSFlag & ~JitState::PREFIX_DIRTY);
|
||||
}
|
||||
|
||||
if ((js.prefixTFlag & JitState::PREFIX_DIRTY) != 0) {
|
||||
MOVI2R(R0, js.prefixT);
|
||||
gpr.SetRegImm(R0, js.prefixT);
|
||||
STR(R0, CTXREG, offsetof(MIPSState, vfpuCtrl[VFPU_CTRL_TPREFIX]));
|
||||
js.prefixTFlag = (JitState::PrefixState) (js.prefixTFlag & ~JitState::PREFIX_DIRTY);
|
||||
}
|
||||
|
||||
if ((js.prefixDFlag & JitState::PREFIX_DIRTY) != 0) {
|
||||
MOVI2R(R0, js.prefixD);
|
||||
gpr.SetRegImm(R0, js.prefixD);
|
||||
STR(R0, CTXREG, offsetof(MIPSState, vfpuCtrl[VFPU_CTRL_DPREFIX]));
|
||||
js.prefixDFlag = (JitState::PrefixState) (js.prefixDFlag & ~JitState::PREFIX_DIRTY);
|
||||
}
|
||||
@ -230,7 +230,7 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b)
|
||||
// Not intrusive so keeping it around here to experiment with, may help on ARMv6 due to
|
||||
// large/slow construction of 32-bit immediates?
|
||||
JumpTarget backJump = GetCodePtr();
|
||||
MOVI2R(R0, js.blockStart);
|
||||
gpr.SetRegImm(R0, js.blockStart);
|
||||
B((const void *)outerLoopPCInR0);
|
||||
b->checkedEntry = GetCodePtr();
|
||||
SetCC(CC_LT);
|
||||
@ -244,7 +244,7 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b)
|
||||
} else {
|
||||
b->checkedEntry = GetCodePtr();
|
||||
SetCC(CC_LT);
|
||||
MOVI2R(R0, js.blockStart);
|
||||
gpr.SetRegImm(R0, js.blockStart);
|
||||
B((const void *)outerLoopPCInR0);
|
||||
SetCC(CC_AL);
|
||||
}
|
||||
@ -283,7 +283,7 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b)
|
||||
|
||||
if (jo.useForwardJump) {
|
||||
SetJumpTarget(bail);
|
||||
MOVI2R(R0, js.blockStart);
|
||||
gpr.SetRegImm(R0, js.blockStart);
|
||||
B((const void *)outerLoopPCInR0);
|
||||
}
|
||||
|
||||
@ -329,9 +329,9 @@ void Jit::Comp_Generic(MIPSOpcode op)
|
||||
if (func)
|
||||
{
|
||||
SaveDowncount();
|
||||
MOVI2R(R0, js.compilerPC);
|
||||
gpr.SetRegImm(R0, js.compilerPC);
|
||||
MovToPC(R0);
|
||||
MOVI2R(R0, op.encoding);
|
||||
gpr.SetRegImm(R0, op.encoding);
|
||||
QuickCallFunction(R1, (void *)func);
|
||||
RestoreDowncount();
|
||||
}
|
||||
@ -373,7 +373,7 @@ void Jit::WriteDownCount(int offset)
|
||||
} else {
|
||||
// Should be fine to use R2 here, flushed the regcache anyway.
|
||||
// If js.downcountAmount can be expressed as an Imm8, we don't need this anyway.
|
||||
MOVI2R(R2, theDowncount);
|
||||
gpr.SetRegImm(R2, theDowncount);
|
||||
SUBS(R7, R7, R2);
|
||||
}
|
||||
} else {
|
||||
@ -386,7 +386,7 @@ void Jit::WriteDownCount(int offset)
|
||||
} else {
|
||||
// Should be fine to use R2 here, flushed the regcache anyway.
|
||||
// If js.downcountAmount can be expressed as an Imm8, we don't need this anyway.
|
||||
MOVI2R(R2, theDowncount);
|
||||
gpr.SetRegImm(R2, theDowncount);
|
||||
SUBS(R1, R1, R2);
|
||||
STR(R1, CTXREG, offsetof(MIPSState, downcount));
|
||||
}
|
||||
@ -412,7 +412,7 @@ void Jit::WriteExit(u32 destination, int exit_num)
|
||||
B(blocks.GetBlock(block)->checkedEntry);
|
||||
b->linkStatus[exit_num] = true;
|
||||
} else {
|
||||
MOVI2R(R0, destination);
|
||||
gpr.SetRegImm(R0, destination);
|
||||
B((const void *)dispatcherPCInR0);
|
||||
}
|
||||
}
|
||||
|
@ -100,6 +100,10 @@ bool ArmRegCache::IsMappedAsPointer(MIPSGPReg mipsReg) {
|
||||
return mr[mipsReg].loc == ML_ARMREG_AS_PTR;
|
||||
}
|
||||
|
||||
void ArmRegCache::SetRegImm(ARMReg reg, u32 imm) {
|
||||
emit_->MOVI2R(reg, imm);
|
||||
}
|
||||
|
||||
void ArmRegCache::MapRegTo(ARMReg reg, MIPSGPReg mipsReg, int mapFlags) {
|
||||
ar[reg].isDirty = (mapFlags & MAP_DIRTY) ? true : false;
|
||||
if (!(mapFlags & MAP_NOINIT)) {
|
||||
@ -119,7 +123,7 @@ void ArmRegCache::MapRegTo(ARMReg reg, MIPSGPReg mipsReg, int mapFlags) {
|
||||
mr[mipsReg].loc = ML_ARMREG;
|
||||
break;
|
||||
case ML_IMM:
|
||||
emit_->MOVI2R(reg, mr[mipsReg].imm);
|
||||
SetRegImm(reg, mr[mipsReg].imm);
|
||||
ar[reg].isDirty = true; // IMM is always dirty.
|
||||
|
||||
// If we are mapping dirty, it means we're gonna overwrite.
|
||||
@ -311,7 +315,7 @@ void ArmRegCache::FlushR(MIPSGPReg r) {
|
||||
case ML_IMM:
|
||||
// IMM is always "dirty".
|
||||
if (r != MIPS_REG_ZERO) {
|
||||
emit_->MOVI2R(R0, mr[r].imm);
|
||||
SetRegImm(R0, mr[r].imm);
|
||||
emit_->STR(R0, CTXREG, GetMipsRegOffset(r));
|
||||
}
|
||||
break;
|
||||
|
@ -90,6 +90,8 @@ public:
|
||||
void SetImm(MIPSGPReg reg, u32 immVal);
|
||||
bool IsImm(MIPSGPReg reg) const;
|
||||
u32 GetImm(MIPSGPReg reg) const;
|
||||
// Optimally set a register to an imm value (possibly using another register.)
|
||||
void SetRegImm(ARMReg reg, u32 imm);
|
||||
|
||||
// Returns an ARM register containing the requested MIPS register.
|
||||
ARMReg MapReg(MIPSGPReg reg, int mapFlags = 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user