diff --git a/Common/ArmEmitter.cpp b/Common/ArmEmitter.cpp index e4306c0324..15c60f8a6f 100644 --- a/Common/ArmEmitter.cpp +++ b/Common/ArmEmitter.cpp @@ -542,11 +542,20 @@ void ARMXEmitter::WriteStoreOp(u32 op, ARMReg dest, ARMReg src, Operand2 op2) Write32(condition | (op << 20) | (3 << 23) | (dest << 16) | (src << 12) | op2.Imm12()); } void ARMXEmitter::STR (ARMReg dest, ARMReg src, Operand2 op) { WriteStoreOp(0x40, dest, src, op);} +void ARMXEmitter::STRH(ARMReg dest, ARMReg src, Operand2 op) +{ + u8 Imm = op.Imm8(); + Write32(condition | (0x04 << 20) | (src << 16) | (dest << 12) | ((Imm >> 4) << 8) | (0xB << 4) | (Imm & 0x0F)); +} void ARMXEmitter::STRB(ARMReg dest, ARMReg src, Operand2 op) { WriteStoreOp(0x44, dest, src, op);} void ARMXEmitter::STR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add) { Write32(condition | (0x60 << 20) | (Index << 24) | (Add << 23) | (dest << 16) | (base << 12) | offset); } +void ARMXEmitter::STRB (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add) +{ + Write32(condition | (0x64 << 20) | (Index << 24) | (Add << 23) | (dest << 16) | (base << 12) | offset); +} void ARMXEmitter::LDREX(ARMReg dest, ARMReg base) { Write32(condition | (25 << 20) | (base << 16) | (dest << 12) | 0xF9F); @@ -577,6 +586,10 @@ void ARMXEmitter::LDR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool { Write32(condition | (0x61 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | offset); } +void ARMXEmitter::LDRB (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add) +{ + Write32(condition | (0x65 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | offset); +} void ARMXEmitter::WriteRegStoreOp(u32 op, ARMReg dest, bool WriteBack, u16 RegList) { Write32(condition | (op << 20) | (WriteBack << 21) | (dest << 16) | RegList); diff --git a/Common/ArmEmitter.h b/Common/ArmEmitter.h index e050cd53f4..90160707e1 100644 --- a/Common/ArmEmitter.h +++ b/Common/ArmEmitter.h @@ -468,15 +468,19 @@ public: // Memory load/store operations void LDR (ARMReg dest, ARMReg src, Operand2 op2 = 0); + void LDRH(ARMReg dest, ARMReg src, Operand2 op2 = 0); + void LDRB(ARMReg dest, ARMReg src, Operand2 op2 = 0); // Offset adds to the base register in LDR void LDR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); - void LDRH(ARMReg dest, ARMReg src, Operand2 op = 0); - void LDRB(ARMReg dest, ARMReg src, Operand2 op2 = 0); + void LDRB (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); + void STR (ARMReg dest, ARMReg src, Operand2 op2 = 0); + void STRH(ARMReg dest, ARMReg src, Operand2 op2 = 0); + void STRB(ARMReg dest, ARMReg src, Operand2 op2 = 0); // Offset adds on to the destination register in STR void STR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); + void STRB (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); - void STRB(ARMReg dest, ARMReg src, Operand2 op2 = 0); void STMFD(ARMReg dest, bool WriteBack, const int Regnum, ...); void LDMFD(ARMReg dest, bool WriteBack, const int Regnum, ...); diff --git a/Core/MIPS/ARM/ArmCompLoadStore.cpp b/Core/MIPS/ARM/ArmCompLoadStore.cpp index fff481a295..db7e843474 100644 --- a/Core/MIPS/ARM/ArmCompLoadStore.cpp +++ b/Core/MIPS/ARM/ArmCompLoadStore.cpp @@ -94,12 +94,9 @@ namespace MIPSComp } switch (o) { - case 37: //R(rt) = ReadMem16(addr); break; //lhu - Comp_Generic(op); - return; - - case 35: //R(rt) = ReadMem32(addr); //lw + case 35: //R(rt) = ReadMem32(addr); break; //lw case 36: //R(rt) = ReadMem8 (addr); break; //lbu + case 37: //R(rt) = ReadMem16(addr); break; //lhu if (g_Config.bFastMemory) { if (gpr.IsImm(rs)) { // We can compute the full address at compile time. Kickass. @@ -113,8 +110,10 @@ namespace MIPSComp if (o == 35) { LDR(gpr.R(rt), R11, R0, true, true); } else if (o == 36) { + LDRB(gpr.R(rt), R11, R0, true, true); + } else if (o == 37) { ADD(R0, R0, R11); // TODO: Merge with next instruction - LDRB(gpr.R(rt), R0); + LDRH(gpr.R(rt), R0); } } else { Comp_Generic(op); @@ -122,11 +121,8 @@ namespace MIPSComp } break; + case 40: //WriteMem8 (addr, R(rt)); break; //sb case 41: //WriteMem16(addr, R(rt)); break; //sh - Comp_Generic(op); - return; - - case 40: //sb case 43: //WriteMem32(addr, R(rt)); break; //sw if (g_Config.bFastMemory) { if (gpr.IsImm(rs)) { @@ -141,15 +137,16 @@ namespace MIPSComp if (o == 43) { STR(R0, gpr.R(rt), R11, true, true); } else if (o == 40) { - ADD(R0, R0, R11); - STRB(R0, gpr.R(rt)); + STRB(R0, gpr.R(rt), R11, true, true); + } else if (o == 41) { + ADD(R0, R0, R11); // TODO: Merge with next instruction + STRH(gpr.R(rt), R0); } } else { Comp_Generic(op); return; } break; - // break; /* case 34: //lwl {