[x64] Minor cleanups in emitter

This commit is contained in:
Dr. Chat 2018-11-17 16:06:45 -06:00
parent b2f9d54e7e
commit 4571e8207a
1 changed files with 8 additions and 7 deletions

View File

@ -148,11 +148,13 @@ bool X64Emitter::Emit(HIRBuilder* builder, size_t* out_stack_size) {
for (auto it = locals.begin(); it != locals.end(); ++it) { for (auto it = locals.begin(); it != locals.end(); ++it) {
auto slot = *it; auto slot = *it;
size_t type_size = GetTypeSize(slot->type); size_t type_size = GetTypeSize(slot->type);
// Align to natural size. // Align to natural size.
stack_offset = xe::align(stack_offset, type_size); stack_offset = xe::align(stack_offset, type_size);
slot->set_constant((uint32_t)stack_offset); slot->set_constant((uint32_t)stack_offset);
stack_offset += type_size; stack_offset += type_size;
} }
// Ensure 16b alignment. // Ensure 16b alignment.
stack_offset -= StackLayout::GUEST_STACK_SIZE; stack_offset -= StackLayout::GUEST_STACK_SIZE;
stack_offset = xe::align(stack_offset, static_cast<size_t>(16)); stack_offset = xe::align(stack_offset, static_cast<size_t>(16));
@ -160,7 +162,7 @@ bool X64Emitter::Emit(HIRBuilder* builder, size_t* out_stack_size) {
// Function prolog. // Function prolog.
// Must be 16b aligned. // Must be 16b aligned.
// Windows is very strict about the form of this and the epilog: // Windows is very strict about the form of this and the epilog:
// https://msdn.microsoft.com/en-us/library/tawsa7cb.aspx // https://docs.microsoft.com/en-us/cpp/build/prolog-and-epilog?view=vs-2017
// IMPORTANT: any changes to the prolog must be kept in sync with // IMPORTANT: any changes to the prolog must be kept in sync with
// X64CodeCache, which dynamically generates exception information. // X64CodeCache, which dynamically generates exception information.
// Adding or changing anything here must be matched! // Adding or changing anything here must be matched!
@ -168,6 +170,7 @@ bool X64Emitter::Emit(HIRBuilder* builder, size_t* out_stack_size) {
assert_true((stack_size + 8) % 16 == 0); assert_true((stack_size + 8) % 16 == 0);
*out_stack_size = stack_size; *out_stack_size = stack_size;
stack_size_ = stack_size; stack_size_ = stack_size;
sub(rsp, (uint32_t)stack_size); sub(rsp, (uint32_t)stack_size);
mov(qword[rsp + StackLayout::GUEST_CTX_HOME], GetContextReg()); mov(qword[rsp + StackLayout::GUEST_CTX_HOME], GetContextReg());
mov(qword[rsp + StackLayout::GUEST_RET_ADDR], rcx); mov(qword[rsp + StackLayout::GUEST_RET_ADDR], rcx);
@ -340,13 +343,14 @@ void X64Emitter::UnimplementedInstr(const hir::Instr* i) {
// This is used by the X64ThunkEmitter's ResolveFunctionThunk. // This is used by the X64ThunkEmitter's ResolveFunctionThunk.
extern "C" uint64_t ResolveFunction(void* raw_context, extern "C" uint64_t ResolveFunction(void* raw_context,
uint32_t target_address) { uint64_t target_address) {
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context); auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
// TODO(benvanik): required? // TODO(benvanik): required?
assert_not_zero(target_address); assert_not_zero(target_address);
auto fn = thread_state->processor()->ResolveFunction(target_address); auto fn =
thread_state->processor()->ResolveFunction((uint32_t)target_address);
assert_not_null(fn); assert_not_null(fn);
auto x64_fn = static_cast<X64Function*>(fn); auto x64_fn = static_cast<X64Function*>(fn);
uint64_t addr = reinterpret_cast<uint64_t>(x64_fn->machine_code()); uint64_t addr = reinterpret_cast<uint64_t>(x64_fn->machine_code());
@ -373,10 +377,7 @@ void X64Emitter::Call(const hir::Instr* instr, GuestFunction* function) {
// Old-style resolve. // Old-style resolve.
// Not too important because indirection table is almost always available. // Not too important because indirection table is almost always available.
// TODO: Overwrite the call-site with a straight call. // TODO: Overwrite the call-site with a straight call.
mov(rax, reinterpret_cast<uint64_t>(ResolveFunction)); CallNative(&ResolveFunction, function->address());
mov(rcx, GetContextReg());
mov(rdx, function->address());
call(rax);
} }
// Actually jump/call to rax. // Actually jump/call to rax.