Implement a few more store instructions on ARM
This commit is contained in:
parent
62adcaf552
commit
ccf1cee203
|
@ -171,6 +171,9 @@ public:
|
||||||
void lhz(UGeckoInstruction _inst);
|
void lhz(UGeckoInstruction _inst);
|
||||||
void lwz(UGeckoInstruction _inst);
|
void lwz(UGeckoInstruction _inst);
|
||||||
void lwzx(UGeckoInstruction _inst);
|
void lwzx(UGeckoInstruction _inst);
|
||||||
|
void stbu(UGeckoInstruction _inst);
|
||||||
|
void sth(UGeckoInstruction _inst);
|
||||||
|
void sthu(UGeckoInstruction _inst);
|
||||||
void stw(UGeckoInstruction _inst);
|
void stw(UGeckoInstruction _inst);
|
||||||
void stwu(UGeckoInstruction _inst);
|
void stwu(UGeckoInstruction _inst);
|
||||||
|
|
||||||
|
|
|
@ -50,38 +50,48 @@ static void BackPatchError(const std::string &text, u8 *codePtr, u32 emAddress)
|
||||||
bool DisamLoadStore(const u32 inst, ARMReg &rD, u8 &accessSize, bool &Store)
|
bool DisamLoadStore(const u32 inst, ARMReg &rD, u8 &accessSize, bool &Store)
|
||||||
{
|
{
|
||||||
u8 op = (inst >> 20) & 0xFF;
|
u8 op = (inst >> 20) & 0xFF;
|
||||||
|
rD = (ARMReg)((inst >> 12) & 0xF);
|
||||||
|
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case 0x58: // STR
|
case 0x58: // STR
|
||||||
{
|
{
|
||||||
rD = (ARMReg)((inst >> 12) & 0xF);
|
|
||||||
Store = true;
|
Store = true;
|
||||||
accessSize = 32;
|
accessSize = 32;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x59: // LDR
|
case 0x59: // LDR
|
||||||
{
|
{
|
||||||
rD = (ARMReg)((inst >> 12) & 0xF);
|
|
||||||
Store = false;
|
Store = false;
|
||||||
accessSize = 32;
|
accessSize = 32;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x05: // LDRH
|
case 0x1D: // LDRH
|
||||||
{
|
{
|
||||||
rD = (ARMReg)((inst >> 12) & 0xF);
|
|
||||||
Store = false;
|
Store = false;
|
||||||
accessSize = 16;
|
accessSize = 16;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x45 + 0x18: // LDRB
|
case 0x45 + 0x18: // LDRB
|
||||||
{
|
{
|
||||||
rD = (ARMReg)((inst >> 12) & 0xF);
|
|
||||||
Store = false;
|
Store = false;
|
||||||
accessSize = 8;
|
accessSize = 8;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x5C: // STRB
|
||||||
|
{
|
||||||
|
Store = true;
|
||||||
|
accessSize = 8;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x1C: // STRH
|
||||||
|
{
|
||||||
|
Store = true;
|
||||||
|
accessSize = 16;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x44 + 0x18: // STRB
|
|
||||||
default:
|
default:
|
||||||
|
printf("Op is 0x%02x\n", op);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -110,11 +120,11 @@ const u8 *JitArm::BackPatch(u8 *codePtr, int accessType, u32 emAddress, void *ct
|
||||||
switch (accessSize)
|
switch (accessSize)
|
||||||
{
|
{
|
||||||
case 8: // 8bit
|
case 8: // 8bit
|
||||||
//emitter.MOVI2R(R14, (u32)&Memory::Write_U8, false); // 1-2
|
emitter.MOVI2R(R14, (u32)&Memory::Write_U8, false); // 1-2
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case 16: // 16bit
|
case 16: // 16bit
|
||||||
//emitter.MOVI2R(R14, (u32)&Memory::Write_U16, false); // 1-2
|
emitter.MOVI2R(R14, (u32)&Memory::Write_U16, false); // 1-2
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case 32: // 32bit
|
case 32: // 32bit
|
||||||
|
|
|
@ -36,6 +36,118 @@
|
||||||
#else
|
#else
|
||||||
#define FASTMEM 1
|
#define FASTMEM 1
|
||||||
#endif
|
#endif
|
||||||
|
void JitArm::stbu(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(LoadStore)
|
||||||
|
ARMReg RA = gpr.R(inst.RA);
|
||||||
|
ARMReg RS = gpr.R(inst.RS);
|
||||||
|
ARMReg ValueReg = gpr.GetReg();
|
||||||
|
ARMReg Addr = gpr.GetReg();
|
||||||
|
ARMReg Function = gpr.GetReg();
|
||||||
|
|
||||||
|
MOVI2R(Addr, inst.SIMM_16);
|
||||||
|
ADD(Addr, Addr, RA);
|
||||||
|
|
||||||
|
// Check for DSI exception prior to writing back address
|
||||||
|
LDR(Function, R9, PPCSTATE_OFF(Exceptions));
|
||||||
|
CMP(Function, EXCEPTION_DSI);
|
||||||
|
FixupBranch DoNotWrite = B_CC(CC_EQ);
|
||||||
|
MOV(RA, Addr);
|
||||||
|
SetJumpTarget(DoNotWrite);
|
||||||
|
|
||||||
|
MOV(ValueReg, RS);
|
||||||
|
|
||||||
|
MOVI2R(Function, (u32)&Memory::Write_U8);
|
||||||
|
PUSH(4, R0, R1, R2, R3);
|
||||||
|
MOV(R0, ValueReg);
|
||||||
|
MOV(R1, Addr);
|
||||||
|
BL(Function);
|
||||||
|
POP(4, R0, R1, R2, R3);
|
||||||
|
|
||||||
|
gpr.Unlock(ValueReg, Addr, Function);
|
||||||
|
}
|
||||||
|
void JitArm::sth(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(LoadStore)
|
||||||
|
|
||||||
|
ARMReg RS = gpr.R(inst.RS);
|
||||||
|
#if 0 // FASTMEM
|
||||||
|
// R10 contains the dest address
|
||||||
|
ARMReg Value = R11;
|
||||||
|
ARMReg RA;
|
||||||
|
if (inst.RA)
|
||||||
|
RA = gpr.R(inst.RA);
|
||||||
|
MOV(Value, RS);
|
||||||
|
if (inst.RA)
|
||||||
|
{
|
||||||
|
MOVI2R(R10, inst.SIMM_16, false);
|
||||||
|
ADD(R10, R10, RA);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MOVI2R(R10, (u32)inst.SIMM_16, false);
|
||||||
|
NOP(1);
|
||||||
|
}
|
||||||
|
StoreFromReg(R10, Value, 16, 0);
|
||||||
|
#else
|
||||||
|
ARMReg ValueReg = gpr.GetReg();
|
||||||
|
ARMReg Addr = gpr.GetReg();
|
||||||
|
ARMReg Function = gpr.GetReg();
|
||||||
|
|
||||||
|
MOV(ValueReg, RS);
|
||||||
|
if (inst.RA)
|
||||||
|
{
|
||||||
|
MOVI2R(Addr, inst.SIMM_16);
|
||||||
|
ARMReg RA = gpr.R(inst.RA);
|
||||||
|
ADD(Addr, Addr, RA);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MOVI2R(Addr, (u32)inst.SIMM_16);
|
||||||
|
|
||||||
|
MOVI2R(Function, (u32)&Memory::Write_U16);
|
||||||
|
PUSH(4, R0, R1, R2, R3);
|
||||||
|
MOV(R0, ValueReg);
|
||||||
|
MOV(R1, Addr);
|
||||||
|
BL(Function);
|
||||||
|
POP(4, R0, R1, R2, R3);
|
||||||
|
gpr.Unlock(ValueReg, Addr, Function);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void JitArm::sthu(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(LoadStore)
|
||||||
|
|
||||||
|
ARMReg RA = gpr.R(inst.RA);
|
||||||
|
ARMReg RS = gpr.R(inst.RS);
|
||||||
|
ARMReg ValueReg = gpr.GetReg();
|
||||||
|
ARMReg Addr = gpr.GetReg();
|
||||||
|
ARMReg Function = gpr.GetReg();
|
||||||
|
|
||||||
|
MOVI2R(Addr, inst.SIMM_16);
|
||||||
|
ADD(Addr, Addr, RA);
|
||||||
|
|
||||||
|
// Check for DSI exception prior to writing back address
|
||||||
|
LDR(Function, R9, PPCSTATE_OFF(Exceptions));
|
||||||
|
CMP(Function, EXCEPTION_DSI);
|
||||||
|
FixupBranch DoNotWrite = B_CC(CC_EQ);
|
||||||
|
MOV(RA, Addr);
|
||||||
|
SetJumpTarget(DoNotWrite);
|
||||||
|
|
||||||
|
MOV(ValueReg, RS);
|
||||||
|
|
||||||
|
MOVI2R(Function, (u32)&Memory::Write_U16);
|
||||||
|
PUSH(4, R0, R1, R2, R3);
|
||||||
|
MOV(R0, ValueReg);
|
||||||
|
MOV(R1, Addr);
|
||||||
|
BL(Function);
|
||||||
|
POP(4, R0, R1, R2, R3);
|
||||||
|
|
||||||
|
gpr.Unlock(ValueReg, Addr, Function);
|
||||||
|
}
|
||||||
|
|
||||||
void JitArm::stw(UGeckoInstruction inst)
|
void JitArm::stw(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
|
@ -98,8 +210,7 @@ void JitArm::stwu(UGeckoInstruction inst)
|
||||||
MOVI2R(Addr, inst.SIMM_16);
|
MOVI2R(Addr, inst.SIMM_16);
|
||||||
ADD(Addr, Addr, RA);
|
ADD(Addr, Addr, RA);
|
||||||
|
|
||||||
// Check and set the update before writing since calling a function can
|
// Check for DSI exception prior to writing back address
|
||||||
// mess with the "special registers R11+ which may cause some issues.
|
|
||||||
LDR(Function, R9, PPCSTATE_OFF(Exceptions));
|
LDR(Function, R9, PPCSTATE_OFF(Exceptions));
|
||||||
CMP(Function, EXCEPTION_DSI);
|
CMP(Function, EXCEPTION_DSI);
|
||||||
FixupBranch DoNotWrite = B_CC(CC_EQ);
|
FixupBranch DoNotWrite = B_CC(CC_EQ);
|
||||||
|
@ -144,10 +255,10 @@ void JitArm::StoreFromReg(ARMReg dest, ARMReg value, int accessSize, s32 offset)
|
||||||
STR(value, dest); // 8
|
STR(value, dest); // 8
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
// Not implemented
|
STRH(value, dest);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
// Not implemented
|
STRB(value, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
gpr.Unlock(rA);
|
gpr.Unlock(rA);
|
||||||
|
@ -256,14 +367,11 @@ void JitArm::lhz(UGeckoInstruction inst)
|
||||||
if (inst.RA)
|
if (inst.RA)
|
||||||
{
|
{
|
||||||
ARMReg RA = gpr.R(inst.RA);
|
ARMReg RA = gpr.R(inst.RA);
|
||||||
printf("lhz jump to here: 0x%08x\n", (u32)GetCodePtr());
|
|
||||||
MOV(R10, RA); // - 4
|
MOV(R10, RA); // - 4
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
printf("lhz jump to here: 0x%08x\n", (u32)GetCodePtr());
|
|
||||||
MOV(R10, 0); // - 4
|
MOV(R10, 0); // - 4
|
||||||
}
|
|
||||||
LoadToReg(RD, R10, 16, (u32)inst.SIMM_16);
|
LoadToReg(RD, R10, 16, (u32)inst.SIMM_16);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
|
@ -87,12 +87,12 @@ static GekkoOPTemplate primarytable[] =
|
||||||
{42, &JitArm::Default}, //"lha", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}},
|
{42, &JitArm::Default}, //"lha", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}},
|
||||||
{43, &JitArm::Default}, //"lhau", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}},
|
{43, &JitArm::Default}, //"lhau", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}},
|
||||||
|
|
||||||
{44, &JitArm::Default}, //"sth", OPTYPE_STORE, FL_IN_A | FL_IN_S}},
|
{44, &JitArm::sth}, //"sth", OPTYPE_STORE, FL_IN_A | FL_IN_S}},
|
||||||
{45, &JitArm::Default}, //"sthu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}},
|
{45, &JitArm::sthu}, //"sthu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}},
|
||||||
{36, &JitArm::stw}, //"stw", OPTYPE_STORE, FL_IN_A | FL_IN_S}},
|
{36, &JitArm::stw}, //"stw", OPTYPE_STORE, FL_IN_A | FL_IN_S}},
|
||||||
{37, &JitArm::stwu}, //"stwu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}},
|
{37, &JitArm::stwu}, //"stwu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}},
|
||||||
{38, &JitArm::Default}, //"stb", OPTYPE_STORE, FL_IN_A | FL_IN_S}},
|
{38, &JitArm::Default}, //"stb", OPTYPE_STORE, FL_IN_A | FL_IN_S}},
|
||||||
{39, &JitArm::Default}, //"stbu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}},
|
{39, &JitArm::stbu}, //"stbu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}},
|
||||||
|
|
||||||
{46, &JitArm::Default}, //"lmw", OPTYPE_SYSTEM, FL_EVIL, 10}},
|
{46, &JitArm::Default}, //"lmw", OPTYPE_SYSTEM, FL_EVIL, 10}},
|
||||||
{47, &JitArm::Default}, //"stmw", OPTYPE_SYSTEM, FL_EVIL, 10}},
|
{47, &JitArm::Default}, //"stmw", OPTYPE_SYSTEM, FL_EVIL, 10}},
|
||||||
|
|
Loading…
Reference in New Issue