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:
Henrik Rydgård 2015-04-11 00:52:42 -07:00 committed by Unknown W. Brackets
parent 59d0baca93
commit a897723e6a
14 changed files with 51 additions and 36 deletions

View file

@ -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;

View file

@ -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

View file

@ -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)))

View file

@ -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) };

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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))) {

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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);