emit_x64_data_processing: Minor optimization for immediates in EmitSub
This commit is contained in:
parent
eeeafaf5fb
commit
e926f0b393
1 changed files with 14 additions and 6 deletions
|
@ -1090,19 +1090,21 @@ static void EmitSub(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, int bit
|
||||||
// TODO: Optimize CMP case.
|
// TODO: Optimize CMP case.
|
||||||
// Note that x64 CF is inverse of what the ARM carry flag is here.
|
// Note that x64 CF is inverse of what the ARM carry flag is here.
|
||||||
|
|
||||||
|
bool invert_output_carry = true;
|
||||||
|
|
||||||
if (args[1].IsImmediate() && args[1].GetType() == IR::Type::U32) {
|
if (args[1].IsImmediate() && args[1].GetType() == IR::Type::U32) {
|
||||||
const u32 op_arg = args[1].GetImmediateU32();
|
const u32 op_arg = args[1].GetImmediateU32();
|
||||||
if (carry_in.IsImmediate()) {
|
if (carry_in.IsImmediate()) {
|
||||||
if (carry_in.GetImmediateU1()) {
|
if (carry_in.GetImmediateU1()) {
|
||||||
code.sub(result, op_arg);
|
code.sub(result, op_arg);
|
||||||
} else {
|
} else {
|
||||||
code.stc();
|
code.add(result, ~op_arg);
|
||||||
code.sbb(result, op_arg);
|
invert_output_carry = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
code.bt(carry.cvt32(), 0);
|
code.bt(carry.cvt32(), 0);
|
||||||
code.cmc();
|
code.adc(result, ~op_arg);
|
||||||
code.sbb(result, op_arg);
|
invert_output_carry = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
OpArg op_arg = ctx.reg_alloc.UseOpArg(args[1]);
|
OpArg op_arg = ctx.reg_alloc.UseOpArg(args[1]);
|
||||||
|
@ -1122,14 +1124,20 @@ static void EmitSub(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, int bit
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nzcv_inst) {
|
if (nzcv_inst) {
|
||||||
|
if (invert_output_carry) {
|
||||||
code.cmc();
|
code.cmc();
|
||||||
|
}
|
||||||
code.lahf();
|
code.lahf();
|
||||||
code.seto(code.al);
|
code.seto(code.al);
|
||||||
ctx.reg_alloc.DefineValue(nzcv_inst, nzcv);
|
ctx.reg_alloc.DefineValue(nzcv_inst, nzcv);
|
||||||
ctx.EraseInstruction(nzcv_inst);
|
ctx.EraseInstruction(nzcv_inst);
|
||||||
}
|
}
|
||||||
if (carry_inst) {
|
if (carry_inst) {
|
||||||
|
if (invert_output_carry) {
|
||||||
code.setnc(carry);
|
code.setnc(carry);
|
||||||
|
} else {
|
||||||
|
code.setc(carry);
|
||||||
|
}
|
||||||
ctx.reg_alloc.DefineValue(carry_inst, carry);
|
ctx.reg_alloc.DefineValue(carry_inst, carry);
|
||||||
ctx.EraseInstruction(carry_inst);
|
ctx.EraseInstruction(carry_inst);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue