From 41bf19244d593071193371933ee769d9ed3b3bb5 Mon Sep 17 00:00:00 2001 From: Ced2911 Date: Tue, 13 Aug 2013 17:37:18 +0200 Subject: [PATCH] use rlwinm instead of and, started jitted memory instructions --- Core/MIPS/PPC/PpcAsm.cpp | 11 +- Core/MIPS/PPC/PpcCompLoadStore.cpp | 176 ++++++++++++++++++++++++++++- Core/MIPS/PPC/PpcJit.h | 2 + 3 files changed, 179 insertions(+), 10 deletions(-) diff --git a/Core/MIPS/PPC/PpcAsm.cpp b/Core/MIPS/PPC/PpcAsm.cpp index 3acf74af50..f32ff874b9 100644 --- a/Core/MIPS/PPC/PpcAsm.cpp +++ b/Core/MIPS/PPC/PpcAsm.cpp @@ -220,20 +220,19 @@ void Jit::GenerateFixedCode() { // read op // R3 = mips->pc & Memory::MEMVIEW32_MASK LWZ(R3, CTXREG, offsetof(MIPSState, pc)); - MOVI2R(SREG, Memory::MEMVIEW32_MASK); - AND(R3, R3, SREG); + // & Memory::MEMVIEW32_MASK + RLWINM(R3, R3, 0, 2, 31); // R3 = memory::base[r3]; ADD(R3, BASEREG, R3); MOVI2R(R0, 0); - LWBRX(R3, R3, R0); // R3 = op now ! + LWBRX(R3, R3, R0); // R4 = R3 & MIPS_EMUHACK_VALUE_MASK - MOVI2R(SREG, MIPS_EMUHACK_VALUE_MASK); - AND(R4, R3, SREG); + RLWINM(R4, R3, 0, 6, 31); // R3 = R3 & MIPS_EMUHACK_MASK - ANDIS(R3, R3, (MIPS_EMUHACK_MASK>>16)); + RLWINM(R3, R3, 0, 0, 6); // compare, op == MIPS_EMUHACK_OPCODE MOVI2R(SREG, MIPS_EMUHACK_OPCODE); diff --git a/Core/MIPS/PPC/PpcCompLoadStore.cpp b/Core/MIPS/PPC/PpcCompLoadStore.cpp index e213c3078f..36001d17b5 100644 --- a/Core/MIPS/PPC/PpcCompLoadStore.cpp +++ b/Core/MIPS/PPC/PpcCompLoadStore.cpp @@ -10,15 +10,183 @@ #include "ppcEmitter.h" #include "PpcJit.h" -#include + +#define _RS ((op>>21) & 0x1F) +#define _RT ((op>>16) & 0x1F) +#define _RD ((op>>11) & 0x1F) +#define _FS ((op>>11) & 0x1F) +#define _FT ((op>>16) & 0x1F) +#define _FD ((op>>6 ) & 0x1F) +#define _POS ((op>>6 ) & 0x1F) +#define _SIZE ((op>>11 ) & 0x1F) + +// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly. +// Currently known non working ones should have DISABLE. + +#define CONDITIONAL_DISABLE { Comp_Generic(op); return; } +//#define CONDITIONAL_DISABLE ; +#define DISABLE { Comp_Generic(op); return; } using namespace PpcGen; namespace MIPSComp { -void Jit::Comp_ITypeMem(u32 op) { - Comp_Generic(op); +void Jit::SetRegToEffectiveAddress(PpcGen::PPCReg r, int rs, s16 offset) { + if (offset == 0xa24) { + printf("Rs : %02x\n", rs); + Break(); + } + /* + if (offset) { + bool negated; + if (TryMakeOperand2_AllowNegation(offset, op2, &negated)) { + if (!negated) + ADD(R0, gpr.R(rs), op2); + else + SUB(R0, gpr.R(rs), op2); + } else { + // Try to avoid using MOVT + if (offset < 0) { + MOVI2R(R0, (u32)(-offset)); + SUB(R0, gpr.R(rs), R0); + } else { + MOVI2R(R0, (u32)offset); + ADD(R0, gpr.R(rs), R0); + } + } + BIC(R0, R0, Operand2(0xC0, 4)); // &= 0x3FFFFFFF + } else { + BIC(R0, gpr.R(rs), Operand2(0xC0, 4)); // &= 0x3FFFFFFF + } + */ + if (offset) { + // optimize ... + + //MOVI2R(SREG, (u32)offset); + //ADD(SREG, gpr.R(rs), SREG); + ADDI(SREG, gpr.R(rs), offset); + + //Break(); + RLWINM(SREG, SREG, 0, 2, 31); // &= 0x3FFFFFFF + } else { + RLWINM(SREG, gpr.R(rs), 0, 2, 31); // &= 0x3FFFFFFF + } + } -} \ No newline at end of file +void Jit::Comp_ITypeMem(u32 op) { + CONDITIONAL_DISABLE; + int offset = (signed short)(op&0xFFFF); + bool load = false; + int rt = _RT; + int rs = _RS; + int o = op>>26; + if (((op >> 29) & 1) == 0 && rt == 0) { + // Don't load anything into $zr + return; + } + + u32 iaddr = gpr.IsImm(rs) ? offset + gpr.GetImm(rs) : 0xFFFFFFFF; + bool doCheck = false; + + switch (o) + { + case 32: //lb + case 33: //lh + case 35: //lw + case 36: //lbu + case 37: //lhu + load = true; + case 40: //sb + case 41: //sh + case 43: //sw + if (gpr.IsImm(rs) && Memory::IsValidAddress(iaddr)) { + // We can compute the full address at compile time. Kickass. + u32 addr = iaddr & 0x3FFFFFFF; + // Must be OK even if rs == rt since we have the value from imm already. + gpr.MapReg(rt, load ? MAP_NOINIT | MAP_DIRTY : 0); + MOVI2R(SREG, addr); + } else { + _dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address? CPU bug?"); + load ? gpr.MapDirtyIn(rt, rs) : gpr.MapInIn(rt, rs); + + SetRegToEffectiveAddress(SREG, rs, offset); + //DISABLE; + } + switch (o) + { + // Load + case 32: //lb + Break(); + + LBZ(gpr.R(rt), BASEREG, SREG); + EXTSB(gpr.R(rt), gpr.R(rt)); + + break; + case 33: //lh + LHBRX(gpr.R(rt), BASEREG, SREG); + EXTSH(gpr.R(rt), gpr.R(rt)); + break; + case 35: //lw + LWBRX(gpr.R(rt), BASEREG, SREG); + break; + case 36: //lbu + LBZ (gpr.R(rt), BASEREG, SREG); + break; + case 37: //lhu + LHBRX (gpr.R(rt), BASEREG, SREG); + break; + // Store + case 40: //sb + Break(); + STB (gpr.R(rt), BASEREG, SREG); + break; + case 41: //sh + STHBRX(gpr.R(rt), BASEREG, SREG); + break; + case 43: //sw + STWBRX(gpr.R(rt), BASEREG, SREG); + break; + } + /* + if (doCheck) { + if (load) { + SetCC(CC_EQ); + MOVI2R(gpr.R(rt), 0); + } + SetCC(CC_AL); + } + */ + break; + /* + case 34: //lwl + case 38: //lwr + load = true; + case 42: //swl + case 46: //swr + if (!js.inDelaySlot) { + // Optimisation: Combine to single unaligned load/store + bool isLeft = (o == 34 || o == 42); + u32 nextOp = Memory::Read_Instruction(js.compilerPC + 4); + // Find a matching shift in opposite direction with opposite offset. + if (nextOp == (isLeft ? (op + (4<<26) - 3) + : (op - (4<<26) + 3))) + { + EatInstruction(nextOp); + nextOp = ((load ? 35 : 43) << 26) | ((isLeft ? nextOp : op) & 0x3FFFFFF); //lw, sw + Comp_ITypeMem(nextOp); + return; + } + } + + DISABLE; // Disabled until crashes are resolved. + break; + */ + default: + Comp_Generic(op); + return ; + } + + } +} diff --git a/Core/MIPS/PPC/PpcJit.h b/Core/MIPS/PPC/PpcJit.h index 51e079d8df..12b5bd0711 100644 --- a/Core/MIPS/PPC/PpcJit.h +++ b/Core/MIPS/PPC/PpcJit.h @@ -220,6 +220,8 @@ namespace MIPSComp void BranchVFPUFlag(u32 op, PpcGen::FixupBranchType cc, bool likely); void BranchRSZeroComp(u32 op, PpcGen::FixupBranchType cc, bool andLink, bool likely); void BranchRSRTComp(u32 op, PpcGen::FixupBranchType cc, bool likely); + + void SetRegToEffectiveAddress(PpcGen::PPCReg r, int rs, s16 offset); // flush regs void FlushAll();