JitArm64: Store carry within the host carry flag.
This commit is contained in:
parent
1c9ed79c6a
commit
4d88f5410e
|
@ -54,6 +54,7 @@ void JitArm64::Init()
|
||||||
code_block.m_gpa = &js.gpa;
|
code_block.m_gpa = &js.gpa;
|
||||||
code_block.m_fpa = &js.fpa;
|
code_block.m_fpa = &js.fpa;
|
||||||
analyzer.SetOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE);
|
analyzer.SetOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE);
|
||||||
|
analyzer.SetOption(PPCAnalyst::PPCAnalyzer::OPTION_CARRY_MERGE);
|
||||||
|
|
||||||
m_supports_cycle_counter = HasCycleCounters();
|
m_supports_cycle_counter = HasCycleCounters();
|
||||||
}
|
}
|
||||||
|
@ -79,6 +80,7 @@ void JitArm64::Shutdown()
|
||||||
|
|
||||||
void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
|
void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
FlushCarry();
|
||||||
gpr.Flush(FlushMode::FLUSH_ALL, js.op);
|
gpr.Flush(FlushMode::FLUSH_ALL, js.op);
|
||||||
fpr.Flush(FlushMode::FLUSH_ALL, js.op);
|
fpr.Flush(FlushMode::FLUSH_ALL, js.op);
|
||||||
|
|
||||||
|
@ -419,6 +421,7 @@ const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitB
|
||||||
js.downcountAmount = 0;
|
js.downcountAmount = 0;
|
||||||
js.skipInstructions = 0;
|
js.skipInstructions = 0;
|
||||||
js.curBlock = b;
|
js.curBlock = b;
|
||||||
|
js.carryFlagSet = false;
|
||||||
|
|
||||||
PPCAnalyst::CodeOp* ops = code_buf->codebuffer;
|
PPCAnalyst::CodeOp* ops = code_buf->codebuffer;
|
||||||
|
|
||||||
|
|
|
@ -241,6 +241,7 @@ private:
|
||||||
void ComputeRC(u64 imm, int crf = 0, bool needs_sext = true);
|
void ComputeRC(u64 imm, int crf = 0, bool needs_sext = true);
|
||||||
void ComputeCarry(bool Carry);
|
void ComputeCarry(bool Carry);
|
||||||
void ComputeCarry();
|
void ComputeCarry();
|
||||||
|
void FlushCarry();
|
||||||
|
|
||||||
void reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32),
|
void reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32),
|
||||||
void (ARM64XEmitter::*op)(ARM64Reg, ARM64Reg, u64, ARM64Reg), bool Rc = false);
|
void (ARM64XEmitter::*op)(ARM64Reg, ARM64Reg, u64, ARM64Reg), bool Rc = false);
|
||||||
|
|
|
@ -49,6 +49,8 @@ void JitArm64::ComputeRC(u64 imm, int crf, bool needs_sext)
|
||||||
|
|
||||||
void JitArm64::ComputeCarry(bool Carry)
|
void JitArm64::ComputeCarry(bool Carry)
|
||||||
{
|
{
|
||||||
|
js.carryFlagSet = false;
|
||||||
|
|
||||||
if (!js.op->wantsCA)
|
if (!js.op->wantsCA)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -66,13 +68,31 @@ void JitArm64::ComputeCarry(bool Carry)
|
||||||
|
|
||||||
void JitArm64::ComputeCarry()
|
void JitArm64::ComputeCarry()
|
||||||
{
|
{
|
||||||
|
js.carryFlagSet = false;
|
||||||
|
|
||||||
if (!js.op->wantsCA)
|
if (!js.op->wantsCA)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
js.carryFlagSet = true;
|
||||||
|
if (MergeAllowedNextInstructions(1) && js.op[1].wantsCAInFlags)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FlushCarry();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitArm64::FlushCarry()
|
||||||
|
{
|
||||||
|
if (!js.carryFlagSet)
|
||||||
|
return;
|
||||||
|
|
||||||
ARM64Reg WA = gpr.GetReg();
|
ARM64Reg WA = gpr.GetReg();
|
||||||
CSINC(WA, WSP, WSP, CC_CC);
|
CSINC(WA, WSP, WSP, CC_CC);
|
||||||
STRB(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
|
STRB(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
|
||||||
gpr.Unlock(WA);
|
gpr.Unlock(WA);
|
||||||
|
|
||||||
|
js.carryFlagSet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32),
|
void JitArm64::reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32),
|
||||||
|
@ -732,6 +752,8 @@ void JitArm64::addzex(UGeckoInstruction inst)
|
||||||
JITDISABLE(bJITIntegerOff);
|
JITDISABLE(bJITIntegerOff);
|
||||||
FALLBACK_IF(inst.OE);
|
FALLBACK_IF(inst.OE);
|
||||||
|
|
||||||
|
FlushCarry();
|
||||||
|
|
||||||
int a = inst.RA, d = inst.RD;
|
int a = inst.RA, d = inst.RD;
|
||||||
|
|
||||||
if (d == a)
|
if (d == a)
|
||||||
|
@ -784,6 +806,8 @@ void JitArm64::subfex(UGeckoInstruction inst)
|
||||||
JITDISABLE(bJITIntegerOff);
|
JITDISABLE(bJITIntegerOff);
|
||||||
FALLBACK_IF(inst.OE);
|
FALLBACK_IF(inst.OE);
|
||||||
|
|
||||||
|
FlushCarry();
|
||||||
|
|
||||||
int a = inst.RA, b = inst.RB, d = inst.RD;
|
int a = inst.RA, b = inst.RB, d = inst.RD;
|
||||||
|
|
||||||
if (gpr.IsImm(a) && gpr.IsImm(b))
|
if (gpr.IsImm(a) && gpr.IsImm(b))
|
||||||
|
@ -875,6 +899,8 @@ void JitArm64::subfzex(UGeckoInstruction inst)
|
||||||
JITDISABLE(bJITIntegerOff);
|
JITDISABLE(bJITIntegerOff);
|
||||||
FALLBACK_IF(inst.OE);
|
FALLBACK_IF(inst.OE);
|
||||||
|
|
||||||
|
FlushCarry();
|
||||||
|
|
||||||
int a = inst.RA, d = inst.RD;
|
int a = inst.RA, d = inst.RD;
|
||||||
|
|
||||||
gpr.BindToRegister(d, d == a);
|
gpr.BindToRegister(d, d == a);
|
||||||
|
@ -926,6 +952,8 @@ void JitArm64::addex(UGeckoInstruction inst)
|
||||||
JITDISABLE(bJITIntegerOff);
|
JITDISABLE(bJITIntegerOff);
|
||||||
FALLBACK_IF(inst.OE);
|
FALLBACK_IF(inst.OE);
|
||||||
|
|
||||||
|
FlushCarry();
|
||||||
|
|
||||||
int a = inst.RA, b = inst.RB, d = inst.RD;
|
int a = inst.RA, b = inst.RB, d = inst.RD;
|
||||||
|
|
||||||
if (gpr.IsImm(a) && gpr.IsImm(b))
|
if (gpr.IsImm(a) && gpr.IsImm(b))
|
||||||
|
|
Loading…
Reference in New Issue