Removing IVM.

This commit is contained in:
Ben Vanik 2015-01-19 12:35:43 -08:00
parent 056d4ed9b0
commit b8bb338564
23 changed files with 3 additions and 5178 deletions

View File

@ -26,5 +26,4 @@ A backend takes optimized IR and assembles an implementation-specific result.
The backend is also responsible for executing the code it generates and supporting The backend is also responsible for executing the code it generates and supporting
debugging features (such as breakpoints). debugging features (such as breakpoints).
* IVM: bytecode interpreter
* x64: IA-64 with AVX2 code generator * x64: IA-64 with AVX2 code generator

View File

@ -1,124 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <alloy/backend/ivm/ivm_assembler.h>
#include <alloy/reset_scope.h>
#include <alloy/backend/backend.h>
#include <alloy/backend/ivm/ivm_intcode.h>
#include <alloy/backend/ivm/ivm_function.h>
#include <alloy/hir/hir_builder.h>
#include <alloy/hir/label.h>
#include <alloy/runtime/runtime.h>
#include <xenia/profiling.h>
namespace alloy {
namespace backend {
namespace ivm {
using alloy::hir::HIRBuilder;
using alloy::runtime::DebugInfo;
using alloy::runtime::Function;
using alloy::runtime::FunctionInfo;
IVMAssembler::IVMAssembler(Backend* backend)
: Assembler(backend), source_map_arena_(128 * 1024) {}
IVMAssembler::~IVMAssembler() = default;
int IVMAssembler::Initialize() {
int result = Assembler::Initialize();
if (result) {
return result;
}
return result;
}
void IVMAssembler::Reset() {
intcode_arena_.Reset();
source_map_arena_.Reset();
scratch_arena_.Reset();
Assembler::Reset();
}
int IVMAssembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
uint32_t debug_info_flags,
std::unique_ptr<DebugInfo> debug_info,
uint32_t trace_flags, Function** out_function) {
SCOPE_profile_cpu_f("alloy");
// Reset when we leave.
make_reset_scope(this);
IVMFunction* fn = new IVMFunction(symbol_info);
fn->set_debug_info(std::move(debug_info));
TranslationContext ctx;
ctx.register_count = 0;
ctx.intcode_count = 0;
ctx.intcode_arena = &intcode_arena_;
ctx.source_map_count = 0;
ctx.source_map_arena = &source_map_arena_;
ctx.scratch_arena = &scratch_arena_;
ctx.label_ref_head = NULL;
// Reset label tags as we use them.
builder->ResetLabelTags();
// Function prologue.
size_t stack_offset = 0;
auto locals = builder->locals();
for (auto it = locals.begin(); it != locals.end(); ++it) {
auto slot = *it;
size_t type_size = GetTypeSize(slot->type);
// Align to natural size.
stack_offset = poly::align(stack_offset, type_size);
slot->set_constant((uint32_t)stack_offset);
stack_offset += type_size;
}
// Ensure 16b alignment.
stack_offset = poly::align(stack_offset, static_cast<size_t>(16));
ctx.stack_size = stack_offset;
auto block = builder->first_block();
while (block) {
auto label = block->label_head;
while (label) {
label->tag = (void*)(0x80000000 | ctx.intcode_count);
label = label->next;
}
auto i = block->instr_head;
while (i) {
TranslateIntCodes(ctx, i);
i = i->next;
}
block = block->next;
}
// Function epilogue.
// Fixup label references.
LabelRef* label_ref = ctx.label_ref_head;
while (label_ref) {
label_ref->instr->src1_reg =
(uint32_t)(intptr_t)label_ref->label->tag & ~0x80000000;
label_ref = label_ref->next;
}
fn->Setup(ctx);
*out_function = fn;
return 0;
}
} // namespace ivm
} // namespace backend
} // namespace alloy

View File

@ -1,44 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef ALLOY_BACKEND_IVM_IVM_ASSEMBLER_H_
#define ALLOY_BACKEND_IVM_IVM_ASSEMBLER_H_
#include <alloy/arena.h>
#include <alloy/backend/assembler.h>
namespace alloy {
namespace backend {
namespace ivm {
class IVMAssembler : public Assembler {
public:
IVMAssembler(Backend* backend);
~IVMAssembler() override;
int Initialize() override;
void Reset() override;
int Assemble(runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder,
uint32_t debug_info_flags,
std::unique_ptr<runtime::DebugInfo> debug_info,
uint32_t trace_flags, runtime::Function** out_function) override;
private:
Arena intcode_arena_;
Arena source_map_arena_;
Arena scratch_arena_;
};
} // namespace ivm
} // namespace backend
} // namespace alloy
#endif // ALLOY_BACKEND_IVM_IVM_ASSEMBLER_H_

View File

@ -1,56 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <alloy/backend/ivm/ivm_backend.h>
#include <alloy/backend/ivm/ivm_assembler.h>
#include <alloy/backend/ivm/ivm_stack.h>
namespace alloy {
namespace backend {
namespace ivm {
using alloy::runtime::Runtime;
IVMBackend::IVMBackend(Runtime* runtime) : Backend(runtime) {}
IVMBackend::~IVMBackend() = default;
int IVMBackend::Initialize() {
int result = Backend::Initialize();
if (result) {
return result;
}
machine_info_.register_sets[0] = {
0, "gpr", MachineInfo::RegisterSet::INT_TYPES, 16,
};
machine_info_.register_sets[1] = {
1, "vec", MachineInfo::RegisterSet::FLOAT_TYPES |
MachineInfo::RegisterSet::VEC_TYPES,
16,
};
return result;
}
void* IVMBackend::AllocThreadData() { return new IVMStack(); }
void IVMBackend::FreeThreadData(void* thread_data) {
auto stack = (IVMStack*)thread_data;
delete stack;
}
std::unique_ptr<Assembler> IVMBackend::CreateAssembler() {
return std::make_unique<IVMAssembler>(this);
}
} // namespace ivm
} // namespace backend
} // namespace alloy

View File

@ -1,38 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef ALLOY_BACKEND_IVM_IVM_BACKEND_H_
#define ALLOY_BACKEND_IVM_IVM_BACKEND_H_
#include <alloy/backend/backend.h>
namespace alloy {
namespace backend {
namespace ivm {
#define ALLOY_HAS_IVM_BACKEND 1
class IVMBackend : public Backend {
public:
IVMBackend(runtime::Runtime* runtime);
~IVMBackend() override;
int Initialize() override;
void* AllocThreadData() override;
void FreeThreadData(void* thread_data) override;
std::unique_ptr<Assembler> CreateAssembler() override;
};
} // namespace ivm
} // namespace backend
} // namespace alloy
#endif // ALLOY_BACKEND_IVM_IVM_BACKEND_H_

View File

@ -1,176 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <alloy/backend/ivm/ivm_function.h>
#include <alloy/backend/ivm/ivm_stack.h>
#include <alloy/runtime/runtime.h>
#include <alloy/runtime/thread_state.h>
namespace alloy {
namespace backend {
namespace ivm {
using alloy::runtime::Breakpoint;
using alloy::runtime::FunctionInfo;
using alloy::runtime::ThreadState;
IVMFunction::IVMFunction(FunctionInfo* symbol_info)
: Function(symbol_info),
register_count_(0),
intcode_count_(0),
intcodes_(nullptr),
source_map_count_(0),
source_map_(nullptr) {}
IVMFunction::~IVMFunction() {
free(intcodes_);
free(source_map_);
}
void IVMFunction::Setup(TranslationContext& ctx) {
register_count_ = ctx.register_count;
stack_size_ = ctx.stack_size;
intcode_count_ = ctx.intcode_count;
intcodes_ = (IntCode*)ctx.intcode_arena->CloneContents();
source_map_count_ = ctx.source_map_count;
source_map_ = (SourceMapEntry*)ctx.source_map_arena->CloneContents();
}
IntCode* IVMFunction::GetIntCodeAtSourceOffset(uint64_t offset) {
for (size_t n = 0; n < source_map_count_; n++) {
auto entry = &source_map_[n];
if (entry->source_offset == offset) {
return &intcodes_[entry->intcode_index];
}
}
return NULL;
}
int IVMFunction::AddBreakpointImpl(Breakpoint* breakpoint) {
auto i = GetIntCodeAtSourceOffset(breakpoint->address());
if (!i) {
return 1;
}
// TEMP breakpoints always overwrite normal ones.
if (!i->debug_flags || breakpoint->type() == Breakpoint::TEMP_TYPE) {
uint64_t breakpoint_ptr = (uint64_t)breakpoint;
i->src2_reg = (uint32_t)breakpoint_ptr;
i->src3_reg = (uint32_t)(breakpoint_ptr >> 32);
}
// Increment breakpoint counter.
++i->debug_flags;
return 0;
}
int IVMFunction::RemoveBreakpointImpl(Breakpoint* breakpoint) {
auto i = GetIntCodeAtSourceOffset(breakpoint->address());
if (!i) {
return 1;
}
// Decrement breakpoint counter.
--i->debug_flags;
i->src2_reg = i->src3_reg = 0;
// If there were other breakpoints, see what they were.
if (i->debug_flags) {
auto old_breakpoint = FindBreakpoint(breakpoint->address());
if (old_breakpoint) {
uint64_t breakpoint_ptr = (uint64_t)old_breakpoint;
i->src2_reg = (uint32_t)breakpoint_ptr;
i->src3_reg = (uint32_t)(breakpoint_ptr >> 32);
}
}
return 0;
}
void IVMFunction::OnBreakpointHit(ThreadState* thread_state, IntCode* i) {
uint64_t breakpoint_ptr = i->src2_reg | (uint64_t(i->src3_reg) << 32);
Breakpoint* breakpoint = (Breakpoint*)breakpoint_ptr;
// Notify debugger.
// The debugger may choose to wait (blocking us).
auto debugger = thread_state->runtime()->debugger();
debugger->OnBreakpointHit(thread_state, breakpoint);
}
#undef TRACE_SOURCE_OFFSET
int IVMFunction::CallImpl(ThreadState* thread_state, uint64_t return_address) {
// Setup register file on stack.
auto stack = (IVMStack*)thread_state->backend_data();
auto register_file = (Register*)stack->Alloc(register_count_);
auto local_stack = (uint8_t*)alloca(stack_size_);
Memory* memory = thread_state->memory();
IntCodeState ics;
ics.rf = register_file;
ics.locals = local_stack;
ics.context = (uint8_t*)thread_state->raw_context();
ics.membase = memory->membase();
ics.did_carry = 0;
ics.did_saturate = 0;
ics.thread_state = thread_state;
ics.return_address = return_address;
ics.call_return_address = 0;
// TODO(benvanik): DID_CARRY -- need HIR to set a OPCODE_FLAG_SET_CARRY
// or something so the fns can set an ics flag.
#ifdef TRACE_SOURCE_OFFSET
size_t source_index = 0;
#endif
uint32_t ia = 0;
while (true) {
#ifdef TRACE_SOURCE_OFFSET
uint64_t source_offset = -1;
if (source_index < this->source_map_count_ &&
this->source_map_[source_index].intcode_index <= ia) {
while (source_index + 1 < this->source_map_count_ &&
this->source_map_[source_index + 1].intcode_index <= ia) {
source_index++;
}
source_offset = this->source_map_[source_index].source_offset;
}
#endif
IntCode* i = &intcodes_[ia];
if (i->debug_flags) {
OnBreakpointHit(thread_state, i);
}
uint32_t new_ia = i->intcode_fn(ics, i);
if (new_ia == IA_NEXT) {
ia++;
} else if (new_ia == IA_RETURN) {
break;
} else {
ia = new_ia;
#ifdef TRACE_SOURCE_OFFSET
source_index = 0;
#endif
}
}
stack->Free(register_count_);
return 0;
}
} // namespace ivm
} // namespace backend
} // namespace alloy

View File

@ -1,51 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef ALLOY_BACKEND_IVM_IVM_FUNCTION_H_
#define ALLOY_BACKEND_IVM_IVM_FUNCTION_H_
#include <alloy/backend/ivm/ivm_intcode.h>
#include <alloy/runtime/function.h>
#include <alloy/runtime/symbol_info.h>
namespace alloy {
namespace backend {
namespace ivm {
class IVMFunction : public runtime::Function {
public:
IVMFunction(runtime::FunctionInfo* symbol_info);
virtual ~IVMFunction();
void Setup(TranslationContext& ctx);
protected:
virtual int AddBreakpointImpl(runtime::Breakpoint* breakpoint);
virtual int RemoveBreakpointImpl(runtime::Breakpoint* breakpoint);
virtual int CallImpl(runtime::ThreadState* thread_state,
uint64_t return_address);
private:
IntCode* GetIntCodeAtSourceOffset(uint64_t offset);
void OnBreakpointHit(runtime::ThreadState* thread_state, IntCode* i);
private:
size_t register_count_;
size_t stack_size_;
size_t intcode_count_;
IntCode* intcodes_;
size_t source_map_count_;
SourceMapEntry* source_map_;
};
} // namespace ivm
} // namespace backend
} // namespace alloy
#endif // ALLOY_BACKEND_IVM_IVM_FUNCTION_H_

File diff suppressed because it is too large Load Diff

View File

@ -1,107 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef ALLOY_BACKEND_IVM_INTCODE_H_
#define ALLOY_BACKEND_IVM_INTCODE_H_
#include <alloy/hir/instr.h>
#include <alloy/hir/opcodes.h>
namespace alloy {
namespace runtime {
class ThreadState;
} // namespace runtime
} // namespace alloy
namespace alloy {
namespace backend {
namespace ivm {
typedef union {
int8_t i8;
uint8_t u8;
int16_t i16;
uint16_t u16;
int32_t i32;
uint32_t u32;
int64_t i64;
uint64_t u64;
float f32;
double f64;
vec128_t v128;
} Register;
typedef struct {
Register* rf;
uint8_t* locals;
uint8_t* context;
uint8_t* membase;
int8_t did_carry;
int8_t did_saturate;
runtime::ThreadState* thread_state;
uint64_t return_address;
uint64_t call_return_address;
} IntCodeState;
struct IntCode_s;
typedef uint32_t (*IntCodeFn)(IntCodeState& ics, const struct IntCode_s* i);
#define IA_RETURN 0xA0000000
#define IA_NEXT 0xB0000000
typedef struct IntCode_s {
IntCodeFn intcode_fn;
uint16_t flags;
uint16_t debug_flags;
uint32_t dest_reg;
union {
struct {
uint32_t src1_reg;
uint32_t src2_reg;
uint32_t src3_reg;
// <4 bytes available>
};
struct {
Register constant;
};
};
// debugging info/etc
} IntCode;
typedef struct LabelRef_s {
hir::Label* label;
IntCode* instr;
LabelRef_s* next;
} LabelRef;
typedef struct SourceMapEntry_s {
uint64_t source_offset;
uint64_t intcode_index;
} SourceMapEntry;
typedef struct {
uint32_t register_count;
size_t intcode_count;
Arena* intcode_arena;
size_t source_map_count;
Arena* source_map_arena;
Arena* scratch_arena;
LabelRef* label_ref_head;
size_t stack_size;
} TranslationContext;
int TranslateIntCodes(TranslationContext& ctx, hir::Instr* i);
} // namespace ivm
} // namespace backend
} // namespace alloy
#endif // ALLOY_BACKEND_IVM_INTCODE_H_

View File

@ -1,79 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <alloy/backend/ivm/ivm_stack.h>
namespace alloy {
namespace backend {
namespace ivm {
IVMStack::IVMStack()
: chunk_size_(2 * 1024 * 1024), head_chunk_(NULL), active_chunk_(NULL) {}
IVMStack::~IVMStack() {
Chunk* chunk = head_chunk_;
while (chunk) {
Chunk* next = chunk->next;
delete chunk;
chunk = next;
}
head_chunk_ = NULL;
}
Register* IVMStack::Alloc(size_t register_count) {
size_t size = register_count * sizeof(Register);
if (active_chunk_) {
if (active_chunk_->capacity - active_chunk_->offset < size) {
Chunk* next = active_chunk_->next;
if (!next) {
assert_true(size < chunk_size_, "need to support larger chunks");
next = new Chunk(chunk_size_);
next->prev = active_chunk_;
active_chunk_->next = next;
}
next->offset = 0;
active_chunk_ = next;
}
} else {
head_chunk_ = active_chunk_ = new Chunk(chunk_size_);
}
uint8_t* p = active_chunk_->buffer + active_chunk_->offset;
active_chunk_->offset += size;
return (Register*)p;
}
void IVMStack::Free(size_t register_count) {
size_t size = register_count * sizeof(Register);
if (active_chunk_->offset == size) {
// Moving back a chunk.
active_chunk_->offset = 0;
if (active_chunk_->prev) {
active_chunk_ = active_chunk_->prev;
}
} else {
// Still in same chunk.
active_chunk_->offset -= size;
}
}
IVMStack::Chunk::Chunk(size_t chunk_size)
: prev(NULL), next(NULL), capacity(chunk_size), buffer(0), offset(0) {
buffer = reinterpret_cast<uint8_t*>(malloc(capacity));
}
IVMStack::Chunk::~Chunk() {
if (buffer) {
free(buffer);
}
}
} // namespace ivm
} // namespace backend
} // namespace alloy

View File

@ -1,51 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef ALLOY_BACKEND_IVM_IVM_STACK_H_
#define ALLOY_BACKEND_IVM_IVM_STACK_H_
#include <alloy/backend/ivm/ivm_intcode.h>
namespace alloy {
namespace backend {
namespace ivm {
class IVMStack {
public:
IVMStack();
~IVMStack();
Register* Alloc(size_t register_count);
void Free(size_t register_count);
private:
class Chunk {
public:
Chunk(size_t chunk_size);
~Chunk();
Chunk* prev;
Chunk* next;
size_t capacity;
uint8_t* buffer;
size_t offset;
};
private:
size_t chunk_size_;
Chunk* head_chunk_;
Chunk* active_chunk_;
};
} // namespace ivm
} // namespace backend
} // namespace alloy
#endif // ALLOY_BACKEND_IVM_IVM_STACK_H_

View File

@ -1,15 +0,0 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'sources': [
'ivm_intcode.cc',
'ivm_intcode.h',
'ivm_assembler.cc',
'ivm_assembler.h',
'ivm_backend.cc',
'ivm_backend.h',
'ivm_function.cc',
'ivm_function.h',
'ivm_stack.cc',
'ivm_stack.h',
],
}

View File

@ -9,7 +9,6 @@
], ],
'includes': [ 'includes': [
'ivm/sources.gypi',
'x64/sources.gypi', 'x64/sources.gypi',
], ],
} }

View File

@ -8,7 +8,6 @@
*/ */
#include <alloy/alloy.h> #include <alloy/alloy.h>
#include <alloy/backend/ivm/ivm_backend.h>
#include <alloy/backend/x64/x64_backend.h> #include <alloy/backend/x64/x64_backend.h>
#include <alloy/frontend/ppc/ppc_context.h> #include <alloy/frontend/ppc/ppc_context.h>
#include <alloy/frontend/ppc/ppc_frontend.h> #include <alloy/frontend/ppc/ppc_frontend.h>

View File

@ -73,36 +73,4 @@ SimpleMemory::SimpleMemory(size_t capacity) : memory_(capacity) {
SimpleMemory::~SimpleMemory() = default; SimpleMemory::~SimpleMemory() = default;
uint8_t SimpleMemory::LoadI8(uint64_t address) {
return poly::load<uint8_t>(membase_ + address);
}
uint16_t SimpleMemory::LoadI16(uint64_t address) {
return poly::load<uint16_t>(membase_ + address);
}
uint32_t SimpleMemory::LoadI32(uint64_t address) {
return poly::load<uint32_t>(membase_ + address);
}
uint64_t SimpleMemory::LoadI64(uint64_t address) {
return poly::load<uint64_t>(membase_ + address);
}
void SimpleMemory::StoreI8(uint64_t address, uint8_t value) {
poly::store<uint8_t>(membase_ + address, value);
}
void SimpleMemory::StoreI16(uint64_t address, uint16_t value) {
poly::store<uint16_t>(membase_ + address, value);
}
void SimpleMemory::StoreI32(uint64_t address, uint32_t value) {
poly::store<uint32_t>(membase_ + address, value);
}
void SimpleMemory::StoreI64(uint64_t address, uint64_t value) {
poly::store<uint64_t>(membase_ + address, value);
}
} // namespace alloy } // namespace alloy

View File

@ -40,16 +40,6 @@ class Memory {
uint64_t SearchAligned(uint64_t start, uint64_t end, const uint32_t* values, uint64_t SearchAligned(uint64_t start, uint64_t end, const uint32_t* values,
size_t value_count); size_t value_count);
// TODO(benvanik): remove with IVM.
virtual uint8_t LoadI8(uint64_t address) = 0;
virtual uint16_t LoadI16(uint64_t address) = 0;
virtual uint32_t LoadI32(uint64_t address) = 0;
virtual uint64_t LoadI64(uint64_t address) = 0;
virtual void StoreI8(uint64_t address, uint8_t value) = 0;
virtual void StoreI16(uint64_t address, uint16_t value) = 0;
virtual void StoreI32(uint64_t address, uint32_t value) = 0;
virtual void StoreI64(uint64_t address, uint64_t value) = 0;
protected: protected:
size_t system_page_size_; size_t system_page_size_;
uint8_t* membase_; uint8_t* membase_;
@ -63,16 +53,6 @@ class SimpleMemory : public Memory {
SimpleMemory(size_t capacity); SimpleMemory(size_t capacity);
~SimpleMemory() override; ~SimpleMemory() override;
// TODO(benvanik): remove with IVM.
uint8_t LoadI8(uint64_t address) override;
uint16_t LoadI16(uint64_t address) override;
uint32_t LoadI32(uint64_t address) override;
uint64_t LoadI64(uint64_t address) override;
void StoreI8(uint64_t address, uint8_t value) override;
void StoreI16(uint64_t address, uint16_t value) override;
void StoreI32(uint64_t address, uint32_t value) override;
void StoreI64(uint64_t address, uint64_t value) override;
private: private:
std::vector<uint8_t> memory_; std::vector<uint8_t> memory_;
}; };

View File

@ -53,7 +53,6 @@ bool FunctionInstrument::Attach() {
// Function impl attach: // Function impl attach:
// - add instrument to list // - add instrument to list
// IVM: handle in Call()
// JIT: transition to instrumented state // JIT: transition to instrumented state
// - rewrite enter/exit to jump to instrumentation thunk // - rewrite enter/exit to jump to instrumentation thunk
// - some sort of locking required? // - some sort of locking required?

View File

@ -17,10 +17,9 @@
#include <xenia/profiling.h> #include <xenia/profiling.h>
// TODO(benvanik): based on compiler support // TODO(benvanik): based on compiler support
#include <alloy/backend/ivm/ivm_backend.h>
#include <alloy/backend/x64/x64_backend.h> #include <alloy/backend/x64/x64_backend.h>
DEFINE_string(runtime_backend, "any", "Runtime backend [any, ivm, x64]."); DEFINE_string(runtime_backend, "any", "Runtime backend [any, x64].");
namespace alloy { namespace alloy {
namespace runtime { namespace runtime {
@ -81,22 +80,12 @@ int Runtime::Initialize(std::unique_ptr<Frontend> frontend,
backend.reset(new alloy::backend::x64::X64Backend(this)); backend.reset(new alloy::backend::x64::X64Backend(this));
} }
#endif // ALLOY_HAS_X64_BACKEND #endif // ALLOY_HAS_X64_BACKEND
#if defined(ALLOY_HAS_IVM_BACKEND) && ALLOY_HAS_IVM_BACKEND
if (FLAGS_runtime_backend == "ivm") {
backend.reset(new alloy::backend::ivm::IVMBackend(this));
}
#endif // ALLOY_HAS_IVM_BACKEND
if (FLAGS_runtime_backend == "any") { if (FLAGS_runtime_backend == "any") {
#if defined(ALLOY_HAS_X64_BACKEND) && ALLOY_HAS_X64_BACKEND #if defined(ALLOY_HAS_X64_BACKEND) && ALLOY_HAS_X64_BACKEND
if (!backend) { if (!backend) {
backend.reset(new alloy::backend::x64::X64Backend(this)); backend.reset(new alloy::backend::x64::X64Backend(this));
} }
#endif // ALLOY_HAS_X64_BACKEND #endif // ALLOY_HAS_X64_BACKEND
#if defined(ALLOY_HAS_IVM_BACKEND) && ALLOY_HAS_IVM_BACKEND
if (!backend) {
backend.reset(new alloy::backend::ivm::IVMBackend(this));
}
#endif // ALLOY_HAS_IVM_BACKEND
} }
} }

View File

@ -8,7 +8,6 @@
*/ */
#include <alloy/alloy.h> #include <alloy/alloy.h>
#include <alloy/backend/ivm/ivm_backend.h>
#include <alloy/backend/x64/x64_backend.h> #include <alloy/backend/x64/x64_backend.h>
#include <alloy/frontend/ppc/ppc_context.h> #include <alloy/frontend/ppc/ppc_context.h>
#include <alloy/frontend/ppc/ppc_frontend.h> #include <alloy/frontend/ppc/ppc_frontend.h>

View File

@ -11,7 +11,6 @@
#define ALLOY_TEST_UTIL_H_ #define ALLOY_TEST_UTIL_H_
#include <alloy/alloy.h> #include <alloy/alloy.h>
#include <alloy/backend/ivm/ivm_backend.h>
#include <alloy/backend/x64/x64_backend.h> #include <alloy/backend/x64/x64_backend.h>
#include <alloy/frontend/ppc/ppc_context.h> #include <alloy/frontend/ppc/ppc_context.h>
#include <alloy/frontend/ppc/ppc_frontend.h> #include <alloy/frontend/ppc/ppc_frontend.h>
@ -22,7 +21,6 @@
#include <third_party/catch/single_include/catch.hpp> #include <third_party/catch/single_include/catch.hpp>
#define ALLOY_TEST_IVM 1
#define ALLOY_TEST_X64 1 #define ALLOY_TEST_X64 1
namespace alloy { namespace alloy {
@ -86,17 +84,6 @@ class TestFunction {
memory_size = 16 * 1024 * 1024; memory_size = 16 * 1024 * 1024;
memory.reset(new SimpleMemory(memory_size)); memory.reset(new SimpleMemory(memory_size));
#if ALLOY_TEST_IVM
{
auto runtime = std::make_unique<Runtime>(memory.get());
auto frontend =
std::make_unique<alloy::frontend::ppc::PPCFrontend>(runtime.get());
auto backend =
std::make_unique<alloy::backend::ivm::IVMBackend>(runtime.get());
runtime->Initialize(std::move(frontend), std::move(backend));
runtimes.emplace_back(std::move(runtime));
}
#endif // ALLOY_TEST_IVM
#if ALLOY_TEST_X64 #if ALLOY_TEST_X64
{ {
auto runtime = std::make_unique<Runtime>(memory.get()); auto runtime = std::make_unique<Runtime>(memory.get());

View File

@ -90,7 +90,6 @@ int Processor::Setup() {
} }
std::unique_ptr<Backend> backend; std::unique_ptr<Backend> backend;
// backend.reset(new alloy::backend::ivm::IVMBackend(runtime));
// backend.reset(new alloy::backend::x64::X64Backend(runtime)); // backend.reset(new alloy::backend::x64::X64Backend(runtime));
int result = runtime_->Initialize(std::move(backend)); int result = runtime_->Initialize(std::move(backend));
if (result) { if (result) {

View File

@ -203,8 +203,8 @@ int Memory::Initialize() {
// I have no idea what this is, but games try to read/write there. // I have no idea what this is, but games try to read/write there.
VirtualAlloc(Translate(0x40000000), 0x00010000, MEM_COMMIT, PAGE_READWRITE); VirtualAlloc(Translate(0x40000000), 0x00010000, MEM_COMMIT, PAGE_READWRITE);
StoreI32(0x40000000, 0x00C40000); poly::store_and_swap<uint32_t>(Translate(0x40000000), 0x00C40000);
StoreI32(0x40000004, 0x00010000); poly::store_and_swap<uint32_t>(Translate(0x40000004), 0x00010000);
return 0; return 0;
} }
@ -286,62 +286,6 @@ void Memory::CancelWriteWatch(uintptr_t watch_handle) {
mmio_handler_->CancelWriteWatch(watch_handle); mmio_handler_->CancelWriteWatch(watch_handle);
} }
uint8_t Memory::LoadI8(uint64_t address) {
uint64_t value;
if (!mmio_handler_->CheckLoad(address, &value)) {
value = *reinterpret_cast<uint8_t*>(Translate(address));
}
return static_cast<uint8_t>(value);
}
uint16_t Memory::LoadI16(uint64_t address) {
uint64_t value;
if (!mmio_handler_->CheckLoad(address, &value)) {
value = *reinterpret_cast<uint16_t*>(Translate(address));
}
return static_cast<uint16_t>(value);
}
uint32_t Memory::LoadI32(uint64_t address) {
uint64_t value;
if (!mmio_handler_->CheckLoad(address, &value)) {
value = *reinterpret_cast<uint32_t*>(Translate(address));
}
return static_cast<uint32_t>(value);
}
uint64_t Memory::LoadI64(uint64_t address) {
uint64_t value;
if (!mmio_handler_->CheckLoad(address, &value)) {
value = *reinterpret_cast<uint64_t*>(Translate(address));
}
return static_cast<uint64_t>(value);
}
void Memory::StoreI8(uint64_t address, uint8_t value) {
if (!mmio_handler_->CheckStore(address, value)) {
*reinterpret_cast<uint8_t*>(Translate(address)) = value;
}
}
void Memory::StoreI16(uint64_t address, uint16_t value) {
if (!mmio_handler_->CheckStore(address, value)) {
*reinterpret_cast<uint16_t*>(Translate(address)) = value;
}
}
void Memory::StoreI32(uint64_t address, uint32_t value) {
if (!mmio_handler_->CheckStore(address, value)) {
*reinterpret_cast<uint32_t*>(Translate(address)) = value;
}
}
void Memory::StoreI64(uint64_t address, uint64_t value) {
if (!mmio_handler_->CheckStore(address, value)) {
*reinterpret_cast<uint64_t*>(Translate(address)) = value;
}
}
uint64_t Memory::HeapAlloc(uint64_t base_address, size_t size, uint32_t flags, uint64_t Memory::HeapAlloc(uint64_t base_address, size_t size, uint32_t flags,
uint32_t alignment) { uint32_t alignment) {
// If we were given a base address we are outside of the normal heap and // If we were given a base address we are outside of the normal heap and

View File

@ -58,15 +58,6 @@ class Memory : public alloy::Memory {
void* callback_context, void* callback_data); void* callback_context, void* callback_data);
void CancelWriteWatch(uintptr_t watch_handle); void CancelWriteWatch(uintptr_t watch_handle);
uint8_t LoadI8(uint64_t address) override;
uint16_t LoadI16(uint64_t address) override;
uint32_t LoadI32(uint64_t address) override;
uint64_t LoadI64(uint64_t address) override;
void StoreI8(uint64_t address, uint8_t value) override;
void StoreI16(uint64_t address, uint16_t value) override;
void StoreI32(uint64_t address, uint32_t value) override;
void StoreI64(uint64_t address, uint64_t value) override;
uint64_t HeapAlloc(uint64_t base_address, size_t size, uint32_t flags, uint64_t HeapAlloc(uint64_t base_address, size_t size, uint32_t flags,
uint32_t alignment = 0x20); uint32_t alignment = 0x20);
int HeapFree(uint64_t address, size_t size); int HeapFree(uint64_t address, size_t size);