mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Separate out jit reading nearby instructions.
This makes it easier to use an IR for these things, or remove them.
This commit is contained in:
parent
59d0baca93
commit
a897723e6a
14 changed files with 51 additions and 36 deletions
|
@ -104,7 +104,7 @@ void ArmJit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely)
|
|||
return;
|
||||
}
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC+4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rt, rs);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
|
||||
|
@ -220,7 +220,7 @@ void ArmJit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool like
|
|||
return;
|
||||
}
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
|
||||
|
@ -326,7 +326,7 @@ void ArmJit::BranchFPFlag(MIPSOpcode op, CCFlags cc, bool likely)
|
|||
int offset = _IMM16 << 2;
|
||||
u32 targetAddr = js.compilerPC + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceFPU(op, delaySlotOp);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
if (!likely && delaySlotIsNice)
|
||||
|
@ -384,7 +384,7 @@ void ArmJit::BranchVFPUFlag(MIPSOpcode op, CCFlags cc, bool likely)
|
|||
int offset = _IMM16 << 2;
|
||||
u32 targetAddr = js.compilerPC + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
|
||||
// Sometimes there's a VFPU branch in a delay slot (Disgaea 2: Dark Hero Days, Zettai Hero Project, La Pucelle)
|
||||
// The behavior is undefined - the CPU may take the second branch even if the first one passes.
|
||||
|
@ -511,7 +511,7 @@ void ArmJit::Comp_JumpReg(MIPSOpcode op)
|
|||
MIPSGPReg rd = _RD;
|
||||
bool andLink = (op & 0x3f) == 9 && rd != MIPS_REG_ZERO;
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);
|
||||
if (andLink && rs == rd)
|
||||
delaySlotIsNice = false;
|
||||
|
|
|
@ -63,7 +63,7 @@ void ArmJit::Comp_FPU3op(MIPSOpcode op)
|
|||
case 0: VADD(fpr.R(fd), fpr.R(fs), fpr.R(ft)); break; //F(fd) = F(fs) + F(ft); //add
|
||||
case 1: VSUB(fpr.R(fd), fpr.R(fs), fpr.R(ft)); break; //F(fd) = F(fs) - F(ft); //sub
|
||||
case 2: { //F(fd) = F(fs) * F(ft); //mul
|
||||
MIPSOpcode nextOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode nextOp = GetOffsetInstruction(1);
|
||||
// Optimization possible if destination is the same
|
||||
if (fd == (int)((nextOp>>6) & 0x1F)) {
|
||||
// VMUL + VNEG -> VNMUL
|
||||
|
|
|
@ -139,7 +139,7 @@ namespace MIPSComp
|
|||
if (!js.inDelaySlot) {
|
||||
// Optimisation: Combine to single unaligned load/store
|
||||
bool isLeft = (o == 34 || o == 42);
|
||||
MIPSOpcode nextOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode nextOp = GetOffsetInstruction(1);
|
||||
// Find a matching shift in opposite direction with opposite offset.
|
||||
if (nextOp == (isLeft ? (op.encoding + (4<<26) - 3)
|
||||
: (op.encoding - (4<<26) + 3)))
|
||||
|
|
|
@ -284,9 +284,9 @@ void ArmJit::CompNEON_SVQ(MIPSOpcode op) {
|
|||
// Check for four-in-a-row
|
||||
const u32 ops[4] = {
|
||||
op.encoding,
|
||||
Memory::Read_Instruction(js.compilerPC + 4).encoding,
|
||||
Memory::Read_Instruction(js.compilerPC + 8).encoding,
|
||||
Memory::Read_Instruction(js.compilerPC + 12).encoding
|
||||
GetOffsetInstruction(1).encoding,
|
||||
GetOffsetInstruction(2).encoding,
|
||||
GetOffsetInstruction(3).encoding
|
||||
};
|
||||
if (g_Config.bFastMemory && (ops[1] >> 26) == 54 && (ops[2] >> 26) == 54 && (ops[3] >> 26) == 54) {
|
||||
int offsets[4] = {offset, (s16)(ops[1] & 0xFFFC), (s16)(ops[2] & 0xFFFC), (s16)(ops[3] & 0xFFFC)};
|
||||
|
@ -350,9 +350,9 @@ void ArmJit::CompNEON_SVQ(MIPSOpcode op) {
|
|||
{
|
||||
const u32 ops[4] = {
|
||||
op.encoding,
|
||||
Memory::Read_Instruction(js.compilerPC + 4).encoding,
|
||||
Memory::Read_Instruction(js.compilerPC + 8).encoding,
|
||||
Memory::Read_Instruction(js.compilerPC + 12).encoding
|
||||
GetOffsetInstruction(1).encoding,
|
||||
GetOffsetInstruction(2).encoding,
|
||||
GetOffsetInstruction(3).encoding
|
||||
};
|
||||
if (g_Config.bFastMemory && (ops[1] >> 26) == 54 && (ops[2] >> 26) == 54 && (ops[3] >> 26) == 54) {
|
||||
int offsets[4] = { offset, (s16)(ops[1] & 0xFFFC), (s16)(ops[2] & 0xFFFC), (s16)(ops[3] & 0xFFFC) };
|
||||
|
|
|
@ -235,6 +235,10 @@ void ArmJit::RunLoopUntil(u64 globalticks)
|
|||
((void (*)())enterCode)();
|
||||
}
|
||||
|
||||
MIPSOpcode ArmJit::GetOffsetInstruction(int offset) {
|
||||
return Memory::Read_Instruction(js.compilerPC + 4 * offset);
|
||||
}
|
||||
|
||||
const u8 *ArmJit::DoJit(u32 em_address, JitBlock *b)
|
||||
{
|
||||
js.cancel = false;
|
||||
|
|
|
@ -85,10 +85,6 @@ public:
|
|||
|
||||
bool DescribeCodePtr(const u8 *ptr, std::string &name);
|
||||
|
||||
void CompileDelaySlot(int flags);
|
||||
void EatInstruction(MIPSOpcode op);
|
||||
void AddContinuedBlock(u32 dest);
|
||||
|
||||
void Comp_RunBlock(MIPSOpcode op);
|
||||
void Comp_ReplacementFunc(MIPSOpcode op);
|
||||
|
||||
|
@ -215,6 +211,11 @@ private:
|
|||
void FlushAll();
|
||||
void FlushPrefixV();
|
||||
|
||||
void CompileDelaySlot(int flags);
|
||||
void EatInstruction(MIPSOpcode op);
|
||||
void AddContinuedBlock(u32 dest);
|
||||
MIPSOpcode GetOffsetInstruction(int offset);
|
||||
|
||||
void WriteDownCount(int offset = 0);
|
||||
void WriteDownCountR(ArmGen::ARMReg reg);
|
||||
void RestoreRoundingMode(bool force = false);
|
||||
|
|
|
@ -104,7 +104,7 @@ void Arm64Jit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely)
|
|||
return;
|
||||
}
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC+4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rt, rs);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
|
||||
|
@ -208,7 +208,7 @@ void Arm64Jit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool li
|
|||
return;
|
||||
}
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
|
||||
|
@ -313,7 +313,7 @@ void Arm64Jit::BranchFPFlag(MIPSOpcode op, CCFlags cc, bool likely) {
|
|||
int offset = _IMM16 << 2;
|
||||
u32 targetAddr = js.compilerPC + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceFPU(op, delaySlotOp);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
if (!likely && delaySlotIsNice)
|
||||
|
@ -364,7 +364,7 @@ void Arm64Jit::BranchVFPUFlag(MIPSOpcode op, CCFlags cc, bool likely) {
|
|||
int offset = _IMM16 << 2;
|
||||
u32 targetAddr = js.compilerPC + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
|
||||
// Sometimes there's a VFPU branch in a delay slot (Disgaea 2: Dark Hero Days, Zettai Hero Project, La Pucelle)
|
||||
// The behavior is undefined - the CPU may take the second branch even if the first one passes.
|
||||
|
@ -491,7 +491,7 @@ void Arm64Jit::Comp_JumpReg(MIPSOpcode op)
|
|||
MIPSGPReg rd = _RD;
|
||||
bool andLink = (op & 0x3f) == 9 && rd != MIPS_REG_ZERO;
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);
|
||||
if (andLink && rs == rd)
|
||||
delaySlotIsNice = false;
|
||||
|
|
|
@ -95,7 +95,7 @@ namespace MIPSComp
|
|||
if (!js.inDelaySlot && false) {
|
||||
// Optimisation: Combine to single unaligned load/store
|
||||
bool isLeft = (o == 34 || o == 42);
|
||||
MIPSOpcode nextOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode nextOp = GetOffsetInstruction(1);
|
||||
// Find a matching shift in opposite direction with opposite offset.
|
||||
if (nextOp == (isLeft ? (op.encoding + (4 << 26) - 3)
|
||||
: (op.encoding - (4 << 26) + 3))) {
|
||||
|
|
|
@ -220,6 +220,10 @@ void Arm64Jit::RunLoopUntil(u64 globalticks) {
|
|||
((void (*)())enterCode)();
|
||||
}
|
||||
|
||||
MIPSOpcode Arm64Jit::GetOffsetInstruction(int offset) {
|
||||
return Memory::Read_Instruction(js.compilerPC + 4 * offset);
|
||||
}
|
||||
|
||||
const u8 *Arm64Jit::DoJit(u32 em_address, JitBlock *b) {
|
||||
js.cancel = false;
|
||||
js.blockStart = js.compilerPC = mips_->pc;
|
||||
|
|
|
@ -81,10 +81,6 @@ public:
|
|||
|
||||
bool DescribeCodePtr(const u8 *ptr, std::string &name);
|
||||
|
||||
void CompileDelaySlot(int flags);
|
||||
void EatInstruction(MIPSOpcode op);
|
||||
void AddContinuedBlock(u32 dest);
|
||||
|
||||
void Comp_RunBlock(MIPSOpcode op);
|
||||
void Comp_ReplacementFunc(MIPSOpcode op);
|
||||
|
||||
|
@ -211,6 +207,11 @@ private:
|
|||
void FlushAll();
|
||||
void FlushPrefixV();
|
||||
|
||||
void CompileDelaySlot(int flags);
|
||||
void EatInstruction(MIPSOpcode op);
|
||||
void AddContinuedBlock(u32 dest);
|
||||
MIPSOpcode GetOffsetInstruction(int offset);
|
||||
|
||||
void WriteDownCount(int offset = 0);
|
||||
void WriteDownCountR(Arm64Gen::ARM64Reg reg);
|
||||
void RestoreRoundingMode(bool force = false);
|
||||
|
|
|
@ -364,7 +364,7 @@ void Jit::BranchRSRTComp(MIPSOpcode op, Gen::CCFlags cc, bool likely)
|
|||
return;
|
||||
}
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC+4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rt, rs);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
|
||||
|
@ -443,7 +443,7 @@ void Jit::BranchRSZeroComp(MIPSOpcode op, Gen::CCFlags cc, bool andLink, bool li
|
|||
return;
|
||||
}
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
|
||||
|
@ -514,7 +514,7 @@ void Jit::BranchFPFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely)
|
|||
int offset = _IMM16 << 2;
|
||||
u32 targetAddr = js.compilerPC + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceFPU(op, delaySlotOp);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
if (!likely && delaySlotIsNice)
|
||||
|
@ -552,7 +552,7 @@ void Jit::BranchVFPUFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely)
|
|||
int offset = _IMM16 << 2;
|
||||
u32 targetAddr = js.compilerPC + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
|
||||
// Sometimes there's a VFPU branch in a delay slot (Disgaea 2: Dark Hero Days, Zettai Hero Project, La Pucelle)
|
||||
// The behavior is undefined - the CPU may take the second branch even if the first one passes.
|
||||
|
@ -672,7 +672,7 @@ void Jit::Comp_JumpReg(MIPSOpcode op)
|
|||
MIPSGPReg rd = _RD;
|
||||
bool andLink = (op & 0x3f) == 9 && rd != MIPS_REG_ZERO;
|
||||
|
||||
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);
|
||||
if (andLink && rs == rd)
|
||||
delaySlotIsNice = false;
|
||||
|
|
|
@ -329,7 +329,7 @@ namespace MIPSComp {
|
|||
|
||||
case 34: //lwl
|
||||
{
|
||||
MIPSOpcode nextOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode nextOp = GetOffsetInstruction(1);
|
||||
// Looking for lwr rd, offset-3(rs) which makes a pair.
|
||||
u32 desiredOp = ((op & 0xFFFF0000) + (4 << 26)) + (offset - 3);
|
||||
if (!js.inDelaySlot && nextOp == desiredOp)
|
||||
|
@ -345,7 +345,7 @@ namespace MIPSComp {
|
|||
|
||||
case 38: //lwr
|
||||
{
|
||||
MIPSOpcode nextOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode nextOp = GetOffsetInstruction(1);
|
||||
// Looking for lwl rd, offset+3(rs) which makes a pair.
|
||||
u32 desiredOp = ((op & 0xFFFF0000) - (4 << 26)) + (offset + 3);
|
||||
if (!js.inDelaySlot && nextOp == desiredOp)
|
||||
|
@ -361,7 +361,7 @@ namespace MIPSComp {
|
|||
|
||||
case 42: //swl
|
||||
{
|
||||
MIPSOpcode nextOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode nextOp = GetOffsetInstruction(1);
|
||||
// Looking for swr rd, offset-3(rs) which makes a pair.
|
||||
u32 desiredOp = ((op & 0xFFFF0000) + (4 << 26)) + (offset - 3);
|
||||
if (!js.inDelaySlot && nextOp == desiredOp)
|
||||
|
@ -377,7 +377,7 @@ namespace MIPSComp {
|
|||
|
||||
case 46: //swr
|
||||
{
|
||||
MIPSOpcode nextOp = Memory::Read_Instruction(js.compilerPC + 4);
|
||||
MIPSOpcode nextOp = GetOffsetInstruction(1);
|
||||
// Looking for swl rd, offset+3(rs) which makes a pair.
|
||||
u32 desiredOp = ((op & 0xFFFF0000) - (4 << 26)) + (offset + 3);
|
||||
if (!js.inDelaySlot && nextOp == desiredOp)
|
||||
|
|
|
@ -402,6 +402,10 @@ void Jit::RunLoopUntil(u64 globalticks)
|
|||
((void (*)())asm_.enterCode)();
|
||||
}
|
||||
|
||||
MIPSOpcode Jit::GetOffsetInstruction(int offset) {
|
||||
return Memory::Read_Instruction(js.compilerPC + 4 * offset);
|
||||
}
|
||||
|
||||
const u8 *Jit::DoJit(u32 em_address, JitBlock *b)
|
||||
{
|
||||
js.cancel = false;
|
||||
|
|
|
@ -199,6 +199,7 @@ private:
|
|||
}
|
||||
void EatInstruction(MIPSOpcode op);
|
||||
void AddContinuedBlock(u32 dest);
|
||||
MIPSOpcode GetOffsetInstruction(int offset);
|
||||
|
||||
void WriteExit(u32 destination, int exit_num);
|
||||
void WriteExitDestInReg(Gen::X64Reg reg);
|
||||
|
|
Loading…
Add table
Reference in a new issue