Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[ARM] Reimplement fastmem for the few loadstores that had it before.
  • Loading branch information
Sonicadvance1 committed Sep 4, 2013
1 parent e9ffba7 commit 8684b76
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 44 deletions.
1 change: 1 addition & 0 deletions Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp
Expand Up @@ -296,6 +296,7 @@ void STACKALIGN JitArm::Jit(u32 em_address)
}
void JitArm::Break(UGeckoInstruction inst)
{
ERROR_LOG(DYNA_REC, "%s called a Break instruction!", PPCTables::GetInstructionName(inst));
BKPT(0x4444);
}

Expand Down
4 changes: 2 additions & 2 deletions Source/Core/Core/Src/PowerPC/JitArm32/Jit.h
Expand Up @@ -127,8 +127,8 @@ class JitArm : public JitBase, public ArmGen::ARMXCodeBlock
void UnsafeStoreFromReg(ARMReg dest, ARMReg value, int accessSize, s32 offset);
void SafeStoreFromReg(bool fastmem, s32 dest, u32 value, s32 offsetReg, int accessSize, s32 offset);

void SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, int accessSize, s32 offset, bool signExtend, bool reverse);
void LoadToReg(ARMReg dest, ARMReg addr, int accessSize, s32 offset);
void UnsafeLoadToReg(ARMReg dest, ARMReg addr, int accessSize, s32 offset);
void SafeLoadToReg(bool fastmem, u32 dest, s32 addr, s32 offsetReg, int accessSize, s32 offset, bool signExtend, bool reverse);


// OPCODES
Expand Down
98 changes: 56 additions & 42 deletions Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp
Expand Up @@ -217,9 +217,58 @@ void JitArm::stX(UGeckoInstruction inst)
}
}

void JitArm::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, int accessSize, s32 offset, bool signExtend, bool reverse)
void JitArm::UnsafeLoadToReg(ARMReg dest, ARMReg addr, int accessSize, s32 offset)
{
ARMReg rA = gpr.GetReg();
MOVI2R(rA, offset, false); // -3
ADD(addr, addr, rA); // - 1

// All this gets replaced on backpatch
MOVI2R(rA, Memory::MEMVIEW32_MASK, false); // 2
AND(addr, addr, rA); // 3
MOVI2R(rA, (u32)Memory::base, false); // 5
ADD(addr, addr, rA); // 6
switch (accessSize)
{
case 32:
LDR(dest, addr); // 7
break;
case 16:
LDRH(dest, addr);
break;
case 8:
LDRB(dest, addr);
break;
}
switch (accessSize)
{
case 32:
REV(dest, dest); // 9
break;
case 16:
REV16(dest, dest);
break;
case 8:
NOP(1);
break;

}
gpr.Unlock(rA);
}

void JitArm::SafeLoadToReg(bool fastmem, u32 dest, s32 addr, s32 offsetReg, int accessSize, s32 offset, bool signExtend, bool reverse)
{
ARMReg RD = gpr.R(dest);
if (Core::g_CoreStartupParameter.bFastmem && fastmem)
{
if (addr != -1)
MOV(R10, gpr.R(addr));
else
MOV(R10, 0);

UnsafeLoadToReg(RD, R10, accessSize, offset);
return;
}
ARMReg rA = gpr.GetReg();
ARMReg rB = gpr.GetReg();

Expand Down Expand Up @@ -273,7 +322,8 @@ void JitArm::lXX(UGeckoInstruction inst)
bool update = false;
bool signExtend = false;
bool reverse = false;

bool fastmem = false;

switch(inst.OPCD)
{
case 31:
Expand Down Expand Up @@ -322,18 +372,21 @@ void JitArm::lXX(UGeckoInstruction inst)
zeroA = false;
update = true;
case 32: // lwz
fastmem = true;
accessSize = 32;
break;
case 35: // lbzu
zeroA = false;
update = true;
case 34: // lbz
fastmem = true;
accessSize = 8;
break;
case 41: // lhzu
zeroA = false;
update = true;
case 40: // lhz
fastmem = true;
accessSize = 16;
break;
case 43: // lhau
Expand All @@ -351,7 +404,7 @@ void JitArm::lXX(UGeckoInstruction inst)
CMP(rA, EXCEPTION_DSI);
FixupBranch DoNotLoad = B_CC(CC_EQ);

SafeLoadToReg(d, zeroA ? a ? a : -1 : a, offsetReg, accessSize, offset, signExtend, reverse);
SafeLoadToReg(fastmem, d, zeroA ? a ? a : -1 : a, offsetReg, accessSize, offset, signExtend, reverse);

if (update)
{
Expand Down Expand Up @@ -397,45 +450,6 @@ void JitArm::lXX(UGeckoInstruction inst)

}

void JitArm::LoadToReg(ARMReg dest, ARMReg addr, int accessSize, s32 offset)
{
ARMReg rA = gpr.GetReg();
MOVI2R(rA, offset, false); // -3
ADD(addr, addr, rA); // - 1

// All this gets replaced on backpatch
MOVI2R(rA, Memory::MEMVIEW32_MASK, false); // 2
AND(addr, addr, rA); // 3
MOVI2R(rA, (u32)Memory::base, false); // 5
ADD(addr, addr, rA); // 6
switch (accessSize)
{
case 32:
LDR(dest, addr); // 7
break;
case 16:
LDRH(dest, addr);
break;
case 8:
LDRB(dest, addr);
break;
}
switch (accessSize)
{
case 32:
REV(dest, dest); // 9
break;
case 16:
REV16(dest, dest);
break;
case 8:
NOP(1);
break;

}
gpr.Unlock(rA);
}

// Some games use this heavily in video codecs
// We make the assumption that this pulls from main RAM at /all/ times
void JitArm::lmw(UGeckoInstruction inst)
Expand Down

0 comments on commit 8684b76

Please sign in to comment.