void Jit64::regimmop(int d, int a, bool binary, u32 value, Operation doop, void (XEmitter::*op)(int, const Gen::OpArg&, const Gen::OpArg&), bool Rc, bool carry) { gpr.Lock(d, a); if (a || binary || carry) // yeh nasty special case addic { if (gpr.R(a).IsImm() && !carry) { gpr.SetImmediate32(d, doop((u32)gpr.R(a).offset, value)); if (Rc) { ComputeRC(gpr.R(d)); } } else if (a == d) { gpr.KillImmediate(d, true, true); (this->*op)(32, gpr.R(d), Imm32(value)); //m_GPR[d] = m_GPR[_inst.RA] + _inst.SIMM_16; if (Rc) { // All of the possible passed operators affect Sign/Zero flags GenerateRC(); } if (carry) GenerateCarry(); } else { gpr.BindToRegister(d, false); MOV(32, gpr.R(d), gpr.R(a)); (this->*op)(32, gpr.R(d), Imm32(value)); //m_GPR[d] = m_GPR[_inst.RA] + _inst.SIMM_16; if (Rc) { // All of the possible passed operators affect Sign/Zero flags GenerateRC(); } if (carry) GenerateCarry(); } } else if (doop == Add) { // a == 0, which for these instructions imply value = 0 gpr.SetImmediate32(d, value); if (Rc) { ComputeRC(gpr.R(d)); } } else { _assert_msg_(DYNA_REC, 0, "WTF regimmop"); } gpr.UnlockAll(); }
void JitArm::subfx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) u32 a = inst.RA, b = inst.RB, d = inst.RD; if (inst.OE) PanicAlert("OE: subfx"); if (gpr.IsImm(a) && gpr.IsImm(b)) { gpr.SetImmediate(d, gpr.GetImm(b) - gpr.GetImm(a)); if (inst.Rc) ComputeRC(gpr.GetImm(d), 0); return; } ARMReg RA = gpr.R(a); ARMReg RB = gpr.R(b); ARMReg RD = gpr.R(d); SUBS(RD, RB, RA); if (inst.Rc) GenerateRC(); }