Replacing DidCarry with manual calculation and fixing compares.

This commit is contained in:
Ben Vanik
2015-06-06 15:24:46 -07:00
parent 6b52f6715a
commit 429698c2ec
14 changed files with 156 additions and 428 deletions

View File

@@ -2404,14 +2404,14 @@ EMITTER_OPCODE_TABLE(
COMPARE_##op##_I16, \
COMPARE_##op##_I32, \
COMPARE_##op##_I64);
EMITTER_ASSOCIATIVE_COMPARE_XX(SLT, setl, setge);
EMITTER_ASSOCIATIVE_COMPARE_XX(SLE, setle, setg);
EMITTER_ASSOCIATIVE_COMPARE_XX(SGT, setg, setle);
EMITTER_ASSOCIATIVE_COMPARE_XX(SGE, setge, setl);
EMITTER_ASSOCIATIVE_COMPARE_XX(ULT, setb, setae);
EMITTER_ASSOCIATIVE_COMPARE_XX(ULE, setbe, seta);
EMITTER_ASSOCIATIVE_COMPARE_XX(UGT, seta, setbe);
EMITTER_ASSOCIATIVE_COMPARE_XX(UGE, setae, setb);
EMITTER_ASSOCIATIVE_COMPARE_XX(SLT, setl, setg);
EMITTER_ASSOCIATIVE_COMPARE_XX(SLE, setle, setge);
EMITTER_ASSOCIATIVE_COMPARE_XX(SGT, setg, setl);
EMITTER_ASSOCIATIVE_COMPARE_XX(SGE, setge, setle);
EMITTER_ASSOCIATIVE_COMPARE_XX(ULT, setb, seta);
EMITTER_ASSOCIATIVE_COMPARE_XX(ULE, setbe, setae);
EMITTER_ASSOCIATIVE_COMPARE_XX(UGT, seta, setb);
EMITTER_ASSOCIATIVE_COMPARE_XX(UGE, setae, setbe);
// http://x86.renejeschke.de/html/file_module_x86_id_288.html
#define EMITTER_ASSOCIATIVE_COMPARE_FLT_XX(op, instr) \
@@ -2449,61 +2449,6 @@ EMITTER_ASSOCIATIVE_COMPARE_FLT_XX(UGT, seta);
EMITTER_ASSOCIATIVE_COMPARE_FLT_XX(UGE, setae);
// ============================================================================
// OPCODE_DID_CARRY
// ============================================================================
// TODO(benvanik): salc/setalc
// https://code.google.com/p/corkami/wiki/x86oddities
EMITTER(DID_CARRY_I8, MATCH(I<OPCODE_DID_CARRY, I8<>, I8<>>)) {
static void Emit(X64Emitter& e, const EmitArgType& i) {
assert_true(!i.src1.is_constant);
e.LoadEflags();
e.setc(i.dest);
}
};
EMITTER(DID_CARRY_I16, MATCH(I<OPCODE_DID_CARRY, I8<>, I16<>>)) {
static void Emit(X64Emitter& e, const EmitArgType& i) {
assert_true(!i.src1.is_constant);
e.LoadEflags();
e.setc(i.dest);
}
};
EMITTER(DID_CARRY_I32, MATCH(I<OPCODE_DID_CARRY, I8<>, I32<>>)) {
static void Emit(X64Emitter& e, const EmitArgType& i) {
assert_true(!i.src1.is_constant);
e.LoadEflags();
e.setc(i.dest);
}
};
EMITTER(DID_CARRY_I64, MATCH(I<OPCODE_DID_CARRY, I8<>, I64<>>)) {
static void Emit(X64Emitter& e, const EmitArgType& i) {
assert_true(!i.src1.is_constant);
e.LoadEflags();
e.setc(i.dest);
}
};
EMITTER_OPCODE_TABLE(
OPCODE_DID_CARRY,
DID_CARRY_I8,
DID_CARRY_I16,
DID_CARRY_I32,
DID_CARRY_I64);
// ============================================================================
// OPCODE_DID_OVERFLOW
// ============================================================================
EMITTER(DID_OVERFLOW, MATCH(I<OPCODE_DID_OVERFLOW, I8<>>)) {
static void Emit(X64Emitter& e, const EmitArgType& i) {
e.LoadEflags();
e.seto(i.dest);
}
};
EMITTER_OPCODE_TABLE(
OPCODE_DID_OVERFLOW,
DID_OVERFLOW);
// ============================================================================
// OPCODE_DID_SATURATE
// ============================================================================
@@ -2736,10 +2681,6 @@ void EmitAddXX(X64Emitter& e, const ARGS& i) {
e, i,
[](X64Emitter& e, const REG& dest_src, const REG& src) { e.add(dest_src, src); },
[](X64Emitter& e, const REG& dest_src, int32_t constant) { e.add(dest_src, constant); });
if (i.instr->flags & ARITHMETIC_SET_CARRY) {
// CF is set if carried.
e.StoreEflags();
}
}
EMITTER(ADD_I8, MATCH(I<OPCODE_ADD, I8<>, I8<>, I8<>>)) {
static void Emit(X64Emitter& e, const EmitArgType& i) {
@@ -2817,10 +2758,6 @@ void EmitAddCarryXX(X64Emitter& e, const ARGS& i) {
}, [](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();
}
}
EMITTER(ADD_CARRY_I8, MATCH(I<OPCODE_ADD_CARRY, I8<>, I8<>, I8<>, I8<>>)) {
static void Emit(X64Emitter& e, const EmitArgType& i) {
@@ -3009,31 +2946,10 @@ EMITTER_OPCODE_TABLE(
// TODO(benvanik): put dest/src1|2 together.
template <typename SEQ, typename REG, typename ARGS>
void EmitSubXX(X64Emitter& e, const ARGS& i) {
if (i.instr->flags & ARITHMETIC_SET_CARRY) {
// TODO(benvanik): faster way of doing sub with CF set?
SEQ::EmitAssociativeBinaryOp(
e, i,
[](X64Emitter& e, const REG& dest_src, const REG& src) {
auto temp = GetTempReg<REG>(e);
e.mov(temp, src);
e.not(temp);
e.stc();
e.adc(dest_src, temp);
},
[](X64Emitter& e, const REG& dest_src, int32_t constant) {
auto temp = GetTempReg<REG>(e);
e.mov(temp, constant);
e.not(temp);
e.stc();
e.adc(dest_src, temp);
});
e.StoreEflags();
} else {
SEQ::EmitAssociativeBinaryOp(
e, i,
[](X64Emitter& e, const REG& dest_src, const REG& src) { e.sub(dest_src, src); },
[](X64Emitter& e, const REG& dest_src, int32_t constant) { e.sub(dest_src, constant); });
}
SEQ::EmitAssociativeBinaryOp(
e, i,
[](X64Emitter& e, const REG& dest_src, const REG& src) { e.sub(dest_src, src); },
[](X64Emitter& e, const REG& dest_src, int32_t constant) { e.sub(dest_src, constant); });
}
EMITTER(SUB_I8, MATCH(I<OPCODE_SUB, I8<>, I8<>, I8<>>)) {
static void Emit(X64Emitter& e, const EmitArgType& i) {
@@ -6576,8 +6492,6 @@ void RegisterSequences() {
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_COMPARE_ULE_FLT);
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_COMPARE_UGT_FLT);
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_COMPARE_UGE_FLT);
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_DID_CARRY);
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_DID_OVERFLOW);
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_DID_SATURATE);
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_VECTOR_COMPARE_EQ);
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_VECTOR_COMPARE_SGT);