Merge pull request #2527 from Sonicadvance1/aarch_multi_loadstore

[AArch64] Implement lmw/stmw.
This commit is contained in:
Ryan Houdek 2015-06-07 23:12:42 -04:00
commit c8068e26fb
3 changed files with 115 additions and 2 deletions

View File

@ -115,6 +115,8 @@ public:
void icbi(UGeckoInstruction inst); void icbi(UGeckoInstruction inst);
void lXX(UGeckoInstruction inst); void lXX(UGeckoInstruction inst);
void stX(UGeckoInstruction inst); void stX(UGeckoInstruction inst);
void lmw(UGeckoInstruction inst);
void stmw(UGeckoInstruction inst);
// LoadStore floating point // LoadStore floating point
void lfXX(UGeckoInstruction inst); void lfXX(UGeckoInstruction inst);

View File

@ -515,3 +515,114 @@ void JitArm64::stX(UGeckoInstruction inst)
gpr.Unlock(WA); gpr.Unlock(WA);
} }
} }
void JitArm64::lmw(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITLoadStoreOff);
FALLBACK_IF(!jo.fastmem);
u32 a = inst.RA;
ARM64Reg WA = gpr.GetReg();
ARM64Reg XA = EncodeRegTo64(WA);
if (a)
{
bool add = inst.SIMM_16 >= 0;
u16 off = std::abs(inst.SIMM_16);
if (off < 4096)
{
if (add)
ADD(WA, gpr.R(a), off);
else
SUB(WA, gpr.R(a), off);
}
else
{
u16 remaining = off >> 12;
if (add)
{
ADD(WA, WA, remaining, true);
ADD(WA, gpr.R(a), off & 0xFFF);
}
else
{
SUB(WA, WA, remaining, true);
SUB(WA, gpr.R(a), off & 0xFFF);
}
}
}
else
{
MOVI2R(WA, (u32)(s32)(s16)inst.SIMM_16);
}
u8* base = UReg_MSR(MSR).DR ? Memory::logical_base : Memory::physical_base;
MOVK(XA, ((u64)base >> 32) & 0xFFFF, SHIFT_32);
for (int i = inst.RD; i < 32; i++)
{
gpr.BindToRegister(i, false);
ARM64Reg RX = gpr.R(i);
LDR(INDEX_UNSIGNED, RX, XA, (i - inst.RD) * 4);
REV32(RX, RX);
}
gpr.Unlock(WA);
}
void JitArm64::stmw(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITLoadStoreOff);
FALLBACK_IF(!jo.fastmem);
u32 a = inst.RA;
ARM64Reg WA = gpr.GetReg();
ARM64Reg XA = EncodeRegTo64(WA);
ARM64Reg WB = gpr.GetReg();
if (a)
{
bool add = inst.SIMM_16 >= 0;
u16 off = std::abs(inst.SIMM_16);
if (off < 4096)
{
if (add)
ADD(WA, gpr.R(a), off);
else
SUB(WA, gpr.R(a), off);
}
else
{
u16 remaining = off >> 12;
if (add)
{
ADD(WA, WA, remaining, true);
ADD(WA, gpr.R(a), off & 0xFFF);
}
else
{
SUB(WA, WA, remaining, true);
SUB(WA, gpr.R(a), off & 0xFFF);
}
}
}
else
{
MOVI2R(WA, (u32)(s32)(s16)inst.SIMM_16);
}
u8* base = UReg_MSR(MSR).DR ? Memory::logical_base : Memory::physical_base;
MOVK(XA, ((u64)base >> 32) & 0xFFFF, SHIFT_32);
for (int i = inst.RD; i < 32; i++)
{
ARM64Reg RX = gpr.R(i);
REV32(WB, RX);
STR(INDEX_UNSIGNED, WB, XA, (i - inst.RD) * 4);
}
gpr.Unlock(WA, WB);
}

View File

@ -79,8 +79,8 @@ static GekkoOPTemplate primarytable[] =
{38, &JitArm64::stX}, // stb {38, &JitArm64::stX}, // stb
{39, &JitArm64::stX}, // stbu {39, &JitArm64::stX}, // stbu
{46, &JitArm64::FallBackToInterpreter}, // lmw {46, &JitArm64::lmw}, // lmw
{47, &JitArm64::FallBackToInterpreter}, // stmw {47, &JitArm64::stmw}, // stmw
{48, &JitArm64::lfXX}, // lfs {48, &JitArm64::lfXX}, // lfs
{49, &JitArm64::lfXX}, // lfsu {49, &JitArm64::lfXX}, // lfsu