[ARM] Minor cleanup to lXX and stX. Fixes a bug.
Fixes an issue in lXX where if the instruction was an update instruction and was a register address offset that we would add garbage values to the writeback register. Does some minor cleanups as well which save a few instructions here and there.
This commit is contained in:
parent
4deb8f4011
commit
d17d5ead07
|
@ -103,11 +103,18 @@ void JitArm::SafeStoreFromReg(bool fastmem, s32 dest, u32 value, s32 regOffset,
|
||||||
}
|
}
|
||||||
MOV(rB, RS);
|
MOV(rB, RS);
|
||||||
if (regOffset == -1)
|
if (regOffset == -1)
|
||||||
|
{
|
||||||
MOVI2R(rC, offset);
|
MOVI2R(rC, offset);
|
||||||
|
if (dest != -1)
|
||||||
|
ADD(rC, rC, RA);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
MOV(rC, RB);
|
{
|
||||||
if (dest != -1)
|
if (dest != -1)
|
||||||
ADD(rC, rC, RA);
|
ADD(rC, RA, RB);
|
||||||
|
else
|
||||||
|
MOV(rC, RB);
|
||||||
|
}
|
||||||
|
|
||||||
PUSH(4, R0, R1, R2, R3);
|
PUSH(4, R0, R1, R2, R3);
|
||||||
MOV(R0, rB);
|
MOV(R0, rB);
|
||||||
|
@ -126,7 +133,6 @@ void JitArm::stX(UGeckoInstruction inst)
|
||||||
s32 offset = inst.SIMM_16;
|
s32 offset = inst.SIMM_16;
|
||||||
u32 accessSize = 0;
|
u32 accessSize = 0;
|
||||||
s32 regOffset = -1;
|
s32 regOffset = -1;
|
||||||
bool zeroA = true;
|
|
||||||
bool update = false;
|
bool update = false;
|
||||||
bool fastmem = false;
|
bool fastmem = false;
|
||||||
switch (inst.OPCD)
|
switch (inst.OPCD)
|
||||||
|
@ -140,7 +146,6 @@ void JitArm::stX(UGeckoInstruction inst)
|
||||||
switch (inst.SUBOP10)
|
switch (inst.SUBOP10)
|
||||||
{
|
{
|
||||||
case 183: // stwux
|
case 183: // stwux
|
||||||
zeroA = false;
|
|
||||||
update = true;
|
update = true;
|
||||||
case 151: // stwx
|
case 151: // stwx
|
||||||
fastmem = true;
|
fastmem = true;
|
||||||
|
@ -148,14 +153,12 @@ void JitArm::stX(UGeckoInstruction inst)
|
||||||
regOffset = b;
|
regOffset = b;
|
||||||
break;
|
break;
|
||||||
case 247: // stbux
|
case 247: // stbux
|
||||||
zeroA = false;
|
|
||||||
update = true;
|
update = true;
|
||||||
case 215: // stbx
|
case 215: // stbx
|
||||||
accessSize = 8;
|
accessSize = 8;
|
||||||
regOffset = b;
|
regOffset = b;
|
||||||
break;
|
break;
|
||||||
case 439: // sthux
|
case 439: // sthux
|
||||||
zeroA = false;
|
|
||||||
update = true;
|
update = true;
|
||||||
case 407: // sthx
|
case 407: // sthx
|
||||||
accessSize = 16;
|
accessSize = 16;
|
||||||
|
@ -175,7 +178,7 @@ void JitArm::stX(UGeckoInstruction inst)
|
||||||
accessSize = 8;
|
accessSize = 8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
SafeStoreFromReg(fastmem, zeroA ? a ? a : -1 : a, s, regOffset, accessSize, offset);
|
SafeStoreFromReg(fastmem, update ? a : (a ? a : -1), s, regOffset, accessSize, offset);
|
||||||
if (update)
|
if (update)
|
||||||
{
|
{
|
||||||
ARMReg rA = gpr.GetReg();
|
ARMReg rA = gpr.GetReg();
|
||||||
|
@ -185,21 +188,27 @@ void JitArm::stX(UGeckoInstruction inst)
|
||||||
RB = gpr.R(regOffset);
|
RB = gpr.R(regOffset);
|
||||||
// Check for DSI exception prior to writing back address
|
// Check for DSI exception prior to writing back address
|
||||||
LDR(rA, R9, PPCSTATE_OFF(Exceptions));
|
LDR(rA, R9, PPCSTATE_OFF(Exceptions));
|
||||||
CMP(rA, EXCEPTION_DSI);
|
TST(rA, EXCEPTION_DSI);
|
||||||
FixupBranch DoNotWrite = B_CC(CC_EQ);
|
FixupBranch DoNotWrite = B_CC(CC_NEQ);
|
||||||
if (a)
|
if (a)
|
||||||
{
|
{
|
||||||
if (regOffset == -1)
|
if (regOffset == -1)
|
||||||
|
{
|
||||||
MOVI2R(rA, offset);
|
MOVI2R(rA, offset);
|
||||||
|
ADD(RA, RA, rA);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
MOV(rA, RB);
|
{
|
||||||
ADD(RA, RA, rA);
|
ADD(RA, RA, RB);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
if (regOffset == -1)
|
if (regOffset == -1)
|
||||||
MOVI2R(RA, (u32)offset);
|
MOVI2R(RA, (u32)offset);
|
||||||
else
|
else
|
||||||
MOV(RA, RB);
|
MOV(RA, RB);
|
||||||
|
}
|
||||||
SetJumpTarget(DoNotWrite);
|
SetJumpTarget(DoNotWrite);
|
||||||
gpr.Unlock(rA);
|
gpr.Unlock(rA);
|
||||||
}
|
}
|
||||||
|
@ -262,12 +271,18 @@ void JitArm::SafeLoadToReg(bool fastmem, u32 dest, s32 addr, s32 offsetReg, int
|
||||||
ARMReg rB = gpr.GetReg();
|
ARMReg rB = gpr.GetReg();
|
||||||
|
|
||||||
if (offsetReg == -1)
|
if (offsetReg == -1)
|
||||||
|
{
|
||||||
MOVI2R(rA, offset);
|
MOVI2R(rA, offset);
|
||||||
|
if (addr != -1)
|
||||||
|
ADD(rA, rA, gpr.R(addr));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
MOV(rA, gpr.R(offsetReg));
|
{
|
||||||
|
if (addr != -1)
|
||||||
if (addr != -1)
|
ADD(rA, gpr.R(addr), gpr.R(offsetReg));
|
||||||
ADD(rA, rA, gpr.R(addr));
|
else
|
||||||
|
MOV(rA, gpr.R(offsetReg));
|
||||||
|
}
|
||||||
|
|
||||||
switch (accessSize)
|
switch (accessSize)
|
||||||
{
|
{
|
||||||
|
@ -308,7 +323,6 @@ void JitArm::lXX(UGeckoInstruction inst)
|
||||||
s32 offset = inst.SIMM_16;
|
s32 offset = inst.SIMM_16;
|
||||||
u32 accessSize = 0;
|
u32 accessSize = 0;
|
||||||
s32 offsetReg = -1;
|
s32 offsetReg = -1;
|
||||||
bool zeroA = true;
|
|
||||||
bool update = false;
|
bool update = false;
|
||||||
bool signExtend = false;
|
bool signExtend = false;
|
||||||
bool reverse = false;
|
bool reverse = false;
|
||||||
|
@ -320,28 +334,24 @@ void JitArm::lXX(UGeckoInstruction inst)
|
||||||
switch (inst.SUBOP10)
|
switch (inst.SUBOP10)
|
||||||
{
|
{
|
||||||
case 55: // lwzux
|
case 55: // lwzux
|
||||||
zeroA = false;
|
|
||||||
update = true;
|
update = true;
|
||||||
case 23: // lwzx
|
case 23: // lwzx
|
||||||
accessSize = 32;
|
accessSize = 32;
|
||||||
offsetReg = b;
|
offsetReg = b;
|
||||||
break;
|
break;
|
||||||
case 119: //lbzux
|
case 119: //lbzux
|
||||||
zeroA = false;
|
|
||||||
update = true;
|
update = true;
|
||||||
case 87: // lbzx
|
case 87: // lbzx
|
||||||
accessSize = 8;
|
accessSize = 8;
|
||||||
offsetReg = b;
|
offsetReg = b;
|
||||||
break;
|
break;
|
||||||
case 311: // lhzux
|
case 311: // lhzux
|
||||||
zeroA = false;
|
|
||||||
update = true;
|
update = true;
|
||||||
case 279: // lhzx
|
case 279: // lhzx
|
||||||
accessSize = 16;
|
accessSize = 16;
|
||||||
offsetReg = b;
|
offsetReg = b;
|
||||||
break;
|
break;
|
||||||
case 375: // lhaux
|
case 375: // lhaux
|
||||||
zeroA = false;
|
|
||||||
update = true;
|
update = true;
|
||||||
case 343: // lhax
|
case 343: // lhax
|
||||||
accessSize = 16;
|
accessSize = 16;
|
||||||
|
@ -359,28 +369,24 @@ void JitArm::lXX(UGeckoInstruction inst)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 33: // lwzu
|
case 33: // lwzu
|
||||||
zeroA = false;
|
|
||||||
update = true;
|
update = true;
|
||||||
case 32: // lwz
|
case 32: // lwz
|
||||||
fastmem = true;
|
fastmem = true;
|
||||||
accessSize = 32;
|
accessSize = 32;
|
||||||
break;
|
break;
|
||||||
case 35: // lbzu
|
case 35: // lbzu
|
||||||
zeroA = false;
|
|
||||||
update = true;
|
update = true;
|
||||||
case 34: // lbz
|
case 34: // lbz
|
||||||
fastmem = true;
|
fastmem = true;
|
||||||
accessSize = 8;
|
accessSize = 8;
|
||||||
break;
|
break;
|
||||||
case 41: // lhzu
|
case 41: // lhzu
|
||||||
zeroA = false;
|
|
||||||
update = true;
|
update = true;
|
||||||
case 40: // lhz
|
case 40: // lhz
|
||||||
fastmem = true;
|
fastmem = true;
|
||||||
accessSize = 16;
|
accessSize = 16;
|
||||||
break;
|
break;
|
||||||
case 43: // lhau
|
case 43: // lhau
|
||||||
zeroA = false;
|
|
||||||
update = true;
|
update = true;
|
||||||
case 42: // lha
|
case 42: // lha
|
||||||
signExtend = true;
|
signExtend = true;
|
||||||
|
@ -392,20 +398,24 @@ void JitArm::lXX(UGeckoInstruction inst)
|
||||||
ARMReg rA = gpr.GetReg(false);
|
ARMReg rA = gpr.GetReg(false);
|
||||||
|
|
||||||
LDR(rA, R9, PPCSTATE_OFF(Exceptions));
|
LDR(rA, R9, PPCSTATE_OFF(Exceptions));
|
||||||
CMP(rA, EXCEPTION_DSI);
|
TST(rA, EXCEPTION_DSI);
|
||||||
FixupBranch DoNotLoad = B_CC(CC_EQ);
|
FixupBranch DoNotLoad = B_CC(CC_NEQ);
|
||||||
|
|
||||||
SafeLoadToReg(fastmem, d, zeroA ? a ? a : -1 : a, offsetReg, accessSize, offset, signExtend, reverse);
|
SafeLoadToReg(fastmem, d, update ? a : (a ? a : -1), offsetReg, accessSize, offset, signExtend, reverse);
|
||||||
|
|
||||||
if (update)
|
if (update)
|
||||||
{
|
{
|
||||||
rA = gpr.GetReg(false);
|
|
||||||
ARMReg RA = gpr.R(a);
|
ARMReg RA = gpr.R(a);
|
||||||
if (offsetReg == -1)
|
if (offsetReg == -1)
|
||||||
|
{
|
||||||
|
rA = gpr.GetReg(false);
|
||||||
MOVI2R(rA, offset);
|
MOVI2R(rA, offset);
|
||||||
|
ADD(RA, RA, rA);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
MOV(RA, gpr.R(offsetReg));
|
{
|
||||||
ADD(RA, RA, rA);
|
ADD(RA, RA, gpr.R(offsetReg));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetJumpTarget(DoNotLoad);
|
SetJumpTarget(DoNotLoad);
|
||||||
|
@ -439,7 +449,6 @@ void JitArm::lXX(UGeckoInstruction inst)
|
||||||
//js.compilerPC += 8;
|
//js.compilerPC += 8;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some games use this heavily in video codecs
|
// Some games use this heavily in video codecs
|
||||||
|
|
Loading…
Reference in New Issue