mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-11 07:03:33 +02:00
Enough to run cpu_alu.prx.
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace MIPSComp
|
||||
|
||||
//TODO - make an option
|
||||
//#if _DEBUG
|
||||
static bool enableDebug = false;
|
||||
static bool enableDebug = true;
|
||||
|
||||
//#else
|
||||
// bool enableDebug = false;
|
||||
|
||||
@@ -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>);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user