diff options
-rw-r--r-- | src/ARMJIT_x64/ARMJIT_Compiler.h | 12 | ||||
-rw-r--r-- | src/ARMJIT_x64/ARMJIT_LoadStore.cpp | 72 |
2 files changed, 54 insertions, 30 deletions
diff --git a/src/ARMJIT_x64/ARMJIT_Compiler.h b/src/ARMJIT_x64/ARMJIT_Compiler.h index 09ac257..d1a6c07 100644 --- a/src/ARMJIT_x64/ARMJIT_Compiler.h +++ b/src/ARMJIT_x64/ARMJIT_Compiler.h @@ -18,15 +18,15 @@ const Gen::X64Reg RSCRATCH2 = Gen::EDX; const Gen::X64Reg RSCRATCH3 = Gen::ECX; const Gen::X64Reg RSCRATCH4 = Gen::R8; -struct ComplexOperand +struct Op2 { - ComplexOperand() + Op2() {} - ComplexOperand(u32 imm) + Op2(u32 imm) : IsImm(true), Imm(imm) {} - ComplexOperand(int reg, int op, int amount) + Op2(int reg, int op, int amount) : IsImm(false) { Reg.Reg = reg; @@ -135,9 +135,9 @@ public: memop_Store = 1 << 3, memop_SubtractOffset = 1 << 4 }; - void Comp_MemAccess(int rd, int rn, const ComplexOperand& op2, int size, int flags); + void Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flags); s32 Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc, bool decrement, bool usermode); - bool Comp_MemLoadLiteral(int size, int rd, u32 addr); + bool Comp_MemLoadLiteral(int size, bool signExtend, int rd, u32 addr); void Comp_ArithTriOp(void (Compiler::*op)(int, const Gen::OpArg&, const Gen::OpArg&), Gen::OpArg rd, Gen::OpArg rn, Gen::OpArg op2, bool carryUsed, int opFlags); diff --git a/src/ARMJIT_x64/ARMJIT_LoadStore.cpp b/src/ARMJIT_x64/ARMJIT_LoadStore.cpp index 0bf2f83..b780c55 100644 --- a/src/ARMJIT_x64/ARMJIT_LoadStore.cpp +++ b/src/ARMJIT_x64/ARMJIT_LoadStore.cpp @@ -30,17 +30,18 @@ s32 Compiler::RewriteMemAccess(u64 pc) improvement. */ -bool Compiler::Comp_MemLoadLiteral(int size, int rd, u32 addr) +bool Compiler::Comp_MemLoadLiteral(int size, bool signExtend, int rd, u32 addr) { - return false; - //u32 translatedAddr = Num == 0 ? TranslateAddr9(addr) : TranslateAddr7(addr); + u32 localAddr = LocaliseCodeAddress(Num, addr); - /*int invalidLiteralIdx = InvalidLiterals.Find(translatedAddr); + int invalidLiteralIdx = InvalidLiterals.Find(localAddr); if (invalidLiteralIdx != -1) { InvalidLiterals.Remove(invalidLiteralIdx); return false; - }*/ + } + + Comp_AddCycles_CDI(); u32 val; // make sure arm7 bios is accessible @@ -52,23 +53,29 @@ bool Compiler::Comp_MemLoadLiteral(int size, int rd, u32 addr) val = ROR(val, (addr & 0x3) << 3); } else if (size == 16) + { CurCPU->DataRead16(addr & ~0x1, &val); + if (signExtend) + val = ((s32)val << 16) >> 16; + } else + { CurCPU->DataRead8(addr, &val); + if (signExtend) + val = ((s32)val << 24) >> 24; + } CurCPU->R[15] = tmpR15; MOV(32, MapReg(rd), Imm32(val)); if (Thumb || CurInstr.Cond() == 0xE) RegCache.PutLiteral(rd, val); - - Comp_AddCycles_CDI(); - + return true; } -void Compiler::Comp_MemAccess(int rd, int rn, const ComplexOperand& op2, int size, int flags) +void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flags) { u32 addressMask = ~0; if (size == 32) @@ -76,11 +83,11 @@ void Compiler::Comp_MemAccess(int rd, int rn, const ComplexOperand& op2, int siz if (size == 16) addressMask = ~1; - if (Config::JIT_LiteralOptimisations && rn == 15 && rd != 15 && op2.IsImm && !(flags & (memop_SignExtend|memop_Post|memop_Store|memop_Writeback))) + if (Config::JIT_LiteralOptimisations && rn == 15 && rd != 15 && op2.IsImm && !(flags & (memop_Post|memop_Store|memop_Writeback))) { u32 addr = R15 + op2.Imm * ((flags & memop_SubtractOffset) ? -1 : 1); - if (Comp_MemLoadLiteral(size, rd, addr)) + if (Comp_MemLoadLiteral(size, flags & memop_SignExtend, rd, addr)) return; } @@ -455,6 +462,23 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc { int regsCount = regs.Count(); + if (regsCount == 0) + return 0; // actually not the right behaviour TODO: fix me + + if (regsCount == 1 && !usermode && RegCache.LoadedRegs & (1 << *regs.begin())) + { + int flags = 0; + if (store) + flags |= memop_Store; + if (decrement) + flags |= memop_SubtractOffset; + Op2 offset = preinc ? Op2(4) : Op2(0); + + Comp_MemAccess(*regs.begin(), rn, offset, 32, flags); + + return decrement ? -4 : 4; + } + s32 offset = (regsCount * 4) * (decrement ? -1 : 1); // we need to make sure that the stack stays aligned to 16 bytes @@ -743,10 +767,10 @@ void Compiler::A_Comp_MemWB() if (!(CurInstr.Instr & (1 << 23))) flags |= memop_SubtractOffset; - ComplexOperand offset; + Op2 offset; if (!(CurInstr.Instr & (1 << 25))) { - offset = ComplexOperand(CurInstr.Instr & 0xFFF); + offset = Op2(CurInstr.Instr & 0xFFF); } else { @@ -754,7 +778,7 @@ void Compiler::A_Comp_MemWB() int amount = (CurInstr.Instr >> 7) & 0x1F; int rm = CurInstr.A_Reg(0); - offset = ComplexOperand(rm, op, amount); + offset = Op2(rm, op, amount); } Comp_MemAccess(CurInstr.A_Reg(12), CurInstr.A_Reg(16), offset, size, flags); @@ -762,9 +786,9 @@ void Compiler::A_Comp_MemWB() void Compiler::A_Comp_MemHalf() { - ComplexOperand offset = CurInstr.Instr & (1 << 22) - ? ComplexOperand(CurInstr.Instr & 0xF | ((CurInstr.Instr >> 4) & 0xF0)) - : ComplexOperand(CurInstr.A_Reg(0), 0, 0); + Op2 offset = CurInstr.Instr & (1 << 22) + ? Op2(CurInstr.Instr & 0xF | ((CurInstr.Instr >> 4) & 0xF0)) + : Op2(CurInstr.A_Reg(0), 0, 0); int op = (CurInstr.Instr >> 5) & 0x3; bool load = CurInstr.Instr & (1 << 20); @@ -806,7 +830,7 @@ void Compiler::T_Comp_MemReg() bool load = op & 0x2; bool byte = op & 0x1; - Comp_MemAccess(CurInstr.T_Reg(0), CurInstr.T_Reg(3), ComplexOperand(CurInstr.T_Reg(6), 0, 0), + Comp_MemAccess(CurInstr.T_Reg(0), CurInstr.T_Reg(3), Op2(CurInstr.T_Reg(6), 0, 0), byte ? 8 : 32, load ? 0 : memop_Store); } @@ -839,7 +863,7 @@ void Compiler::T_Comp_MemImm() bool byte = op & 0x2; u32 offset = ((CurInstr.Instr >> 6) & 0x1F) * (byte ? 1 : 4); - Comp_MemAccess(CurInstr.T_Reg(0), CurInstr.T_Reg(3), ComplexOperand(offset), + Comp_MemAccess(CurInstr.T_Reg(0), CurInstr.T_Reg(3), Op2(offset), byte ? 8 : 32, load ? 0 : memop_Store); } @@ -856,7 +880,7 @@ void Compiler::T_Comp_MemRegHalf() if (!load) flags |= memop_Store; - Comp_MemAccess(CurInstr.T_Reg(0), CurInstr.T_Reg(3), ComplexOperand(CurInstr.T_Reg(6), 0, 0), + Comp_MemAccess(CurInstr.T_Reg(0), CurInstr.T_Reg(3), Op2(CurInstr.T_Reg(6), 0, 0), size, flags); } @@ -865,7 +889,7 @@ void Compiler::T_Comp_MemImmHalf() u32 offset = (CurInstr.Instr >> 5) & 0x3E; bool load = CurInstr.Instr & (1 << 11); - Comp_MemAccess(CurInstr.T_Reg(0), CurInstr.T_Reg(3), ComplexOperand(offset), 16, + Comp_MemAccess(CurInstr.T_Reg(0), CurInstr.T_Reg(3), Op2(offset), 16, load ? 0 : memop_Store); } @@ -873,8 +897,8 @@ void Compiler::T_Comp_LoadPCRel() { u32 offset = (CurInstr.Instr & 0xFF) << 2; u32 addr = (R15 & ~0x2) + offset; - if (!Config::JIT_LiteralOptimisations || !Comp_MemLoadLiteral(32, CurInstr.T_Reg(8), addr)) - Comp_MemAccess(CurInstr.T_Reg(8), 15, ComplexOperand(offset), 32, 0); + if (!Config::JIT_LiteralOptimisations || !Comp_MemLoadLiteral(32, false, CurInstr.T_Reg(8), addr)) + Comp_MemAccess(CurInstr.T_Reg(8), 15, Op2(offset), 32, 0); } void Compiler::T_Comp_MemSPRel() @@ -882,7 +906,7 @@ void Compiler::T_Comp_MemSPRel() u32 offset = (CurInstr.Instr & 0xFF) * 4; bool load = CurInstr.Instr & (1 << 11); - Comp_MemAccess(CurInstr.T_Reg(8), 13, ComplexOperand(offset), 32, + Comp_MemAccess(CurInstr.T_Reg(8), 13, Op2(offset), 32, load ? 0 : memop_Store); } |