void JitArm::lha(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(LoadStore) ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); ARMReg RD = gpr.R(inst.RD); LDR(rA, R9, PPCSTATE_OFF(Exceptions)); CMP(rA, EXCEPTION_DSI); FixupBranch DoNotLoad = B_CC(CC_EQ); if (inst.RA) { MOVI2R(rB, inst.SIMM_16); ARMReg RA = gpr.R(inst.RA); ADD(rB, rB, RA); } else MOVI2R(rB, (u32)inst.SIMM_16); MOVI2R(rA, (u32)&Memory::Read_U16); PUSH(4, R0, R1, R2, R3); MOV(R0, rB); BL(rA); MOV(rA, R0); SXTH(rA, rA); POP(4, R0, R1, R2, R3); MOV(RD, rA); gpr.Unlock(rA, rB); SetJumpTarget(DoNotLoad); }
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(); if (offsetReg == -1) MOVI2R(rA, offset); else MOV(rA, gpr.R(offsetReg)); if (addr != -1) ADD(rA, rA, gpr.R(addr)); switch (accessSize) { case 8: MOVI2R(rB, (u32)&Memory::Read_U8); break; case 16: MOVI2R(rB, (u32)&Memory::Read_U16); break; case 32: MOVI2R(rB, (u32)&Memory::Read_U32); break; } PUSH(4, R0, R1, R2, R3); MOV(R0, rA); BL(rB); MOV(rA, R0); POP(4, R0, R1, R2, R3); MOV(RD, rA); if (signExtend) // Only on 16 loads SXTH(RD, RD); if (reverse) { if (accessSize == 32) REV(RD, RD); else if (accessSize == 16) REV16(RD, RD); } gpr.Unlock(rA, rB); }
void JitArm::extshx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) u32 a = inst.RA, s = inst.RS; if (gpr.IsImm(s)) { gpr.SetImmediate(a, (u32)(s32)(s16)gpr.GetImm(s)); if (inst.Rc) ComputeRC(gpr.GetImm(a), 0); return; } ARMReg rA = gpr.R(a); ARMReg rS = gpr.R(s); SXTH(rA, rS); if (inst.Rc){ CMP(rA, 0); ComputeRC(); } }