JitArm64: Store carry within the host carry flag.

This commit is contained in:
degasus 2016-10-27 20:49:15 +02:00
parent 1c9ed79c6a
commit 4d88f5410e
3 changed files with 32 additions and 0 deletions

View File

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

View File

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

View File

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