Enough to run cpu_alu.prx.

This commit is contained in:
Henrik Rydgard
2016-05-07 21:00:30 +02:00
parent 4acf85aa06
commit 12edfcea5a
9 changed files with 137 additions and 38 deletions
+53 -3
View File
@@ -153,7 +153,7 @@ void IRJit::CompType3(MIPSGPReg rd, MIPSGPReg rs, MIPSGPReg rt, IROp op, IROp co
}
return;
}
/*
if (gpr.IsImm(rt) || (gpr.IsImm(rs) && symmetric)) {
MIPSGPReg lhs = gpr.IsImm(rs) ? rt : rs;
MIPSGPReg rhs = gpr.IsImm(rs) ? rs : rt;
@@ -167,7 +167,7 @@ void IRJit::CompType3(MIPSGPReg rd, MIPSGPReg rs, MIPSGPReg rt, IROp op, IROp co
gpr.SetImm(rhs, rhsImm);
}
return;
}
}*/
// Can't do the RSB optimization on ARM64 - no RSB!
@@ -343,7 +343,57 @@ void IRJit::Comp_ShiftType(MIPSOpcode op) {
}
void IRJit::Comp_Special3(MIPSOpcode op) {
DISABLE;
CONDITIONAL_DISABLE;
MIPSGPReg rs = _RS;
MIPSGPReg rt = _RT;
int pos = _POS;
int size = _SIZE + 1;
u32 mask = 0xFFFFFFFFUL >> (32 - size);
// Don't change $zr.
if (rt == 0)
return;
switch (op & 0x3f) {
case 0x0: //ext
if (gpr.IsImm(rs)) {
gpr.SetImm(rt, (gpr.GetImm(rs) >> pos) & mask);
return;
}
gpr.MapDirtyIn(rt, rs);
ir.Write(IROp::Shl, rt, rs);
ir.Write(IROp::AndConst, rt, rt, ir.AddConstant(mask));
break;
case 0x4: //ins
{
u32 sourcemask = mask >> pos;
u32 destmask = ~(sourcemask << pos);
if (gpr.IsImm(rs)) {
u32 inserted = (gpr.GetImm(rs) & sourcemask) << pos;
if (gpr.IsImm(rt)) {
gpr.SetImm(rt, (gpr.GetImm(rt) & destmask) | inserted);
return;
}
gpr.MapDirty(rt);
ir.Write(IROp::AndConst, rt, rt, ir.AddConstant(destmask));
if (inserted != 0) {
ir.Write(IROp::OrConst, rt, rt, inserted);
}
} else {
gpr.MapDirtyIn(rt, rs);
ir.Write(IROp::AndConst, IRTEMP_0, rs, ir.AddConstant(sourcemask));
ir.Write(IROp::AndConst, rt, rt, ir.AddConstant(destmask));
ir.Write(IROp::ShlImm, IRTEMP_0, IRTEMP_0, pos);
ir.Write(IROp::Or, rt, rt, IRTEMP_0);
}
}
break;
}
}
void IRJit::Comp_Allegrex(MIPSOpcode op) {
+13 -9
View File
@@ -72,12 +72,14 @@ void IRJit::BranchRSRTComp(MIPSOpcode op, IRComparison cc, bool likely)
MIPSGPReg lhs = rs;
MIPSGPReg rhs = rt;
if (!delaySlotIsNice && !likely) { // if likely, we don't need this
if (!delaySlotIsNice) { // if likely, we don't need this
if (rs != 0) {
gpr.MapIn(rs);
ir.Write(IROp::Mov, IRTEMP_0, rs);
lhs = (MIPSGPReg)IRTEMP_0;
}
if (rt != 0) {
gpr.MapIn(rt);
ir.Write(IROp::Mov, IRTEMP_1, rt);
rhs = (MIPSGPReg)IRTEMP_1;
}
@@ -113,21 +115,22 @@ void IRJit::BranchRSZeroComp(MIPSOpcode op, IRComparison cc, bool andLink, bool
ir.Write(IROp::Downcount, 0, js.downcountAmount & 0xFF, js.downcountAmount >> 8);
if (!likely && delaySlotIsNice)
CompileDelaySlot();
int lhs = rs;
gpr.MapIn(rs);
if (!delaySlotIsNice && !likely) { // if likely, we don't need this
MIPSGPReg lhs = rs;
if (!delaySlotIsNice) { // if likely, we don't need this
ir.Write(IROp::Mov, IRTEMP_0, rs);
lhs = IRTEMP_0;
lhs = (MIPSGPReg)IRTEMP_0;
}
if (andLink)
gpr.SetImm(MIPS_REG_RA, GetCompilerPC() + 8);
if (!likely)
CompileDelaySlot();
gpr.MapIn(lhs);
FlushAll();
ir.Write(ComparisonToExit(cc), ir.AddConstant(GetCompilerPC() + 8), lhs);
if (likely) {
if (likely)
CompileDelaySlot();
}
// Taken
FlushAll();
ir.Write(IROp::ExitToConst, ir.AddConstant(targetAddr));
@@ -327,6 +330,7 @@ void IRJit::Comp_JumpReg(MIPSOpcode op) {
if (andLink)
gpr.SetImm(rd, GetCompilerPC() + 8);
CompileDelaySlot();
// Syscall (the delay slot) does FlushAll.
return; // Syscall (delay slot) wrote exit code.
} else if (delaySlotIsNice) {
if (andLink)
+16 -3
View File
@@ -170,13 +170,13 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, const u32 *constPool, int c
break;
case IROp::ShlImm:
mips->r[inst->dest] = mips->r[inst->src1] << inst->src2;
mips->r[inst->dest] = mips->r[inst->src1] << (int)inst->src2;
break;
case IROp::ShrImm:
mips->r[inst->dest] = mips->r[inst->src1] >> inst->src2;
mips->r[inst->dest] = mips->r[inst->src1] >> (int)inst->src2;
break;
case IROp::SarImm:
mips->r[inst->dest] = (s32)mips->r[inst->src1] >> inst->src2;
mips->r[inst->dest] = (s32)mips->r[inst->src1] >> (int)inst->src2;
break;
case IROp::RorImm:
{
@@ -203,6 +203,19 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, const u32 *constPool, int c
}
break;
case IROp::Clz:
{
int x = 31;
int count = 0;
int value = mips->r[inst->src1];
while (x >= 0 && !(value & (1 << x))) {
count++;
x--;
}
mips->r[inst->dest] = count;
break;
}
case IROp::Slt:
mips->r[inst->dest] = (s32)mips->r[inst->src1] < (s32)mips->r[inst->src2];
break;
+20 -6
View File
@@ -48,7 +48,7 @@ IRJit::IRJit(MIPSState *mips) : gpr(), mips_(mips) {
js.currentRoundingFunc = convertS0ToSCRATCH1[0];
u32 size = 128 * 1024;
blTrampolines_ = kernelMemory.Alloc(size, true, "trampoline");
logBlocks = 100;
logBlocks = 0;
InitIR();
}
@@ -184,6 +184,12 @@ void IRJit::RunLoopUntil(u64 globalticks) {
// ApplyRoundingMode(true);
// IR Dispatcher
FILE *f;
int numBlocks = 0;
if (numBlocks) {
f = fopen("E:\\blockir.txt", "w");
}
while (true) {
// RestoreRoundingMode(true);
CoreTiming::Advance();
@@ -197,11 +203,18 @@ void IRJit::RunLoopUntil(u64 globalticks) {
u32 data = inst & 0xFFFFFF;
if (opcode == (MIPS_EMUHACK_OPCODE >> 24)) {
IRBlock *block = blocks_.GetBlock(data);
ILOG("Run block at %08x : v1=%08x a0=%08x", mips_->pc, mips_->r[MIPS_REG_V1], mips_->r[MIPS_REG_A0]);
if (numBlocks > 0) {
// ILOG("Run block at %08x : v1=%08x a0=%08x", mips_->pc, mips_->r[MIPS_REG_V1], mips_->r[MIPS_REG_A0]);
fprintf(f, "BLOCK : %08x v0: %08x v1: %08x a0: %08x s0: %08x s4: %08x\n", mips_->pc, mips_->r[MIPS_REG_V0], mips_->r[MIPS_REG_V1], mips_->r[MIPS_REG_A0], mips_->r[MIPS_REG_S0], mips_->r[MIPS_REG_S4]);
fflush(f);
numBlocks--;
}
mips_->pc = IRInterpret(mips_, block->GetInstructions(), block->GetConstants(), block->GetNumInstructions());
} else {
if (mips_->pc == 0x0880de94)
logBlocks = 10;
// RestoreRoundingMode(true);
ILOG("Compile block at %08x : v1=%08x a0=%08x", mips_->pc, mips_->r[MIPS_REG_V1], mips_->r[MIPS_REG_A0]);
// ILOG("Compile block at %08x : v1=%08x a0=%08x", mips_->pc, mips_->r[MIPS_REG_V1], mips_->r[MIPS_REG_A0]);
Compile(mips_->pc);
// ApplyRoundingMode(true);
}
@@ -252,7 +265,7 @@ void IRJit::DoJit(u32 em_address, IRBlock *b) {
if (logBlocks > 0 && dontLogBlocks == 0) {
char temp2[256];
ILOG("=============== mips %d ===============", blocks_.GetNumBlocks());
ILOG("=============== mips %d %08x ===============", blocks_.GetNumBlocks(), em_address);
for (u32 cpc = em_address; cpc != GetCompilerPC() + 4; cpc += 4) {
temp2[0] = 0;
MIPSDisAsm(Memory::Read_Opcode_JIT(cpc), cpc, temp2, true);
@@ -304,7 +317,8 @@ void IRJit::Comp_ReplacementFunc(MIPSOpcode op) {
}
void IRJit::Comp_Generic(MIPSOpcode op) {
ir.Write(IROp::Interpret, ir.AddConstant(op.encoding));
FlushAll();
ir.Write(IROp::Interpret, 0, ir.AddConstant(op.encoding));
const MIPSInfo info = MIPSGetInfo(op);
if ((info & IS_VFPU) != 0 && (info & VFPU_NO_PREFIX) == 0) {
// If it does eat them, it'll happen in MIPSCompileOp().
@@ -351,7 +365,7 @@ void IRBlockCache::InvalidateICache(u32 addess, u32 length) {
}
void IRBlock::Finalize(int number) {
origFirstOpcode_= Memory::Read_Opcode_JIT(origAddr_);
origFirstOpcode_ = Memory::Read_Opcode_JIT(origAddr_);
MIPSOpcode opcode = MIPSOpcode(MIPS_EMUHACK_OPCODE | number);
Memory::Write_Opcode_JIT(origAddr_, opcode);
}
+6 -1
View File
@@ -42,6 +42,7 @@ public:
numInstructions_ = b.numInstructions_;
numConstants_ = b.numConstants_;
origAddr_ = b.origAddr_;
origFirstOpcode_ = b.origFirstOpcode_;
b.instr_ = nullptr;
b.const_ = nullptr;
}
@@ -86,7 +87,11 @@ public:
return (int)blocks_.size() - 1;
}
IRBlock *GetBlock(int i) {
return &blocks_[i];
if (i >= 0 && i < blocks_.size()) {
return &blocks_[i];
} else {
return nullptr;
}
}
private:
std::vector<IRBlock> blocks_;
+13 -13
View File
@@ -47,21 +47,21 @@ namespace MIPSComp {
}
JitInterface *CreateNativeJit(MIPSState *mips) {
if (false && g_Config.iCpuCore == (int)CPUCore::CPU_JIT) {
#if defined(ARM)
return new MIPSComp::ArmJit(mips);
#elif defined(ARM64)
return new MIPSComp::IRJit(mips);
#elif defined(_M_IX86) || defined(_M_X64)
return new MIPSComp::Jit(mips);
#elif defined(MIPS)
return new MIPSComp::MipsJit(mips);
#if 1
return new MIPSComp::IRJit(mips);
#else
return new MIPSComp::FakeJit(mips);
#if defined(ARM)
return new MIPSComp::ArmJit(mips);
#elif defined(ARM64)
return new MIPSComp::IRJit(mips);
#elif defined(_M_IX86) || defined(_M_X64)
return new MIPSComp::Jit(mips);
#elif defined(MIPS)
return new MIPSComp::MipsJit(mips);
#else
return new MIPSComp::FakeJit(mips);
#endif
#endif
} else if (true || g_Config.iCpuCore == (int)CPUCore::CPU_IRJIT) {
return new MIPSComp::IRJit(mips);
}
}
}
+14
View File
@@ -28,6 +28,7 @@
#include "Core/CoreTiming.h"
#include "Core/Reporting.h"
#include "Core/Debugger/Breakpoints.h"
#include "base/logging.h"
#include "JitCommon/JitCommon.h"
@@ -973,10 +974,13 @@ void MIPSInterpret(MIPSOpcode op) {
int MIPSInterpret_RunUntil(u64 globalTicks)
{
int blockCount = 150000;
FILE *f = fopen("E:\\blockjit.txt", "w");
MIPSState *curMips = currentMIPS;
while (coreState == CORE_RUNNING)
{
CoreTiming::Advance();
u32 lastPC = 0;
// NEVER stop in a delay slot!
while (curMips->downcount >= 0 && coreState == CORE_RUNNING)
@@ -1015,6 +1019,16 @@ int MIPSInterpret_RunUntil(u64 globalTicks)
bool wasInDelaySlot = curMips->inDelaySlot;
if (curMips->pc != lastPC + 4) {
if (blockCount > 0) {
MIPSState *mips_ = curMips;
fprintf(f, "BLOCK : %08x v0: %08x v1: %08x a0: %08x s0: %08x s4: %08x\n", mips_->pc, mips_->r[MIPS_REG_V0], mips_->r[MIPS_REG_V1], mips_->r[MIPS_REG_A0], mips_->r[MIPS_REG_S0], mips_->r[MIPS_REG_S4]);
fflush(f);
blockCount--;
}
}
lastPC = curMips->pc;
MIPSInterpret(op);
if (curMips->inDelaySlot)
+1 -1
View File
@@ -40,7 +40,7 @@ namespace MIPSComp
//TODO - make an option
//#if _DEBUG
static bool enableDebug = false;
static bool enableDebug = true;
//#else
// bool enableDebug = false;
+1 -2
View File
@@ -81,8 +81,7 @@ u32 JitBreakpoint()
host->SetDebugMode(true);
// There's probably a better place for this.
if (USE_JIT_MISSMAP)
{
if (USE_JIT_MISSMAP) {
std::map<u32, std::string> notJitSorted;
std::transform(notJitOps.begin(), notJitOps.end(), std::inserter(notJitSorted, notJitSorted.begin()), flip_pair<std::string, u32>);