Fixing adde_constant.

This commit is contained in:
Ben Vanik
2015-05-12 22:53:20 -07:00
parent dda6f3b6bd
commit 91c6ad8715
8 changed files with 193 additions and 78 deletions

View File

@@ -574,18 +574,32 @@ struct SingleSequence : public Sequence<SingleSequence<SEQ, T>, T> {
const REG_REG_FN& reg_reg_fn,
const REG_CONST_FN& reg_const_fn) {
if (i.src1.is_constant) {
assert_true(!i.src2.is_constant);
if (i.dest == i.src2) {
if (i.src2.is_constant) {
if (i.src1.ConstantFitsIn32Reg()) {
e.mov(i.dest, i.src2.constant());
reg_const_fn(e, i.dest, static_cast<int32_t>(i.src1.constant()));
} else if (i.src2.ConstantFitsIn32Reg()) {
e.mov(i.dest, i.src1.constant());
reg_const_fn(e, i.dest, static_cast<int32_t>(i.src2.constant()));
} else {
auto temp = GetTempReg<typename decltype(i.src1)::reg_type>(e);
e.mov(temp, i.src1.constant());
e.mov(i.dest, i.src1.constant());
auto temp = GetTempReg<typename decltype(i.src2)::reg_type>(e);
e.mov(temp, i.src2.constant());
reg_reg_fn(e, i.dest, temp);
}
} else {
e.mov(i.dest, i.src1.constant());
reg_reg_fn(e, i.dest, i.src2);
if (i.dest == i.src2) {
if (i.src1.ConstantFitsIn32Reg()) {
reg_const_fn(e, i.dest, static_cast<int32_t>(i.src1.constant()));
} else {
auto temp = GetTempReg<typename decltype(i.src1)::reg_type>(e);
e.mov(temp, i.src1.constant());
reg_reg_fn(e, i.dest, temp);
}
} else {
e.mov(i.dest, i.src1.constant());
reg_reg_fn(e, i.dest, i.src2);
}
}
} else if (i.src2.is_constant) {
if (i.dest == i.src1) {

View File

@@ -2702,22 +2702,12 @@ void EmitAddCarryXX(X64Emitter& e, const ARGS& i) {
}
e.sahf();
}
if (i.src1.is_constant && i.src2.is_constant) {
auto ab = i.src1.constant() + i.src2.constant();
if (!ab) {
e.xor(i.dest, i.dest);
} else {
e.mov(i.dest, ab);
}
e.adc(i.dest, 0);
} else {
SEQ::EmitCommutativeBinaryOp(
e, i, [](X64Emitter& e, const REG& dest_src, const REG& src) {
e.adc(dest_src, src);
}, [](X64Emitter& e, const REG& dest_src, int32_t constant) {
e.adc(dest_src, constant);
});
}
SEQ::EmitCommutativeBinaryOp(
e, i, [](X64Emitter& e, const REG& dest_src, const REG& src) {
e.adc(dest_src, src);
}, [](X64Emitter& e, const REG& dest_src, int32_t constant) {
e.adc(dest_src, constant);
});
if (i.instr->flags & ARITHMETIC_SET_CARRY) {
// CF is set if carried.
e.StoreEflags();