aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ARMJIT_x64/ARMJIT_Compiler.h12
-rw-r--r--src/ARMJIT_x64/ARMJIT_LoadStore.cpp72
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);
}