Hacking together proper stack saving. Can't get >128b frames working.

This commit is contained in:
Ben Vanik
2014-01-31 22:16:05 -08:00
parent f85b83709e
commit 009a6d0745
14 changed files with 424 additions and 80 deletions

View File

@@ -9,8 +9,10 @@
#include <alloy/backend/x64/lowering/lowering_sequences.h>
#include <alloy/backend/x64/x64_backend.h>
#include <alloy/backend/x64/x64_emitter.h>
#include <alloy/backend/x64/x64_function.h>
#include <alloy/backend/x64/x64_thunk_emitter.h>
#include <alloy/backend/x64/lowering/lowering_table.h>
#include <alloy/backend/x64/lowering/tracers.h>
#include <alloy/runtime/symbol_info.h>
@@ -44,6 +46,11 @@ namespace {
#define SHUFPS_SWAP_DWORDS 0x1B
// Major templating foo lives in here.
#include <alloy/backend/x64/lowering/op_utils.inl>
enum XmmConst {
XMMZero = 0,
XMMOne = 1,
@@ -156,25 +163,31 @@ void* ResolveFunctionAddress(void* raw_context, uint32_t target_address) {
auto x64_fn = (X64Function*)fn;
return x64_fn->machine_code();
}
void TransitionToHost(X64Emitter& e) {
// Expects:
// rcx = context
// rdx = target host function
// r8 = arg0
// r9 = arg1
// Returns:
// rax = host return
auto thunk = e.backend()->guest_to_host_thunk();
e.mov(e.rax, (uint64_t)thunk);
e.call(e.rax);
}
void IssueCall(X64Emitter& e, FunctionInfo* symbol_info, uint32_t flags) {
auto fn = symbol_info->function();
// Resolve address to the function to call and store in rax.
// TODO(benvanik): caching/etc. For now this makes debugging easier.
e.mov(e.rdx, (uint64_t)symbol_info);
e.mov(e.rax, (uint64_t)ResolveFunctionSymbol);
e.call(e.rax);
e.mov(e.rcx, e.qword[e.rsp + 0]);
e.mov(e.rdx, e.qword[e.rcx + 8]); // membase
CallNative(e, ResolveFunctionSymbol);
// Actually jump/call to rax.
if (flags & CALL_TAIL) {
// TODO(benvanik): adjust stack?
e.add(e.rsp, 72);
e.add(e.rsp, StackLayout::GUEST_STACK_SIZE);
e.jmp(e.rax);
} else {
e.call(e.rax);
e.mov(e.rcx, e.qword[e.rsp + 0]);
e.mov(e.rdx, e.qword[e.rcx + 8]); // membase
}
}
void IssueCallIndirect(X64Emitter& e, Value* target, uint32_t flags) {
@@ -186,30 +199,20 @@ void IssueCallIndirect(X64Emitter& e, Value* target, uint32_t flags) {
e.mov(e.rdx, r);
}
e.EndOp(r);
e.mov(e.rax, (uint64_t)ResolveFunctionAddress);
e.call(e.rax);
e.mov(e.rcx, e.qword[e.rsp + 0]);
e.mov(e.rdx, e.qword[e.rcx + 8]); // membase
CallNative(e, ResolveFunctionAddress);
// Actually jump/call to rax.
if (flags & CALL_TAIL) {
// TODO(benvanik): adjust stack?
e.add(e.rsp, 72);
e.add(e.rsp, StackLayout::GUEST_STACK_SIZE);
e.jmp(e.rax);
} else {
e.call(e.rax);
e.mov(e.rcx, e.qword[e.rsp + 0]);
e.mov(e.rdx, e.qword[e.rcx + 8]); // membase
}
}
} // namespace
// Major templating foo lives in here.
#include <alloy/backend/x64/lowering/op_utils.inl>
void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) {
// --------------------------------------------------------------------------
// General
@@ -337,9 +340,13 @@ table->AddSequence(OPCODE_CALL_EXTERN, [](X64Emitter& e, Instr*& i) {
auto symbol_info = i->src1.symbol_info;
XEASSERT(symbol_info->behavior() == FunctionInfo::BEHAVIOR_EXTERN);
XEASSERTNOTNULL(symbol_info->extern_handler());
e.mov(e.rdx, (uint64_t)symbol_info->extern_arg0());
e.mov(e.r8, (uint64_t)symbol_info->extern_arg1());
CallNative(e, symbol_info->extern_handler());
// rdx = target host function
// r8 = arg0
// r9 = arg1
e.mov(e.rdx, (uint64_t)symbol_info->extern_handler());
e.mov(e.r8, (uint64_t)symbol_info->extern_arg0());
e.mov(e.r9, (uint64_t)symbol_info->extern_arg1());
TransitionToHost(e);
i = e.Advance(i);
return true;
});

View File

@@ -17,7 +17,7 @@ namespace {
#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 STASH_OFFSET 48
#define STASH_OFFSET 0
// 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
@@ -68,7 +68,7 @@ void MovMem64(X64Emitter& e, RegExp& addr, uint64_t v) {
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.rcx, e.qword[e.rsp + StackLayout::RCX_HOME]);
e.mov(e.rdx, e.qword[e.rcx + 8]); // membase
}