Messing with flags. subficx sometimes still wrong.
This commit is contained in:
parent
62ced2742e
commit
53d4cbf2c5
|
@ -113,13 +113,6 @@ uint64_t LoadClock(void* raw_context) {
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallNative(X64Emitter& e, void* target) {
|
|
||||||
e.mov(e.rax, (uint64_t)target);
|
|
||||||
e.call(e.rax);
|
|
||||||
e.mov(e.rcx, e.qword[e.rsp + 0]);
|
|
||||||
e.mov(e.rdx, e.qword[e.rcx + 8]); // membase
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(benvanik): fancy stuff.
|
// TODO(benvanik): fancy stuff.
|
||||||
void* ResolveFunctionSymbol(void* raw_context, FunctionInfo* symbol_info) {
|
void* ResolveFunctionSymbol(void* raw_context, FunctionInfo* symbol_info) {
|
||||||
// TODO(benvanik): generate this thunk at runtime? or a shim?
|
// TODO(benvanik): generate this thunk at runtime? or a shim?
|
||||||
|
@ -1161,6 +1154,8 @@ table->AddSequence(OPCODE_STORE, [](X64Emitter& e, Instr*& i) {
|
||||||
// eh?
|
// eh?
|
||||||
e.bswap(e.r8);
|
e.bswap(e.r8);
|
||||||
CallNative(e, cbs->write);
|
CallNative(e, cbs->write);
|
||||||
|
i = e.Advance(i);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
cbs = cbs->next;
|
cbs = cbs->next;
|
||||||
}
|
}
|
||||||
|
@ -1534,6 +1529,7 @@ table->AddSequence(OPCODE_COMPARE_UGE, [](X64Emitter& e, Instr*& i) {
|
||||||
table->AddSequence(OPCODE_DID_CARRY, [](X64Emitter& e, Instr*& i) {
|
table->AddSequence(OPCODE_DID_CARRY, [](X64Emitter& e, Instr*& i) {
|
||||||
Reg8 dest;
|
Reg8 dest;
|
||||||
e.BeginOp(i->dest, dest, REG_DEST);
|
e.BeginOp(i->dest, dest, REG_DEST);
|
||||||
|
LoadEflags(e);
|
||||||
e.setc(dest);
|
e.setc(dest);
|
||||||
e.EndOp(dest);
|
e.EndOp(dest);
|
||||||
i = e.Advance(i);
|
i = e.Advance(i);
|
||||||
|
@ -1543,6 +1539,7 @@ table->AddSequence(OPCODE_DID_CARRY, [](X64Emitter& e, Instr*& i) {
|
||||||
table->AddSequence(OPCODE_DID_OVERFLOW, [](X64Emitter& e, Instr*& i) {
|
table->AddSequence(OPCODE_DID_OVERFLOW, [](X64Emitter& e, Instr*& i) {
|
||||||
Reg8 dest;
|
Reg8 dest;
|
||||||
e.BeginOp(i->dest, dest, REG_DEST);
|
e.BeginOp(i->dest, dest, REG_DEST);
|
||||||
|
LoadEflags(e);
|
||||||
e.seto(dest);
|
e.seto(dest);
|
||||||
e.EndOp(dest);
|
e.EndOp(dest);
|
||||||
i = e.Advance(i);
|
i = e.Advance(i);
|
||||||
|
|
|
@ -17,6 +17,30 @@ namespace {
|
||||||
#define LIKE_REG(dest, like) Reg(dest.getIdx(), dest.getKind(), like.getBit(), false)
|
#define LIKE_REG(dest, like) Reg(dest.getIdx(), dest.getKind(), like.getBit(), false)
|
||||||
#define NAX_LIKE(like) Reg(e.rax.getIdx(), e.rax.getKind(), like.getBit(), false)
|
#define NAX_LIKE(like) Reg(e.rax.getIdx(), e.rax.getKind(), like.getBit(), false)
|
||||||
|
|
||||||
|
// If we are running with tracing on we have to store the EFLAGS in the stack,
|
||||||
|
// otherwise our calls out to C to print will clear it before DID_CARRY/etc
|
||||||
|
// can get the value.
|
||||||
|
#define STORE_EFLAGS 1
|
||||||
|
|
||||||
|
void LoadEflags(X64Emitter& e) {
|
||||||
|
#if STORE_EFLAGS
|
||||||
|
e.mov(e.eax, e.dword[e.rsp + 40]);
|
||||||
|
e.push(e.ax);
|
||||||
|
e.popf();
|
||||||
|
#else
|
||||||
|
// EFLAGS already present.
|
||||||
|
#endif // STORE_EFLAGS
|
||||||
|
}
|
||||||
|
void StoreEflags(X64Emitter& e) {
|
||||||
|
#if STORE_EFLAGS
|
||||||
|
e.pushf();
|
||||||
|
e.pop(e.word[e.rsp + 40]);
|
||||||
|
#else
|
||||||
|
// EFLAGS should have CA set?
|
||||||
|
// (so long as we don't fuck with it)
|
||||||
|
#endif // STORE_EFLAGS
|
||||||
|
}
|
||||||
|
|
||||||
Address Stash(X64Emitter& e, const Xmm& r) {
|
Address Stash(X64Emitter& e, const Xmm& r) {
|
||||||
// TODO(benvanik): ensure aligned.
|
// TODO(benvanik): ensure aligned.
|
||||||
auto addr = e.ptr[e.rsp + 48];
|
auto addr = e.ptr[e.rsp + 48];
|
||||||
|
@ -39,6 +63,15 @@ void MovMem64(X64Emitter& e, RegExp& addr, uint64_t v) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CallNative(X64Emitter& e, void* target) {
|
||||||
|
e.sub(e.rsp, 0x18);
|
||||||
|
e.mov(e.rax, (uint64_t)target);
|
||||||
|
e.call(e.rax);
|
||||||
|
e.mov(e.rcx, e.qword[e.rsp + 0]);
|
||||||
|
e.mov(e.rdx, e.qword[e.rcx + 8]); // membase
|
||||||
|
e.add(e.rsp, 0x18);
|
||||||
|
}
|
||||||
|
|
||||||
// Sets EFLAGs with zf for the given value.
|
// Sets EFLAGs with zf for the given value.
|
||||||
// ZF = 1 if false, 0 = true (so jz = jump if false)
|
// ZF = 1 if false, 0 = true (so jz = jump if false)
|
||||||
void CheckBoolean(X64Emitter& e, Value* v) {
|
void CheckBoolean(X64Emitter& e, Value* v) {
|
||||||
|
@ -421,9 +454,7 @@ void IntUnaryOp(X64Emitter& e, Instr*& i, v_fn v_fn) {
|
||||||
ASSERT_INVALID_TYPE();
|
ASSERT_INVALID_TYPE();
|
||||||
}
|
}
|
||||||
if (i->flags & ARITHMETIC_SET_CARRY) {
|
if (i->flags & ARITHMETIC_SET_CARRY) {
|
||||||
// EFLAGS should have CA set?
|
StoreEflags(e);
|
||||||
// (so long as we don't fuck with it)
|
|
||||||
// UNIMPLEMENTED_SEQ();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -598,9 +629,7 @@ void IntBinaryOp(X64Emitter& e, Instr*& i, vv_fn vv_fn, vc_fn vc_fn) {
|
||||||
ASSERT_INVALID_TYPE();
|
ASSERT_INVALID_TYPE();
|
||||||
}
|
}
|
||||||
if (i->flags & ARITHMETIC_SET_CARRY) {
|
if (i->flags & ARITHMETIC_SET_CARRY) {
|
||||||
// EFLAGS should have CA set?
|
StoreEflags(e);
|
||||||
// (so long as we don't fuck with it)
|
|
||||||
// UNIMPLEMENTED_SEQ();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -777,9 +806,7 @@ void IntTernaryOp(X64Emitter& e, Instr*& i, vvv_fn vvv_fn, vvc_fn vvc_fn, vcv_fn
|
||||||
ASSERT_INVALID_TYPE();
|
ASSERT_INVALID_TYPE();
|
||||||
}
|
}
|
||||||
if (i->flags & ARITHMETIC_SET_CARRY) {
|
if (i->flags & ARITHMETIC_SET_CARRY) {
|
||||||
// EFLAGS should have CA set?
|
StoreEflags(e);
|
||||||
// (so long as we don't fuck with it)
|
|
||||||
// UNIMPLEMENTED_SEQ();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -946,9 +973,7 @@ void XmmBinaryOp(X64Emitter& e, Instr*& i, uint32_t flags, xmm_vv_fn vv_fn) {
|
||||||
ASSERT_INVALID_TYPE();
|
ASSERT_INVALID_TYPE();
|
||||||
}
|
}
|
||||||
if (flags & ARITHMETIC_SET_CARRY) {
|
if (flags & ARITHMETIC_SET_CARRY) {
|
||||||
// EFLAGS should have CA set?
|
StoreEflags(e);
|
||||||
// (so long as we don't fuck with it)
|
|
||||||
// UNIMPLEMENTED_SEQ();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -992,9 +1017,7 @@ void XmmTernaryOp(X64Emitter& e, Instr*& i, uint32_t flags, xmm_vvv_fn vvv_fn) {
|
||||||
ASSERT_INVALID_TYPE();
|
ASSERT_INVALID_TYPE();
|
||||||
}
|
}
|
||||||
if (flags & ARITHMETIC_SET_CARRY) {
|
if (flags & ARITHMETIC_SET_CARRY) {
|
||||||
// EFLAGS should have CA set?
|
StoreEflags(e);
|
||||||
// (so long as we don't fuck with it)
|
|
||||||
// UNIMPLEMENTED_SEQ();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue