Attempting to inline a lot of MMIO operations. Works for GPU stuff mainly.

This commit is contained in:
Ben Vanik
2015-06-02 20:15:43 -07:00
parent 6618bcf2db
commit 40a6a12800
15 changed files with 199 additions and 22 deletions

View File

@@ -481,9 +481,10 @@ void X64Emitter::CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0),
void X64Emitter::CallNativeSafe(void* fn) {
// rcx = context
// rdx = target host function
// rdx = target function
// r8 = arg0
// r9 = arg1
// r10 = arg2
mov(rdx, reinterpret_cast<uint64_t>(fn));
auto thunk = backend()->guest_to_host_thunk();
mov(rax, reinterpret_cast<uint64_t>(thunk));

View File

@@ -1425,6 +1425,68 @@ EMITTER_OPCODE_TABLE(
STORE_CONTEXT_V128);
// ============================================================================
// OPCODE_LOAD_MMIO
// ============================================================================
// Note: all types are always aligned in the context.
EMITTER(LOAD_MMIO_I32, MATCH(I<OPCODE_LOAD_MMIO, I32<>, OffsetOp, OffsetOp>)) {
static void Emit(X64Emitter& e, const EmitArgType& i) {
// uint64_t (context, addr)
auto mmio_range = reinterpret_cast<MMIORange*>(i.src1.value);
auto read_address = uint32_t(i.src2.value);
e.mov(e.r8, uint64_t(mmio_range->callback_context));
e.mov(e.r9d, read_address);
e.CallNativeSafe(mmio_range->read);
e.bswap(e.eax);
e.mov(i.dest, e.eax);
if (IsTracingData()) {
e.mov(e.r8, i.dest);
e.mov(e.edx, read_address);
e.CallNative(reinterpret_cast<void*>(TraceContextLoadI32));
}
}
};
EMITTER_OPCODE_TABLE(
OPCODE_LOAD_MMIO,
LOAD_MMIO_I32);
// ============================================================================
// OPCODE_STORE_MMIO
// ============================================================================
// Note: all types are always aligned on the stack.
EMITTER(STORE_MMIO_I32, MATCH(I<OPCODE_STORE_MMIO, VoidOp, OffsetOp, OffsetOp, I32<>>)) {
static void Emit(X64Emitter& e, const EmitArgType& i) {
// void (context, addr, value)
auto mmio_range = reinterpret_cast<MMIORange*>(i.src1.value);
auto write_address = uint32_t(i.src2.value);
e.mov(e.r8, uint64_t(mmio_range->callback_context));
e.mov(e.r9d, write_address);
if (i.src3.is_constant) {
e.mov(e.r10d, xe::byte_swap(i.src3.constant()));
} else {
e.mov(e.r10d, i.src3);
e.bswap(e.r10d);
}
e.CallNativeSafe(mmio_range->write);
if (IsTracingData()) {
if (i.src3.is_constant) {
e.mov(e.r8d, i.src3.constant());
} else {
e.mov(e.r8d, i.src3);
}
e.mov(e.edx, write_address);
e.CallNative(reinterpret_cast<void*>(TraceContextStoreI32));
}
}
};
EMITTER_OPCODE_TABLE(
OPCODE_STORE_MMIO,
STORE_MMIO_I32);
// ============================================================================
// OPCODE_LOAD
// ============================================================================
@@ -6374,6 +6436,8 @@ void RegisterSequences() {
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_STORE_LOCAL);
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_LOAD_CONTEXT);
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_STORE_CONTEXT);
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_LOAD_MMIO);
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_STORE_MMIO);
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_LOAD);
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_STORE);
REGISTER_EMITTER_OPCODE_TABLE(OPCODE_MEMSET);

View File

@@ -97,6 +97,7 @@ GuestToHostThunk X64ThunkEmitter::EmitGuestToHostThunk() {
// rdx = target function
// r8 = arg0
// r9 = arg1
// r10 = arg2
const size_t stack_size = StackLayout::THUNK_STACK_SIZE;
// rsp + 0 = return address