Armjit: Add option for fastmem. Small optimization.

This commit is contained in:
Henrik Rydgard 2013-01-11 17:25:54 +01:00
parent 9b791b9953
commit bc9c3db303
6 changed files with 54 additions and 53 deletions

View file

@ -43,10 +43,7 @@ namespace MIPSComp
if (gpr.IsImm(rs)) {
gpr.SetImm(rt, (*eval)(gpr.GetImm(rs), uimm));
} else {
gpr.SpillLock(rs, rt);
gpr.MapReg(rt, MAP_DIRTY);
gpr.MapReg(rs);
gpr.ReleaseSpillLocks();
gpr.MapDirtyIn(rt, rs);
// TODO: Special case when uimm can be represented as an Operand2
Operand2 op2;
if (TryMakeOperand2(uimm, op2)) {
@ -76,13 +73,14 @@ namespace MIPSComp
} else if (rs == 0) { // add to zero register = immediate
gpr.SetImm(rt, (u32)simm);
} else {
gpr.SpillLock(rs, rt);
gpr.MapReg(rt, MAP_DIRTY);
gpr.MapReg(rs);
gpr.ReleaseSpillLocks();
gpr.MapDirtyIn(rt, rs);
Operand2 op2;
if (TryMakeOperand2(simm, op2)) {
ADD(gpr.R(rt), gpr.R(rs), op2);
bool negated;
if (TryMakeOperand2_AllowNegation(simm, op2, &negated)) {
if (!negated)
ADD(gpr.R(rt), gpr.R(rs), op2);
else
SUB(gpr.R(rt), gpr.R(rs), op2);
} else {
ARMABI_MOVI2R(R0, (u32)simm);
ADD(gpr.R(rt), gpr.R(rs), R0);
@ -96,11 +94,7 @@ namespace MIPSComp
case 14: CompImmLogic(rs, rt, uimm, &ARMXEmitter::EOR, &EvalXor); break;
case 10: // R(rt) = (s32)R(rs) < simm; break; //slti
gpr.SpillLock(rt, rs);
gpr.MapReg(rs);
gpr.MapReg(rt, MAP_DIRTY);
gpr.ReleaseSpillLocks();
gpr.MapDirtyIn(rt, rs);
{
Operand2 op2;
if (TryMakeOperand2(simm, op2)) {
@ -253,11 +247,7 @@ namespace MIPSComp
int rt = _RT;
int sa = _SA;
gpr.SpillLock(rd, rt);
gpr.MapReg(rt);
gpr.MapReg(rd, MAP_DIRTY);
gpr.ReleaseSpillLocks();
gpr.MapDirtyIn(rd, rt);
MOV(gpr.R(rd), Operand2(sa, shiftType, gpr.R(rt)));
}

View file

@ -425,7 +425,8 @@ void Jit::Comp_Syscall(u32 op)
{
FlushAll();
ARMABI_CallFunctionC((void *)&CallSyscall, op);
ARMABI_MOVI2R(R0, op);
QuickCallFunction(R1, (void *)&CallSyscall);
WriteSyscallExit();
js.compiling = false;

View file

@ -52,20 +52,20 @@ namespace MIPSComp
case 35: //R(rt) = ReadMem32(addr); //lw
case 36: //R(rt) = ReadMem8 (addr); break; //lbu
if (true || g_Config.bFastMemory) {
gpr.SpillLock(rt, rs);
gpr.MapReg(rt, MAP_DIRTY);
gpr.MapReg(rs);
gpr.ReleaseSpillLocks();
if (g_Config.bFastMemory) {
gpr.MapDirtyIn(rt, rs);
Operand2 op2;
if (TryMakeOperand2(offset, op2)) {
ADD(R0, gpr.R(rs), op2);
if (offset) {
if (TryMakeOperand2(offset, op2)) {
ADD(R0, gpr.R(rs), op2);
} else {
ARMABI_MOVI2R(R0, (u32)offset);
ADD(R0, gpr.R(rs), R0);
}
BIC(R0, R0, Operand2(0xC0, 4)); // &= 0x3FFFFFFF
} else {
ARMABI_MOVI2R(R0, (u32)offset);
ADD(R0, gpr.R(rs), R0);
BIC(R0, gpr.R(rs), Operand2(0xC0, 4)); // &= 0x3FFFFFFF
}
BIC(R0, R0, Operand2(0xC0, 4)); // &= 0x3FFFFFFF
ADD(R0, R0, R11); // TODO: Merge with next instruction
if (o == 35) {
LDR(gpr.R(rt), R0);
@ -84,20 +84,20 @@ namespace MIPSComp
case 40: //sb
case 43: //WriteMem32(addr, R(rt)); break; //sw
if (true || g_Config.bFastMemory) {
gpr.SpillLock(rt, rs);
gpr.MapReg(rt);
gpr.MapReg(rs);
gpr.ReleaseSpillLocks();
if (g_Config.bFastMemory) {
gpr.MapInIn(rt, rs);
Operand2 op2;
if (TryMakeOperand2(offset, op2)) {
ADD(R0, gpr.R(rs), op2);
if (offset) {
if (TryMakeOperand2(offset, op2)) {
ADD(R0, gpr.R(rs), op2);
} else {
ARMABI_MOVI2R(R0, (u32)offset);
ADD(R0, gpr.R(rs), R0);
}
BIC(R0, R0, Operand2(0xC0, 4)); // &= 0x3FFFFFFF
} else {
ARMABI_MOVI2R(R0, (u32)offset);
ADD(R0, gpr.R(rs), R0);
BIC(R0, gpr.R(rs), Operand2(0xC0, 4)); // &= 0x3FFFFFFF
}
BIC(R0, R0, Operand2(0xC0, 4)); // &= 0x3FFFFFFF
ADD(R0, R0, R11);
if (o == 43) {
STR(R0, gpr.R(rt));

View file

@ -125,18 +125,25 @@ allocate:
return INVALID_REG;
}
void ArmRegCache::MapDirtyIn(MIPSReg rd, MIPSReg rs) {
void ArmRegCache::MapInIn(MIPSReg rd, MIPSReg rs) {
SpillLock(rd, rs);
// bool overlap == rd == rs
MapReg(rd, MAP_DIRTY); // can get rid of INITVAL in some cases
MapReg(rd);
MapReg(rs);
ReleaseSpillLocks();
}
void ArmRegCache::MapDirtyInIn(MIPSReg rd, MIPSReg rs, MIPSReg rt) {
void ArmRegCache::MapDirtyIn(MIPSReg rd, MIPSReg rs, bool avoidLoad) {
SpillLock(rd, rs);
bool overlap = avoidLoad && rd == rs;
MapReg(rd, MAP_DIRTY | (overlap ? 0 : MAP_NOINIT));
MapReg(rs);
ReleaseSpillLocks();
}
void ArmRegCache::MapDirtyInIn(MIPSReg rd, MIPSReg rs, MIPSReg rt, bool avoidLoad) {
SpillLock(rd, rs, rt);
// bool overlap == rd == rs || rt == rd || rs == rt;
MapReg(rd, MAP_DIRTY); // can get rid of INITVAL in some cases
bool overlap = avoidLoad && (rd == rs || rd == rt);
MapReg(rd, MAP_DIRTY | (overlap ? 0 : MAP_NOINIT));
MapReg(rt);
MapReg(rs);
ReleaseSpillLocks();

View file

@ -85,8 +85,9 @@ public:
// Returns an ARM register containing the requested MIPS register.
ARMReg MapReg(MIPSReg reg, int mapFlags = 0);
void MapDirtyIn(MIPSReg rd, MIPSReg rs);
void MapDirtyInIn(MIPSReg rd, MIPSReg rs, MIPSReg rt);
void MapInIn(MIPSReg rd, MIPSReg rs);
void MapDirtyIn(MIPSReg rd, MIPSReg rs, bool avoidLoad = true);
void MapDirtyInIn(MIPSReg rd, MIPSReg rs, MIPSReg rt, bool avoidLoad = true);
void FlushArmReg(ARMReg r);
void FlushMipsReg(MIPSReg r);

View file

@ -287,10 +287,12 @@ void SettingsScreen::render() {
g_Config.iWindowZoom = doubleRes ? 2 : 1;
}
UICheckBox(GEN_ID, x, y += stride, "Hardware Transform", ALIGN_TOPLEFT, &g_Config.bHardwareTransform);
UICheckBox(GEN_ID, x, y += stride, "Use VBO for drawing", ALIGN_TOPLEFT, &g_Config.bUseVBO);
UICheckBox(GEN_ID, x, y += stride, "Draw using VBO", ALIGN_TOPLEFT, &g_Config.bUseVBO);
bool useJit = g_Config.iCpuCore == CPU_JIT;
UICheckBox(GEN_ID, x, y += stride, "Use Dynarec (JIT)", ALIGN_TOPLEFT, &useJit);
UICheckBox(GEN_ID, x, y += stride, "JIT (Dynarec)", ALIGN_TOPLEFT, &useJit);
if (g_Config.iCpuCore == CPU_JIT)
UICheckBox(GEN_ID, x + 350, y, "Fastmem (unstable)", ALIGN_TOPLEFT, &g_Config.bFastMemory);
g_Config.iCpuCore = useJit ? CPU_JIT : CPU_INTERPRETER;
// ui_draw2d.DrawText(UBUNTU48, "much faster JIT coming later", x, y+=50, 0xcFFFFFFF, ALIGN_LEFT);
UICheckBox(GEN_ID, x, y += stride, "On-screen Touch Controls", ALIGN_TOPLEFT, &g_Config.bShowTouchControls);