It's getting close to the first totally unoptimized jit run.

This commit is contained in:
Henrik Rydgard 2013-01-08 17:03:17 +01:00
parent 5d6ff0bc20
commit 8c06edc47b
13 changed files with 78 additions and 31 deletions

View File

@ -36,6 +36,16 @@ void ARMXEmitter::ARMABI_CallFunctionC(void *func, u32 Arg)
BL(R14);
POP(5, R0, R1, R2, R3, _LR);
}
void ARMXEmitter::ARMABI_CallFunctionCNoSave(void *func, u32 Arg)
{
ARMABI_MOVI2R(R14, Mem(func));
PUSH(1, _LR);
ARMABI_MOVI2R(R0, Arg);
BL(R14);
POP(1, _LR);
}
void ARMXEmitter::ARMABI_CallFunctionCC(void *func, u32 Arg1, u32 Arg2)
{
ARMABI_MOVI2R(R14, Mem(func));

View File

@ -467,6 +467,7 @@ public:
// where appropriate.
void ARMABI_CallFunction(void *func);
void ARMABI_CallFunctionC(void *func, u32 Arg0);
void ARMABI_CallFunctionCNoSave(void *func, u32 Arg0);
void ARMABI_CallFunctionCC(void *func, u32 Arg1, u32 Arg2);
void ARMABI_CallFunctionCCC(void *func, u32 Arg1, u32 Arg2, u32 Arg3);
void ARMABI_PushAllCalleeSavedRegsAndAdjustStack();

View File

@ -1282,7 +1282,11 @@ Thread *__KernelCreateThread(SceUID &id, SceUID moduleId, const char *name, u32
t->nt.gpreg = 0; // sceKernelStartThread will take care of this.
t->moduleId = moduleId;
strncpy(t->nt.name, name, 32);
if (name) {
strncpy(t->nt.name, name, 32);
} else {
ERROR_LOG(HLE, "Threads must have names!");
}
return t;
}
@ -1994,7 +1998,7 @@ ActionAfterMipsCall *Thread::getRunningCallbackAction()
if (this->GetUID() == currentThread && g_inCbCount > 0)
{
MipsCall *call = mipsCalls.get(this->currentCallbackId);
ActionAfterMipsCall *action;
ActionAfterMipsCall *action = 0;
if (call)
action = dynamic_cast<ActionAfterMipsCall *>(call->doAfter);

View File

@ -59,6 +59,7 @@ namespace MIPSComp
switch (op >> 26)
{
/*
case 8: // same as addiu?
case 9: //R(rt) = R(rs) + simm; break; //addiu
{
@ -77,7 +78,7 @@ namespace MIPSComp
gpr.ReleaseSpillLocks();
}
break;
}
}*/
/*
case 13: // OR
{
@ -123,11 +124,11 @@ namespace MIPSComp
gpr.UnlockAll();
break;
*/
case 15: //R(rt) = uimm << 16; break; //lui
gpr.SetImm(rt, uimm << 16);
break;
*/
default:
Comp_Generic(op);

View File

@ -55,7 +55,7 @@ void Jit::BranchRSRTComp(u32 op, ArmGen::CCFlags cc, bool likely)
bool delaySlotIsNice = GetOutReg(delaySlotOp) != rt && GetOutReg(delaySlotOp) != rs;// IsDelaySlotNice(op, delaySlotOp);
if (!delaySlotIsNice)
{
ERROR_LOG(CPU, "Not nice delay slot in BranchRSRTComp :( %08x", js.compilerPC);
//ERROR_LOG(CPU, "Not nice delay slot in BranchRSRTComp :( %08x", js.compilerPC);
}
// The delay slot being nice doesn't really matter though...
if (rt == 0)
@ -63,11 +63,12 @@ void Jit::BranchRSRTComp(u32 op, ArmGen::CCFlags cc, bool likely)
gpr.MapReg(rs, MAP_INITVAL);
CMP(gpr.R(rs), Operand2(0));
}
/*
else if (rs == 0 && (cc == CC_EQ || cc == CC_NEQ)) // only these are easily 'flippable'
{
gpr.MapReg(rt, MAP_INITVAL);
CMP(gpr.R(rt), Operand2(0));
}
}*/
else
{
gpr.SpillLock(rs, rt);
@ -208,7 +209,7 @@ void Jit::BranchFPFlag(u32 op, ArmGen::CCFlags cc, bool likely)
bool delaySlotIsNice = IsDelaySlotNice(op, delaySlotOp);
if (!delaySlotIsNice)
{
ERROR_LOG(CPU, "Not nice delay slot in BranchFPFlag :(");
//ERROR_LOG(CPU, "Not nice delay slot in BranchFPFlag :(");
}
FlushAll();
@ -270,7 +271,7 @@ void Jit::BranchVFPUFlag(u32 op, ArmGen::CCFlags cc, bool likely)
bool delaySlotIsNice = IsDelaySlotNice(op, delaySlotOp);
if (!delaySlotIsNice)
{
ERROR_LOG(CPU, "Not nice delay slot in BranchFPFlag :(");
//ERROR_LOG(CPU, "Not nice delay slot in BranchFPFlag :(");
}
FlushAll();
@ -337,7 +338,7 @@ void Jit::Comp_Jump(u32 op)
case 3: //jal
ARMABI_MOVI2R(R0, Operand2(js.compilerPC + 8, TYPE_IMM));
ARMABI_MOVI2R(R1, Operand2((u32)&mips_->r[MIPS_REG_RA], TYPE_IMM));
ADD(R1, R10, MIPS_REG_RA * 4); // compute address of RA in ram
STR(R1, R0);
WriteExit(targetAddr, 0);
break;

View File

@ -83,6 +83,30 @@ void Hullo(int a, int b, int c, int d) {
INFO_LOG(DYNA_REC, "Hullo %08x %08x %08x %08x", a, b, c, d);
}
static void DisassembleArm(const u8 *data, int size) {
char temp[256];
for (int i = 0; i < size; i += 4) {
const u32 *codePtr = (const u32 *)(data + i);
u32 inst = codePtr[0];
u32 next = (i < size - 4) ? codePtr[1] : 0;
// MAGIC SPECIAL CASE for MOVW/MOVT readability!
if ((inst & 0x0FF00000) == 0x03000000 && (next & 0x0FF00000) == 0x03400000) {
u32 low = ((inst & 0x000F0000) >> 4) | (inst & 0x0FFF);
u32 hi = ((next & 0x000F0000) >> 4) | (next & 0x0FFF);
int reg0 = (inst & 0x0000F000) >> 12;
int reg1 = (next & 0x0000F000) >> 12;
if (reg0 == reg1) {
sprintf(temp, "%08x MOV32? %s, %04x%04x", (u32)inst, ArmRegName(reg0), hi, low);
INFO_LOG(DYNA_REC, "A: %s", temp);
i += 4;
continue;
}
}
ArmDis((u32)codePtr, inst, temp);
INFO_LOG(DYNA_REC, "A: %s", temp);
}
}
const u8 *Jit::DoJit(u32 em_address, ArmJitBlock *b)
{
js.cancel = false;
@ -130,17 +154,13 @@ const u8 *Jit::DoJit(u32 em_address, ArmJitBlock *b)
}
#ifdef LOGASM
MIPSDisAsm(Memory::Read_Instruction(js.compilerPC), js.compilerPC, temp, true);
INFO_LOG(DYNA_REC, "M: %s", temp);
INFO_LOG(DYNA_REC, "M: %08x %s", js.compilerPC, temp);
#endif
b->codeSize = GetCodePtr() - b->normalEntry;
#ifdef LOGASM
for (int i = 0; i < GetCodePtr() - b->checkedEntry; i += 4) {
const u32 *codePtr = (const u32 *)(b->checkedEntry + i);
u32 inst = *codePtr;
ArmDis((u32)codePtr, inst, temp);
INFO_LOG(DYNA_REC, "A: %s", temp);
}
DisassembleArm(b->checkedEntry, GetCodePtr() - b->checkedEntry);
#endif
AlignCode16();
@ -228,7 +248,8 @@ void Jit::WriteExit(u32 destination, int exit_num)
void Jit::WriteSyscallExit()
{
DoDownCount();
B((const void *)asm_.dispatcherCheckCoreState);
ARMABI_MOVI2R(R0, (u32)asm_.dispatcherCheckCoreState);
B(R0);
}

View File

@ -37,8 +37,10 @@ void ArmRegCache::Start(MIPSAnalyst::AnalysisResults &stats) {
ar[i].allocLock = false;
ar[i].isDirty = false;
}
for (int i = 0; i < 32; i++) {
for (int i = 0; i < NUM_MIPSREG; i++) {
mr[i].loc = ML_MEM;
mr[i].reg = INVALID_REG;
mr[i].imm = -1;
}
}
@ -109,12 +111,15 @@ void ArmRegCache::FlushArmReg(ARMReg r) {
// Nothing to do
return;
}
if (ar[r].isDirty) {
if (mr[ar[r].mipsReg].loc == ML_MEM)
if (ar[r].mipsReg != -1) {
if (ar[r].isDirty && mr[ar[r].mipsReg].loc == ML_ARMREG)
emit->STR(CTXREG, r, 4 * ar[r].mipsReg);
ar[r].isDirty = false;
ar[r].mipsReg = -1;
mr[ar[r].mipsReg].loc = ML_MEM;
} else {
ERROR_LOG(HLE, "Dirty but no mipsreg?");
}
ar[r].isDirty = false;
ar[r].mipsReg = -1;
}
void ArmRegCache::FlushMipsReg(MIPSReg r) {

View File

@ -24,10 +24,10 @@
using namespace ArmGen;
// R2 to R9: mapped MIPS regs
// R2 to R8: mapped MIPS regs
// R9 = code pointers
// R10 = MIPS context
// R11 = base pointer
// R12 = MIPS context
// R14 = code pointers
// Special MIPS registers:
enum {

View File

@ -447,8 +447,6 @@ void Jit::Comp_JumpReg(u32 op)
void Jit::Comp_Syscall(u32 op)
{
// This will most often be called from Comp_JumpReg (jr ra) so we take over the exit sequence...
FlushAll();
ABI_CallFunctionC((void *)(&CallSyscall), op);

View File

@ -55,7 +55,7 @@ u8 *GetPointer(const u32 address)
}
else
{
ERROR_LOG(MEMMAP, "Unknown GetPointer %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);
ERROR_LOG(MEMMAP, "Unknown GetPointer %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);
return 0;
}
}

View File

@ -23,6 +23,7 @@
#include "../Core/Config.h"
#include "../Core/SaveState.h"
#include "EmuThread.h"
#include "ext/disarm.h"
#include "LogManager.h"
#include "ConsoleListener.h"
@ -50,6 +51,9 @@ CMemoryDlg *memoryWindow[MAX_CPUCOUNT];
int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
char temp[256];
ArmDis(0, 0xE12fff10, temp);
Common::EnableCrashingOnCrashes();
const char *fileToStart = NULL;

View File

@ -15,4 +15,4 @@ public class PpssppActivity extends NativeActivity {
{
return false;
}
}
}

View File

@ -951,8 +951,10 @@ void ArmDis(unsigned int addr, unsigned int w, char *output) {
if (instr->undefined || instr->badbits || instr->oddbits) {
if (instr->undefined) sprintf(output, " [undefined instr %08x]", w);
if (instr->badbits) sprintf(output, " [illegal bits %08x]", w);
strcat(output, " ? (extra bits)");
//if (instr->oddbits) sprintf(output, " [unexpected bits %08x]", w);
// HUH? LDR and STR gets this a lot
// strcat(output, " ? (extra bits)");
// if (instr->oddbits) sprintf(output, " [unexpected bits %08x]", w);
}
// zap tabs
while (*output) {