mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
ARMJIT Experiment: Keep downcount in a register. Needs benchmarking.
This commit is contained in:
parent
fe090e8d95
commit
76a937f489
6 changed files with 76 additions and 23 deletions
|
@ -116,12 +116,14 @@ void Jit::GenerateFixedCode()
|
|||
MOVI2R(R11, (u32)Memory::base);
|
||||
MOVI2R(R10, (u32)mips_);
|
||||
MOVI2R(R9, (u32)GetBasePtr());
|
||||
|
||||
RestoreDowncount();
|
||||
MovFromPC(R0);
|
||||
outerLoopPCInR0 = GetCodePtr();
|
||||
MovToPC(R0);
|
||||
outerLoop = GetCodePtr();
|
||||
SaveDowncount();
|
||||
QuickCallFunction(R0, (void *)&CoreTiming::Advance);
|
||||
RestoreDowncount();
|
||||
FixupBranch skipToRealDispatch = B(); //skip the sync and compare first time
|
||||
|
||||
dispatcherCheckCoreState = GetCodePtr();
|
||||
|
@ -174,7 +176,9 @@ void Jit::GenerateFixedCode()
|
|||
SetCC(CC_AL);
|
||||
|
||||
//Ok, no block, let's jit
|
||||
SaveDowncount();
|
||||
QuickCallFunction(R2, (void *)&JitAt);
|
||||
RestoreDowncount();
|
||||
|
||||
B(dispatcherNoCheck); // no point in special casing this
|
||||
|
||||
|
@ -187,8 +191,8 @@ void Jit::GenerateFixedCode()
|
|||
B_CC(CC_EQ, outerLoop);
|
||||
|
||||
SetJumpTarget(badCoreState);
|
||||
|
||||
breakpointBailout = GetCodePtr();
|
||||
SaveDowncount();
|
||||
|
||||
ADD(_SP, _SP, 4);
|
||||
|
||||
|
|
|
@ -414,7 +414,9 @@ void Jit::Comp_Syscall(u32 op)
|
|||
js.downcountAmount = -offset;
|
||||
|
||||
MOVI2R(R0, op);
|
||||
SaveDowncount();
|
||||
QuickCallFunction(R1, (void *)&CallSyscall);
|
||||
RestoreDowncount();
|
||||
|
||||
WriteSyscallExit();
|
||||
js.compiling = false;
|
||||
|
|
|
@ -56,7 +56,7 @@ void DisassembleArm(const u8 *data, int size) {
|
|||
namespace MIPSComp
|
||||
{
|
||||
|
||||
Jit::Jit(MIPSState *mips) : blocks(mips, this), gpr(mips), fpr(mips), mips_(mips)
|
||||
Jit::Jit(MIPSState *mips) : blocks(mips, this), gpr(mips, &jo), fpr(mips), mips_(mips)
|
||||
{
|
||||
blocks.Init();
|
||||
gpr.SetEmitter(this);
|
||||
|
@ -286,10 +286,12 @@ void Jit::Comp_Generic(u32 op)
|
|||
MIPSInterpretFunc func = MIPSGetInterpretFunc(op);
|
||||
if (func)
|
||||
{
|
||||
SaveDowncount();
|
||||
MOVI2R(R0, js.compilerPC);
|
||||
MovToPC(R0);
|
||||
MOVI2R(R0, op);
|
||||
QuickCallFunction(R1, (void *)func);
|
||||
RestoreDowncount();
|
||||
}
|
||||
|
||||
// Might have eaten prefixes, hard to tell...
|
||||
|
@ -305,8 +307,31 @@ void Jit::MovToPC(ARMReg r) {
|
|||
STR(r, CTXREG, offsetof(MIPSState, pc));
|
||||
}
|
||||
|
||||
void Jit::SaveDowncount() {
|
||||
if (jo.downcountInRegister)
|
||||
STR(R7, CTXREG, offsetof(MIPSState, downcount));
|
||||
}
|
||||
|
||||
void Jit::RestoreDowncount() {
|
||||
if (jo.downcountInRegister)
|
||||
LDR(R7, CTXREG, offsetof(MIPSState, downcount));
|
||||
}
|
||||
|
||||
void Jit::WriteDownCount(int offset)
|
||||
{
|
||||
if (jo.downcountInRegister) {
|
||||
int theDowncount = js.downcountAmount + offset;
|
||||
Operand2 op2;
|
||||
if (TryMakeOperand2(theDowncount, op2)) // We can enlarge this if we used rotations
|
||||
{
|
||||
SUBS(R7, R7, op2);
|
||||
} 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);
|
||||
SUBS(R7, R7, R2);
|
||||
}
|
||||
} else {
|
||||
int theDowncount = js.downcountAmount + offset;
|
||||
LDR(R1, CTXREG, offsetof(MIPSState, downcount));
|
||||
Operand2 op2;
|
||||
|
@ -321,6 +346,7 @@ void Jit::WriteDownCount(int offset)
|
|||
SUBS(R1, R1, R2);
|
||||
STR(R1, CTXREG, offsetof(MIPSState, downcount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IDEA - could have a WriteDualExit that takes two destinations and two condition flags,
|
||||
|
|
|
@ -36,9 +36,11 @@ struct ArmJitOptions
|
|||
ArmJitOptions()
|
||||
{
|
||||
enableBlocklink = true;
|
||||
downcountInRegister = true;
|
||||
}
|
||||
|
||||
bool enableBlocklink;
|
||||
bool downcountInRegister;
|
||||
};
|
||||
|
||||
struct ArmJitState
|
||||
|
@ -230,6 +232,9 @@ private:
|
|||
void MovFromPC(ARMReg r);
|
||||
void MovToPC(ARMReg r);
|
||||
|
||||
void SaveDowncount();
|
||||
void RestoreDowncount();
|
||||
|
||||
void WriteExit(u32 destination, int exit_num);
|
||||
void WriteExitDestInR(ARMReg Reg);
|
||||
void WriteSyscallExit();
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "ArmRegCache.h"
|
||||
#include "ArmEmitter.h"
|
||||
#include "ArmJit.h"
|
||||
|
||||
#if defined(MAEMO)
|
||||
#include "stddef.h"
|
||||
|
@ -24,7 +25,7 @@
|
|||
|
||||
using namespace ArmGen;
|
||||
|
||||
ArmRegCache::ArmRegCache(MIPSState *mips) : mips_(mips) {
|
||||
ArmRegCache::ArmRegCache(MIPSState *mips, MIPSComp::ArmJitOptions *options) : mips_(mips), options_(options) {
|
||||
}
|
||||
|
||||
void ArmRegCache::Init(ARMXEmitter *emitter) {
|
||||
|
@ -44,18 +45,26 @@ void ArmRegCache::Start(MIPSAnalyst::AnalysisResults &stats) {
|
|||
}
|
||||
}
|
||||
|
||||
static const ARMReg *GetMIPSAllocationOrder(int &count) {
|
||||
const ARMReg *ArmRegCache::GetMIPSAllocationOrder(int &count) {
|
||||
// Note that R0 is reserved as scratch for now.
|
||||
// R1 could be used as it's only used for scratch outside "regalloc space" now.
|
||||
// R12 is also potentially usable.
|
||||
// R4-R7 are registers we could use for static allocation or downcount.
|
||||
// R8 is used to preserve flags in nasty branches.
|
||||
// R9 and upwards are reserved for jit basics.
|
||||
if (options_->downcountInRegister) {
|
||||
static const ARMReg allocationOrder[] = {
|
||||
R2, R3, R4, R5, R6, R7, R12,
|
||||
R2, R3, R4, R5, R6, R12,
|
||||
};
|
||||
count = sizeof(allocationOrder) / sizeof(const int);
|
||||
return allocationOrder;
|
||||
} else {
|
||||
static const ARMReg allocationOrder2[] = {
|
||||
R2, R3, R4, R5, R6, R7, R12,
|
||||
};
|
||||
count = sizeof(allocationOrder2) / sizeof(const int);
|
||||
return allocationOrder2;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Somewhat smarter spilling - currently simply spills the first available, should do
|
||||
|
|
|
@ -68,10 +68,14 @@ enum {
|
|||
MAP_NOINIT = 2,
|
||||
};
|
||||
|
||||
namespace MIPSComp {
|
||||
struct ArmJitOptions;
|
||||
}
|
||||
|
||||
class ArmRegCache
|
||||
{
|
||||
public:
|
||||
ArmRegCache(MIPSState *mips);
|
||||
ArmRegCache(MIPSState *mips, MIPSComp::ArmJitOptions *options);
|
||||
~ArmRegCache() {}
|
||||
|
||||
void Init(ARMXEmitter *emitter);
|
||||
|
@ -107,7 +111,10 @@ public:
|
|||
int GetMipsRegOffset(MIPSReg r);
|
||||
|
||||
private:
|
||||
const ARMReg *GetMIPSAllocationOrder(int &count);
|
||||
|
||||
MIPSState *mips_;
|
||||
MIPSComp::ArmJitOptions *options_;
|
||||
ARMXEmitter *emit;
|
||||
u32 compilerPC_;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue