Implement a few more store instructions on ARM

This commit is contained in:
Ryan Houdek 2013-04-13 05:00:41 +00:00
parent 62adcaf552
commit ccf1cee203
4 changed files with 141 additions and 20 deletions

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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}},