bool-ifying xe::cpu

This commit is contained in:
Ben Vanik 2015-05-05 17:21:08 -07:00
parent a38b05db24
commit ade5388728
67 changed files with 270 additions and 347 deletions

View File

@ -17,7 +17,7 @@ Assembler::Assembler(Backend* backend) : backend_(backend) {}
Assembler::~Assembler() { Reset(); } Assembler::~Assembler() { Reset(); }
int Assembler::Initialize() { return 0; } bool Assembler::Initialize() { return true; }
void Assembler::Reset() {} void Assembler::Reset() {}

View File

@ -34,14 +34,14 @@ class Assembler {
Assembler(Backend* backend); Assembler(Backend* backend);
virtual ~Assembler(); virtual ~Assembler();
virtual int Initialize(); virtual bool Initialize();
virtual void Reset(); virtual void Reset();
virtual int Assemble(FunctionInfo* symbol_info, hir::HIRBuilder* builder, virtual bool Assemble(FunctionInfo* symbol_info, hir::HIRBuilder* builder,
uint32_t debug_info_flags, uint32_t debug_info_flags,
std::unique_ptr<DebugInfo> debug_info, std::unique_ptr<DebugInfo> debug_info,
uint32_t trace_flags, Function** out_function) = 0; uint32_t trace_flags, Function** out_function) = 0;
protected: protected:
Backend* backend_; Backend* backend_;

View File

@ -19,7 +19,7 @@ Backend::Backend(Processor* processor) : processor_(processor) {
Backend::~Backend() = default; Backend::~Backend() = default;
int Backend::Initialize() { return 0; } bool Backend::Initialize() { return true; }
void* Backend::AllocThreadData() { return nullptr; } void* Backend::AllocThreadData() { return nullptr; }

View File

@ -34,7 +34,7 @@ class Backend {
Processor* processor() const { return processor_; } Processor* processor() const { return processor_; }
const MachineInfo* machine_info() const { return &machine_info_; } const MachineInfo* machine_info() const { return &machine_info_; }
virtual int Initialize(); virtual bool Initialize();
virtual void* AllocThreadData(); virtual void* AllocThreadData();
virtual void FreeThreadData(void* thread_data); virtual void FreeThreadData(void* thread_data);

View File

@ -41,16 +41,15 @@ X64Assembler::~X64Assembler() {
allocator_.reset(); allocator_.reset();
} }
int X64Assembler::Initialize() { bool X64Assembler::Initialize() {
int result = Assembler::Initialize(); if (!Assembler::Initialize()) {
if (result) { return false;
return result;
} }
allocator_.reset(new XbyakAllocator()); allocator_.reset(new XbyakAllocator());
emitter_.reset(new X64Emitter(x64_backend_, allocator_.get())); emitter_.reset(new X64Emitter(x64_backend_, allocator_.get()));
return result; return true;
} }
void X64Assembler::Reset() { void X64Assembler::Reset() {
@ -58,10 +57,10 @@ void X64Assembler::Reset() {
Assembler::Reset(); Assembler::Reset();
} }
int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, bool X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
uint32_t debug_info_flags, uint32_t debug_info_flags,
std::unique_ptr<DebugInfo> debug_info, std::unique_ptr<DebugInfo> debug_info,
uint32_t trace_flags, Function** out_function) { uint32_t trace_flags, Function** out_function) {
SCOPE_profile_cpu_f("cpu"); SCOPE_profile_cpu_f("cpu");
// Reset when we leave. // Reset when we leave.
@ -70,10 +69,9 @@ int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
// Lower HIR -> x64. // Lower HIR -> x64.
void* machine_code = 0; void* machine_code = 0;
size_t code_size = 0; size_t code_size = 0;
int result = emitter_->Emit(builder, debug_info_flags, debug_info.get(), if (!emitter_->Emit(builder, debug_info_flags, debug_info.get(), trace_flags,
trace_flags, machine_code, code_size); machine_code, code_size)) {
if (result) { return false;
return result;
} }
// Stash generated machine code. // Stash generated machine code.
@ -91,7 +89,7 @@ int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
*out_function = fn; *out_function = fn;
} }
return 0; return true;
} }
void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code, void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code,

View File

@ -29,13 +29,14 @@ class X64Assembler : public Assembler {
X64Assembler(X64Backend* backend); X64Assembler(X64Backend* backend);
~X64Assembler() override; ~X64Assembler() override;
int Initialize() override; bool Initialize() override;
void Reset() override; void Reset() override;
int Assemble(FunctionInfo* symbol_info, hir::HIRBuilder* builder, bool Assemble(FunctionInfo* symbol_info, hir::HIRBuilder* builder,
uint32_t debug_info_flags, std::unique_ptr<DebugInfo> debug_info, uint32_t debug_info_flags,
uint32_t trace_flags, Function** out_function) override; std::unique_ptr<DebugInfo> debug_info, uint32_t trace_flags,
Function** out_function) override;
private: private:
void DumpMachineCode(DebugInfo* debug_info, void* machine_code, void DumpMachineCode(DebugInfo* debug_info, void* machine_code,

View File

@ -24,10 +24,9 @@ X64Backend::X64Backend(Processor* processor)
X64Backend::~X64Backend() { delete code_cache_; } X64Backend::~X64Backend() { delete code_cache_; }
int X64Backend::Initialize() { bool X64Backend::Initialize() {
int result = Backend::Initialize(); if (!Backend::Initialize()) {
if (result) { return false;
return result;
} }
RegisterSequences(); RegisterSequences();
@ -42,9 +41,8 @@ int X64Backend::Initialize() {
}; };
code_cache_ = new X64CodeCache(); code_cache_ = new X64CodeCache();
result = code_cache_->Initialize(); if (!code_cache_->Initialize()) {
if (result) { return false;
return result;
} }
// Generate thunks used to transition between jitted code and host code. // Generate thunks used to transition between jitted code and host code.
@ -53,7 +51,7 @@ int X64Backend::Initialize() {
host_to_guest_thunk_ = thunk_emitter->EmitHostToGuestThunk(); host_to_guest_thunk_ = thunk_emitter->EmitHostToGuestThunk();
guest_to_host_thunk_ = thunk_emitter->EmitGuestToHostThunk(); guest_to_host_thunk_ = thunk_emitter->EmitGuestToHostThunk();
return result; return true;
} }
std::unique_ptr<Assembler> X64Backend::CreateAssembler() { std::unique_ptr<Assembler> X64Backend::CreateAssembler() {

View File

@ -33,7 +33,7 @@ class X64Backend : public Backend {
HostToGuestThunk host_to_guest_thunk() const { return host_to_guest_thunk_; } HostToGuestThunk host_to_guest_thunk() const { return host_to_guest_thunk_; }
GuestToHostThunk guest_to_host_thunk() const { return guest_to_host_thunk_; } GuestToHostThunk guest_to_host_thunk() const { return guest_to_host_thunk_; }
int Initialize() override; bool Initialize() override;
std::unique_ptr<Assembler> CreateAssembler() override; std::unique_ptr<Assembler> CreateAssembler() override;

View File

@ -24,7 +24,7 @@ class X64CodeCache {
X64CodeCache(size_t chunk_size = DEFAULT_CHUNK_SIZE); X64CodeCache(size_t chunk_size = DEFAULT_CHUNK_SIZE);
virtual ~X64CodeCache(); virtual ~X64CodeCache();
int Initialize(); bool Initialize();
// TODO(benvanik): ELF serialization/etc // TODO(benvanik): ELF serialization/etc
// TODO(benvanik): keep track of code blocks // TODO(benvanik): keep track of code blocks

View File

@ -57,7 +57,7 @@ X64CodeCache::~X64CodeCache() {
head_chunk_ = NULL; head_chunk_ = NULL;
} }
int X64CodeCache::Initialize() { return 0; } bool X64CodeCache::Initialize() { return true; }
void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size,
size_t stack_size) { size_t stack_size) {

View File

@ -70,13 +70,11 @@ X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator)
trace_flags_(0), trace_flags_(0),
cpu_() {} cpu_() {}
X64Emitter::~X64Emitter() {} X64Emitter::~X64Emitter() = default;
int X64Emitter::Initialize() { return 0; } bool X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags,
DebugInfo* debug_info, uint32_t trace_flags,
int X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags, void*& out_code_address, size_t& out_code_size) {
DebugInfo* debug_info, uint32_t trace_flags,
void*& out_code_address, size_t& out_code_size) {
SCOPE_profile_cpu_f("cpu"); SCOPE_profile_cpu_f("cpu");
// Reset. // Reset.
@ -88,9 +86,8 @@ int X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags,
// Fill the generator with code. // Fill the generator with code.
size_t stack_size = 0; size_t stack_size = 0;
int result = Emit(builder, stack_size); if (!Emit(builder, stack_size)) {
if (result) { return false;
return result;
} }
// Copy the final code to the cache and relocate it. // Copy the final code to the cache and relocate it.
@ -103,7 +100,7 @@ int X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags,
source_map_count_, (SourceMapEntry*)source_map_arena_.CloneContents()); source_map_count_, (SourceMapEntry*)source_map_arena_.CloneContents());
} }
return 0; return true;
} }
void* X64Emitter::Emplace(size_t stack_size) { void* X64Emitter::Emplace(size_t stack_size) {
@ -120,7 +117,7 @@ void* X64Emitter::Emplace(size_t stack_size) {
return new_address; return new_address;
} }
int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) { bool X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) {
// Calculate stack size. We need to align things to their natural sizes. // Calculate stack size. We need to align things to their natural sizes.
// This could be much better (sort by type/etc). // This could be much better (sort by type/etc).
auto locals = builder->locals(); auto locals = builder->locals();
@ -204,7 +201,7 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) {
nop(); nop();
#endif // XE_DEBUG #endif // XE_DEBUG
return 0; return true;
} }
void X64Emitter::MarkSourceOffset(const Instr* i) { void X64Emitter::MarkSourceOffset(const Instr* i) {

View File

@ -105,11 +105,9 @@ class X64Emitter : public Xbyak::CodeGenerator {
X64Backend* backend() const { return backend_; } X64Backend* backend() const { return backend_; }
const Xbyak::util::Cpu* cpu() const { return &cpu_; } const Xbyak::util::Cpu* cpu() const { return &cpu_; }
int Initialize(); bool Emit(hir::HIRBuilder* builder, uint32_t debug_info_flags,
DebugInfo* debug_info, uint32_t trace_flags,
int Emit(hir::HIRBuilder* builder, uint32_t debug_info_flags, void*& out_code_address, size_t& out_code_size);
DebugInfo* debug_info, uint32_t trace_flags, void*& out_code_address,
size_t& out_code_size);
public: public:
// Reserved: rsp // Reserved: rsp
@ -182,7 +180,7 @@ class X64Emitter : public Xbyak::CodeGenerator {
protected: protected:
void* Emplace(size_t stack_size); void* Emplace(size_t stack_size);
int Emit(hir::HIRBuilder* builder, size_t& out_stack_size); bool Emit(hir::HIRBuilder* builder, size_t& out_stack_size);
void EmitGetCurrentThreadId(); void EmitGetCurrentThreadId();
void EmitTraceUserCallReturn(); void EmitTraceUserCallReturn();

View File

@ -30,19 +30,21 @@ void X64Function::Setup(void* machine_code, size_t code_size) {
code_size_ = code_size; code_size_ = code_size;
} }
int X64Function::AddBreakpointImpl(debug::Breakpoint* breakpoint) { return 0; } bool X64Function::AddBreakpointImpl(debug::Breakpoint* breakpoint) {
return false;
int X64Function::RemoveBreakpointImpl(debug::Breakpoint* breakpoint) {
return 0;
} }
int X64Function::CallImpl(ThreadState* thread_state, uint32_t return_address) { bool X64Function::RemoveBreakpointImpl(debug::Breakpoint* breakpoint) {
return false;
}
bool X64Function::CallImpl(ThreadState* thread_state, uint32_t return_address) {
auto backend = auto backend =
reinterpret_cast<X64Backend*>(thread_state->processor()->backend()); reinterpret_cast<X64Backend*>(thread_state->processor()->backend());
auto thunk = backend->host_to_guest_thunk(); auto thunk = backend->host_to_guest_thunk();
thunk(machine_code_, thread_state->context(), thunk(machine_code_, thread_state->context(),
reinterpret_cast<void*>(uintptr_t(return_address))); reinterpret_cast<void*>(uintptr_t(return_address)));
return 0; return true;
} }
} // namespace x64 } // namespace x64

View File

@ -30,9 +30,9 @@ class X64Function : public Function {
void Setup(void* machine_code, size_t code_size); void Setup(void* machine_code, size_t code_size);
protected: protected:
virtual int AddBreakpointImpl(debug::Breakpoint* breakpoint); virtual bool AddBreakpointImpl(debug::Breakpoint* breakpoint);
virtual int RemoveBreakpointImpl(debug::Breakpoint* breakpoint); virtual bool RemoveBreakpointImpl(debug::Breakpoint* breakpoint);
virtual int CallImpl(ThreadState* thread_state, uint32_t return_address); virtual bool CallImpl(ThreadState* thread_state, uint32_t return_address);
private: private:
void* machine_code_; void* machine_code_;

View File

@ -27,18 +27,18 @@ void Compiler::AddPass(std::unique_ptr<CompilerPass> pass) {
void Compiler::Reset() {} void Compiler::Reset() {}
int Compiler::Compile(xe::cpu::hir::HIRBuilder* builder) { bool Compiler::Compile(xe::cpu::hir::HIRBuilder* builder) {
// TODO(benvanik): sophisticated stuff. Run passes in parallel, run until they // TODO(benvanik): sophisticated stuff. Run passes in parallel, run until they
// stop changing things, etc. // stop changing things, etc.
for (size_t i = 0; i < passes_.size(); ++i) { for (size_t i = 0; i < passes_.size(); ++i) {
auto& pass = passes_[i]; auto& pass = passes_[i];
scratch_arena_.Reset(); scratch_arena_.Reset();
if (pass->Run(builder)) { if (!pass->Run(builder)) {
return 1; return false;
} }
} }
return 0; return true;
} }
} // namespace compiler } // namespace compiler

View File

@ -40,7 +40,7 @@ class Compiler {
void Reset(); void Reset();
int Compile(hir::HIRBuilder* builder); bool Compile(hir::HIRBuilder* builder);
private: private:
Processor* processor_; Processor* processor_;

View File

@ -19,10 +19,10 @@ CompilerPass::CompilerPass() : processor_(nullptr), compiler_(nullptr) {}
CompilerPass::~CompilerPass() = default; CompilerPass::~CompilerPass() = default;
int CompilerPass::Initialize(Compiler* compiler) { bool CompilerPass::Initialize(Compiler* compiler) {
processor_ = compiler->processor(); processor_ = compiler->processor();
compiler_ = compiler; compiler_ = compiler;
return 0; return true;
} }
Arena* CompilerPass::scratch_arena() const { Arena* CompilerPass::scratch_arena() const {

View File

@ -30,9 +30,9 @@ class CompilerPass {
CompilerPass(); CompilerPass();
virtual ~CompilerPass(); virtual ~CompilerPass();
virtual int Initialize(Compiler* compiler); virtual bool Initialize(Compiler* compiler);
virtual int Run(hir::HIRBuilder* builder) = 0; virtual bool Run(hir::HIRBuilder* builder) = 0;
protected: protected:
Arena* scratch_arena() const; Arena* scratch_arena() const;

View File

@ -30,7 +30,7 @@ ConstantPropagationPass::ConstantPropagationPass() : CompilerPass() {}
ConstantPropagationPass::~ConstantPropagationPass() {} ConstantPropagationPass::~ConstantPropagationPass() {}
int ConstantPropagationPass::Run(HIRBuilder* builder) { bool ConstantPropagationPass::Run(HIRBuilder* builder) {
// Once ContextPromotion has run there will likely be a whole slew of // Once ContextPromotion has run there will likely be a whole slew of
// constants that can be pushed through the function. // constants that can be pushed through the function.
// Example: // Example:
@ -98,7 +98,7 @@ int ConstantPropagationPass::Run(HIRBuilder* builder) {
case OPCODE_CALL_INDIRECT: case OPCODE_CALL_INDIRECT:
if (i->src1.value->IsConstant()) { if (i->src1.value->IsConstant()) {
FunctionInfo* symbol_info; FunctionInfo* symbol_info;
if (processor_->LookupFunctionInfo( if (!processor_->LookupFunctionInfo(
(uint32_t)i->src1.value->constant.i32, &symbol_info)) { (uint32_t)i->src1.value->constant.i32, &symbol_info)) {
break; break;
} }
@ -468,7 +468,7 @@ int ConstantPropagationPass::Run(HIRBuilder* builder) {
block = block->next; block = block->next;
} }
return 0; return true;
} }
void ConstantPropagationPass::PropagateCarry(Value* v, bool did_carry) { void ConstantPropagationPass::PropagateCarry(Value* v, bool did_carry) {

View File

@ -22,7 +22,7 @@ class ConstantPropagationPass : public CompilerPass {
ConstantPropagationPass(); ConstantPropagationPass();
~ConstantPropagationPass() override; ~ConstantPropagationPass() override;
int Run(hir::HIRBuilder* builder) override; bool Run(hir::HIRBuilder* builder) override;
private: private:
void PropagateCarry(hir::Value* v, bool did_carry); void PropagateCarry(hir::Value* v, bool did_carry);

View File

@ -36,9 +36,9 @@ ContextPromotionPass::ContextPromotionPass() : CompilerPass() {}
ContextPromotionPass::~ContextPromotionPass() {} ContextPromotionPass::~ContextPromotionPass() {}
int ContextPromotionPass::Initialize(Compiler* compiler) { bool ContextPromotionPass::Initialize(Compiler* compiler) {
if (CompilerPass::Initialize(compiler)) { if (!CompilerPass::Initialize(compiler)) {
return 1; return false;
} }
// This is a terrible implementation. // This is a terrible implementation.
@ -46,10 +46,10 @@ int ContextPromotionPass::Initialize(Compiler* compiler) {
context_values_.resize(context_info->size()); context_values_.resize(context_info->size());
context_validity_.resize(static_cast<uint32_t>(context_info->size())); context_validity_.resize(static_cast<uint32_t>(context_info->size()));
return 0; return true;
} }
int ContextPromotionPass::Run(HIRBuilder* builder) { bool ContextPromotionPass::Run(HIRBuilder* builder) {
// Like mem2reg, but because context memory is unaliasable it's easier to // Like mem2reg, but because context memory is unaliasable it's easier to
// check and convert LoadContext/StoreContext into value operations. // check and convert LoadContext/StoreContext into value operations.
// Example of load->value promotion: // Example of load->value promotion:
@ -82,7 +82,7 @@ int ContextPromotionPass::Run(HIRBuilder* builder) {
} }
} }
return 0; return true;
} }
void ContextPromotionPass::PromoteBlock(Block* block) { void ContextPromotionPass::PromoteBlock(Block* block) {

View File

@ -34,9 +34,9 @@ class ContextPromotionPass : public CompilerPass {
ContextPromotionPass(); ContextPromotionPass();
virtual ~ContextPromotionPass() override; virtual ~ContextPromotionPass() override;
int Initialize(Compiler* compiler) override; bool Initialize(Compiler* compiler) override;
int Run(hir::HIRBuilder* builder) override; bool Run(hir::HIRBuilder* builder) override;
private: private:
void PromoteBlock(hir::Block* block); void PromoteBlock(hir::Block* block);

View File

@ -29,7 +29,7 @@ ControlFlowAnalysisPass::ControlFlowAnalysisPass() : CompilerPass() {}
ControlFlowAnalysisPass::~ControlFlowAnalysisPass() {} ControlFlowAnalysisPass::~ControlFlowAnalysisPass() {}
int ControlFlowAnalysisPass::Run(HIRBuilder* builder) { bool ControlFlowAnalysisPass::Run(HIRBuilder* builder) {
// Reset edges for all blocks. Needed to be re-runnable. // Reset edges for all blocks. Needed to be re-runnable.
// Note that this wastes a bunch of arena memory, so we shouldn't // Note that this wastes a bunch of arena memory, so we shouldn't
// re-run too often. // re-run too often.
@ -71,7 +71,7 @@ int ControlFlowAnalysisPass::Run(HIRBuilder* builder) {
block = block->next; block = block->next;
} }
return 0; return true;
} }
} // namespace passes } // namespace passes

View File

@ -22,7 +22,7 @@ class ControlFlowAnalysisPass : public CompilerPass {
ControlFlowAnalysisPass(); ControlFlowAnalysisPass();
~ControlFlowAnalysisPass() override; ~ControlFlowAnalysisPass() override;
int Run(hir::HIRBuilder* builder) override; bool Run(hir::HIRBuilder* builder) override;
private: private:
}; };

View File

@ -30,7 +30,7 @@ ControlFlowSimplificationPass::ControlFlowSimplificationPass()
ControlFlowSimplificationPass::~ControlFlowSimplificationPass() {} ControlFlowSimplificationPass::~ControlFlowSimplificationPass() {}
int ControlFlowSimplificationPass::Run(HIRBuilder* builder) { bool ControlFlowSimplificationPass::Run(HIRBuilder* builder) {
// Walk backwards and merge blocks if possible. // Walk backwards and merge blocks if possible.
bool merged_any = false; bool merged_any = false;
auto block = builder->last_block(); auto block = builder->last_block();
@ -52,7 +52,7 @@ int ControlFlowSimplificationPass::Run(HIRBuilder* builder) {
block = prev_block; block = prev_block;
} }
return 0; return true;
} }
} // namespace passes } // namespace passes

View File

@ -22,7 +22,7 @@ class ControlFlowSimplificationPass : public CompilerPass {
ControlFlowSimplificationPass(); ControlFlowSimplificationPass();
~ControlFlowSimplificationPass() override; ~ControlFlowSimplificationPass() override;
int Run(hir::HIRBuilder* builder) override; bool Run(hir::HIRBuilder* builder) override;
private: private:
}; };

View File

@ -42,14 +42,14 @@ DataFlowAnalysisPass::DataFlowAnalysisPass() : CompilerPass() {}
DataFlowAnalysisPass::~DataFlowAnalysisPass() {} DataFlowAnalysisPass::~DataFlowAnalysisPass() {}
int DataFlowAnalysisPass::Run(HIRBuilder* builder) { bool DataFlowAnalysisPass::Run(HIRBuilder* builder) {
// Linearize blocks so that we can detect cycles and propagate dependencies. // Linearize blocks so that we can detect cycles and propagate dependencies.
uint32_t block_count = LinearizeBlocks(builder); uint32_t block_count = LinearizeBlocks(builder);
// Analyze value flow and add locals as needed. // Analyze value flow and add locals as needed.
AnalyzeFlow(builder, block_count); AnalyzeFlow(builder, block_count);
return 0; return true;
} }
uint32_t DataFlowAnalysisPass::LinearizeBlocks(HIRBuilder* builder) { uint32_t DataFlowAnalysisPass::LinearizeBlocks(HIRBuilder* builder) {

View File

@ -22,7 +22,7 @@ class DataFlowAnalysisPass : public CompilerPass {
DataFlowAnalysisPass(); DataFlowAnalysisPass();
~DataFlowAnalysisPass() override; ~DataFlowAnalysisPass() override;
int Run(hir::HIRBuilder* builder) override; bool Run(hir::HIRBuilder* builder) override;
private: private:
uint32_t LinearizeBlocks(hir::HIRBuilder* builder); uint32_t LinearizeBlocks(hir::HIRBuilder* builder);

View File

@ -27,7 +27,7 @@ DeadCodeEliminationPass::DeadCodeEliminationPass() : CompilerPass() {}
DeadCodeEliminationPass::~DeadCodeEliminationPass() {} DeadCodeEliminationPass::~DeadCodeEliminationPass() {}
int DeadCodeEliminationPass::Run(HIRBuilder* builder) { bool DeadCodeEliminationPass::Run(HIRBuilder* builder) {
// ContextPromotion/DSE will likely leave around a lot of dead statements. // ContextPromotion/DSE will likely leave around a lot of dead statements.
// Code generated for comparison/testing produces many unused statements and // Code generated for comparison/testing produces many unused statements and
// with proper use analysis it should be possible to remove most of them: // with proper use analysis it should be possible to remove most of them:
@ -143,7 +143,7 @@ int DeadCodeEliminationPass::Run(HIRBuilder* builder) {
} }
} }
return 0; return true;
} }
void DeadCodeEliminationPass::MakeNopRecursive(Instr* i) { void DeadCodeEliminationPass::MakeNopRecursive(Instr* i) {

View File

@ -22,7 +22,7 @@ class DeadCodeEliminationPass : public CompilerPass {
DeadCodeEliminationPass(); DeadCodeEliminationPass();
~DeadCodeEliminationPass() override; ~DeadCodeEliminationPass() override;
int Run(hir::HIRBuilder* builder) override; bool Run(hir::HIRBuilder* builder) override;
private: private:
void MakeNopRecursive(hir::Instr* i); void MakeNopRecursive(hir::Instr* i);

View File

@ -28,7 +28,7 @@ FinalizationPass::FinalizationPass() : CompilerPass() {}
FinalizationPass::~FinalizationPass() {} FinalizationPass::~FinalizationPass() {}
int FinalizationPass::Run(HIRBuilder* builder) { bool FinalizationPass::Run(HIRBuilder* builder) {
// Process the HIR and prepare it for lowering. // Process the HIR and prepare it for lowering.
// After this is done the HIR should be ready for emitting. // After this is done the HIR should be ready for emitting.
@ -65,7 +65,7 @@ int FinalizationPass::Run(HIRBuilder* builder) {
block = block->next; block = block->next;
} }
return 0; return true;
} }
} // namespace passes } // namespace passes

View File

@ -22,7 +22,7 @@ class FinalizationPass : public CompilerPass {
FinalizationPass(); FinalizationPass();
~FinalizationPass() override; ~FinalizationPass() override;
int Run(hir::HIRBuilder* builder) override; bool Run(hir::HIRBuilder* builder) override;
private: private:
}; };

View File

@ -69,7 +69,7 @@ RegisterAllocationPass::~RegisterAllocationPass() {
} }
} }
int RegisterAllocationPass::Run(HIRBuilder* builder) { bool RegisterAllocationPass::Run(HIRBuilder* builder) {
// Simple per-block allocator that operates on SSA form. // Simple per-block allocator that operates on SSA form.
// Registers do not move across blocks, though this could be // Registers do not move across blocks, though this could be
// optimized with some intra-block analysis (dominators/etc). // optimized with some intra-block analysis (dominators/etc).
@ -151,7 +151,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) {
// Unable to spill anything - this shouldn't happen. // Unable to spill anything - this shouldn't happen.
XELOGE("Unable to spill any registers"); XELOGE("Unable to spill any registers");
assert_always(); assert_always();
return 1; return false;
} }
// Demand allocation. // Demand allocation.
@ -159,7 +159,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) {
// Boned. // Boned.
XELOGE("Register allocation failed"); XELOGE("Register allocation failed");
assert_always(); assert_always();
return 1; return false;
} }
} }
} }
@ -169,7 +169,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) {
block = block->next; block = block->next;
} }
return 0; return true;
} }
void RegisterAllocationPass::DumpUsage(const char* name) { void RegisterAllocationPass::DumpUsage(const char* name) {

View File

@ -27,7 +27,7 @@ class RegisterAllocationPass : public CompilerPass {
RegisterAllocationPass(const backend::MachineInfo* machine_info); RegisterAllocationPass(const backend::MachineInfo* machine_info);
~RegisterAllocationPass() override; ~RegisterAllocationPass() override;
int Run(hir::HIRBuilder* builder) override; bool Run(hir::HIRBuilder* builder) override;
private: private:
// TODO(benvanik): rewrite all this set shit -- too much indirection, the // TODO(benvanik): rewrite all this set shit -- too much indirection, the

View File

@ -27,10 +27,10 @@ SimplificationPass::SimplificationPass() : CompilerPass() {}
SimplificationPass::~SimplificationPass() {} SimplificationPass::~SimplificationPass() {}
int SimplificationPass::Run(HIRBuilder* builder) { bool SimplificationPass::Run(HIRBuilder* builder) {
EliminateConversions(builder); EliminateConversions(builder);
SimplifyAssignments(builder); SimplifyAssignments(builder);
return 0; return true;
} }
void SimplificationPass::EliminateConversions(HIRBuilder* builder) { void SimplificationPass::EliminateConversions(HIRBuilder* builder) {

View File

@ -22,7 +22,7 @@ class SimplificationPass : public CompilerPass {
SimplificationPass(); SimplificationPass();
~SimplificationPass() override; ~SimplificationPass() override;
int Run(hir::HIRBuilder* builder) override; bool Run(hir::HIRBuilder* builder) override;
private: private:
void EliminateConversions(hir::HIRBuilder* builder); void EliminateConversions(hir::HIRBuilder* builder);

View File

@ -33,7 +33,7 @@ ValidationPass::ValidationPass() : CompilerPass() {}
ValidationPass::~ValidationPass() {} ValidationPass::~ValidationPass() {}
int ValidationPass::Run(HIRBuilder* builder) { bool ValidationPass::Run(HIRBuilder* builder) {
#if 0 #if 0
StringBuffer str; StringBuffer str;
builder->Dump(&str); builder->Dump(&str);
@ -48,15 +48,15 @@ int ValidationPass::Run(HIRBuilder* builder) {
while (label) { while (label) {
assert_true(label->block == block); assert_true(label->block == block);
if (label->block != block) { if (label->block != block) {
return 1; return false;
} }
label = label->next; label = label->next;
} }
auto instr = block->instr_head; auto instr = block->instr_head;
while (instr) { while (instr) {
if (ValidateInstruction(block, instr)) { if (!ValidateInstruction(block, instr)) {
return 1; return false;
} }
instr = instr->next; instr = instr->next;
} }
@ -64,13 +64,13 @@ int ValidationPass::Run(HIRBuilder* builder) {
block = block->next; block = block->next;
} }
return 0; return true;
} }
int ValidationPass::ValidateInstruction(Block* block, Instr* instr) { bool ValidationPass::ValidateInstruction(Block* block, Instr* instr) {
assert_true(instr->block == block); assert_true(instr->block == block);
if (instr->block != block) { if (instr->block != block) {
return 1; return false;
} }
if (instr->dest) { if (instr->dest) {
@ -84,33 +84,33 @@ int ValidationPass::ValidateInstruction(Block* block, Instr* instr) {
uint32_t signature = instr->opcode->signature; uint32_t signature = instr->opcode->signature;
if (GET_OPCODE_SIG_TYPE_SRC1(signature) == OPCODE_SIG_TYPE_V) { if (GET_OPCODE_SIG_TYPE_SRC1(signature) == OPCODE_SIG_TYPE_V) {
if (ValidateValue(block, instr, instr->src1.value)) { if (!ValidateValue(block, instr, instr->src1.value)) {
return 1; return false;
} }
} }
if (GET_OPCODE_SIG_TYPE_SRC2(signature) == OPCODE_SIG_TYPE_V) { if (GET_OPCODE_SIG_TYPE_SRC2(signature) == OPCODE_SIG_TYPE_V) {
if (ValidateValue(block, instr, instr->src2.value)) { if (!ValidateValue(block, instr, instr->src2.value)) {
return 1; return false;
} }
} }
if (GET_OPCODE_SIG_TYPE_SRC3(signature) == OPCODE_SIG_TYPE_V) { if (GET_OPCODE_SIG_TYPE_SRC3(signature) == OPCODE_SIG_TYPE_V) {
if (ValidateValue(block, instr, instr->src3.value)) { if (!ValidateValue(block, instr, instr->src3.value)) {
return 1; return false;
} }
} }
return 0; return true;
} }
int ValidationPass::ValidateValue(Block* block, Instr* instr, Value* value) { bool ValidationPass::ValidateValue(Block* block, Instr* instr, Value* value) {
// if (value->def) { // if (value->def) {
// auto def = value->def; // auto def = value->def;
// assert_true(def->block == block); // assert_true(def->block == block);
// if (def->block != block) { // if (def->block != block) {
// return 1; // return false;
// } // }
//} //}
return 0; return true;
} }
} // namespace passes } // namespace passes

View File

@ -22,11 +22,11 @@ class ValidationPass : public CompilerPass {
ValidationPass(); ValidationPass();
~ValidationPass() override; ~ValidationPass() override;
int Run(hir::HIRBuilder* builder) override; bool Run(hir::HIRBuilder* builder) override;
private: private:
int ValidateInstruction(hir::Block* block, hir::Instr* instr); bool ValidateInstruction(hir::Block* block, hir::Instr* instr);
int ValidateValue(hir::Block* block, hir::Instr* instr, hir::Value* value); bool ValidateValue(hir::Block* block, hir::Instr* instr, hir::Value* value);
}; };
} // namespace passes } // namespace passes

View File

@ -58,7 +58,7 @@ void ValueReductionPass::ComputeLastUse(Value* value) {
value->last_use = last_use ? last_use->instr : nullptr; value->last_use = last_use ? last_use->instr : nullptr;
} }
int ValueReductionPass::Run(HIRBuilder* builder) { bool ValueReductionPass::Run(HIRBuilder* builder) {
// Walk each block and reuse variable ordinals as much as possible. // Walk each block and reuse variable ordinals as much as possible.
llvm::BitVector ordinals(builder->max_value_ordinal()); llvm::BitVector ordinals(builder->max_value_ordinal());
@ -139,7 +139,7 @@ int ValueReductionPass::Run(HIRBuilder* builder) {
block = block->next; block = block->next;
} }
return 0; return true;
} }
} // namespace passes } // namespace passes

View File

@ -22,7 +22,7 @@ class ValueReductionPass : public CompilerPass {
ValueReductionPass(); ValueReductionPass();
~ValueReductionPass() override; ~ValueReductionPass() override;
int Run(hir::HIRBuilder* builder) override; bool Run(hir::HIRBuilder* builder) override;
private: private:
void ComputeLastUse(hir::Value* value); void ComputeLastUse(hir::Value* value);

View File

@ -73,7 +73,7 @@ void HandleGlobalLock(PPCContext* ppc_state, void* arg0, void* arg1) {
} }
} }
int PPCFrontend::Initialize() { bool PPCFrontend::Initialize() {
void* arg0 = reinterpret_cast<void*>(&builtins_.global_lock); void* arg0 = reinterpret_cast<void*>(&builtins_.global_lock);
void* arg1 = reinterpret_cast<void*>(&builtins_.global_lock_taken); void* arg1 = reinterpret_cast<void*>(&builtins_.global_lock_taken);
builtins_.check_global_lock = processor_->DefineBuiltin( builtins_.check_global_lock = processor_->DefineBuiltin(
@ -83,24 +83,25 @@ int PPCFrontend::Initialize() {
"HandleGlobalLock", (FunctionInfo::ExternHandler)HandleGlobalLock, arg0, "HandleGlobalLock", (FunctionInfo::ExternHandler)HandleGlobalLock, arg0,
arg1); arg1);
return 0; return true;
} }
int PPCFrontend::DeclareFunction(FunctionInfo* symbol_info) { bool PPCFrontend::DeclareFunction(FunctionInfo* symbol_info) {
// Could scan or something here. // Could scan or something here.
// Could also check to see if it's a well-known function type and classify // Could also check to see if it's a well-known function type and classify
// for later. // for later.
// Could also kick off a precompiler, since we know it's likely the function // Could also kick off a precompiler, since we know it's likely the function
// will be demanded soon. // will be demanded soon.
return 0; return true;
} }
int PPCFrontend::DefineFunction(FunctionInfo* symbol_info, bool PPCFrontend::DefineFunction(FunctionInfo* symbol_info,
uint32_t debug_info_flags, uint32_t trace_flags, uint32_t debug_info_flags,
Function** out_function) { uint32_t trace_flags,
Function** out_function) {
PPCTranslator* translator = translator_pool_.Allocate(this); PPCTranslator* translator = translator_pool_.Allocate(this);
int result = translator->Translate(symbol_info, debug_info_flags, trace_flags, bool result = translator->Translate(symbol_info, debug_info_flags,
out_function); trace_flags, out_function);
translator_pool_.Release(translator); translator_pool_.Release(translator);
return result; return result;
} }

View File

@ -43,16 +43,16 @@ class PPCFrontend {
explicit PPCFrontend(Processor* processor); explicit PPCFrontend(Processor* processor);
~PPCFrontend(); ~PPCFrontend();
int Initialize(); bool Initialize();
Processor* processor() const { return processor_; } Processor* processor() const { return processor_; }
Memory* memory() const; Memory* memory() const;
ContextInfo* context_info() const { return context_info_.get(); } ContextInfo* context_info() const { return context_info_.get(); }
PPCBuiltins* builtins() { return &builtins_; } PPCBuiltins* builtins() { return &builtins_; }
int DeclareFunction(FunctionInfo* symbol_info); bool DeclareFunction(FunctionInfo* symbol_info);
int DefineFunction(FunctionInfo* symbol_info, uint32_t debug_info_flags, bool DefineFunction(FunctionInfo* symbol_info, uint32_t debug_info_flags,
uint32_t trace_flags, Function** out_function); uint32_t trace_flags, Function** out_function);
private: private:
Processor* processor_; Processor* processor_;

View File

@ -45,7 +45,7 @@ void PPCHIRBuilder::Reset() {
HIRBuilder::Reset(); HIRBuilder::Reset();
} }
int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) { bool PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
SCOPE_profile_cpu_f("cpu"); SCOPE_profile_cpu_f("cpu");
Memory* memory = frontend_->memory(); Memory* memory = frontend_->memory();
@ -154,19 +154,19 @@ void PPCHIRBuilder::AnnotateLabel(uint32_t address, Label* label) {
FunctionInfo* PPCHIRBuilder::LookupFunction(uint32_t address) { FunctionInfo* PPCHIRBuilder::LookupFunction(uint32_t address) {
Processor* processor = frontend_->processor(); Processor* processor = frontend_->processor();
FunctionInfo* symbol_info; FunctionInfo* symbol_info;
if (processor->LookupFunctionInfo(address, &symbol_info)) { if (!processor->LookupFunctionInfo(address, &symbol_info)) {
return NULL; return nullptr;
} }
return symbol_info; return symbol_info;
} }
Label* PPCHIRBuilder::LookupLabel(uint32_t address) { Label* PPCHIRBuilder::LookupLabel(uint32_t address) {
if (address < start_address_) { if (address < start_address_) {
return NULL; return nullptr;
} }
size_t offset = (address - start_address_) / 4; size_t offset = (address - start_address_) / 4;
if (offset >= instr_count_) { if (offset >= instr_count_) {
return NULL; return nullptr;
} }
Label* label = label_list_[offset]; Label* label = label_list_[offset];
if (label) { if (label) {

View File

@ -36,7 +36,7 @@ class PPCHIRBuilder : public hir::HIRBuilder {
// Emit comment nodes. // Emit comment nodes.
EMIT_DEBUG_COMMENTS = 1 << 0, EMIT_DEBUG_COMMENTS = 1 << 0,
}; };
int Emit(FunctionInfo* symbol_info, uint32_t flags); bool Emit(FunctionInfo* symbol_info, uint32_t flags);
FunctionInfo* symbol_info() const { return symbol_info_; } FunctionInfo* symbol_info() const { return symbol_info_; }
FunctionInfo* LookupFunction(uint32_t address); FunctionInfo* LookupFunction(uint32_t address);

View File

@ -35,13 +35,13 @@ PPCScanner::~PPCScanner() {}
bool PPCScanner::IsRestGprLr(uint32_t address) { bool PPCScanner::IsRestGprLr(uint32_t address) {
FunctionInfo* symbol_info; FunctionInfo* symbol_info;
if (frontend_->processor()->LookupFunctionInfo(address, &symbol_info)) { if (!frontend_->processor()->LookupFunctionInfo(address, &symbol_info)) {
return false; return false;
} }
return symbol_info->behavior() == FunctionInfo::BEHAVIOR_EPILOG_RETURN; return symbol_info->behavior() == FunctionInfo::BEHAVIOR_EPILOG_RETURN;
} }
int PPCScanner::FindExtents(FunctionInfo* symbol_info) { bool PPCScanner::Scan(FunctionInfo* symbol_info, DebugInfo* debug_info) {
// This is a simple basic block analyizer. It walks the start address to the // This is a simple basic block analyizer. It walks the start address to the
// end address looking for branches. Each span of instructions between // end address looking for branches. Each span of instructions between
// branches is considered a basic block. When the last blr (that has no // branches is considered a basic block. When the last blr (that has no
@ -275,7 +275,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// - record prolog/epilog lengths/stack size/etc // - record prolog/epilog lengths/stack size/etc
LOGPPC("Finished analyzing %.8X", start_address); LOGPPC("Finished analyzing %.8X", start_address);
return 0; return true;
} }
std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) { std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {

View File

@ -12,6 +12,7 @@
#include <vector> #include <vector>
#include "xenia/cpu/debug_info.h"
#include "xenia/cpu/symbol_info.h" #include "xenia/cpu/symbol_info.h"
namespace xe { namespace xe {
@ -30,7 +31,7 @@ class PPCScanner {
PPCScanner(PPCFrontend* frontend); PPCScanner(PPCFrontend* frontend);
~PPCScanner(); ~PPCScanner();
int FindExtents(FunctionInfo* symbol_info); bool Scan(FunctionInfo* symbol_info, DebugInfo* debug_info);
std::vector<BlockInfo> FindBlocks(FunctionInfo* symbol_info); std::vector<BlockInfo> FindBlocks(FunctionInfo* symbol_info);

View File

@ -86,9 +86,9 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
PPCTranslator::~PPCTranslator() = default; PPCTranslator::~PPCTranslator() = default;
int PPCTranslator::Translate(FunctionInfo* symbol_info, bool PPCTranslator::Translate(FunctionInfo* symbol_info,
uint32_t debug_info_flags, uint32_t trace_flags, uint32_t debug_info_flags, uint32_t trace_flags,
Function** out_function) { Function** out_function) {
SCOPE_profile_cpu_f("cpu"); SCOPE_profile_cpu_f("cpu");
// Reset() all caching when we leave. // Reset() all caching when we leave.
@ -97,18 +97,6 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
xe::make_reset_scope(assembler_); xe::make_reset_scope(assembler_);
xe::make_reset_scope(&string_buffer_); xe::make_reset_scope(&string_buffer_);
// Scan the function to find its extents. We only need to do this if we
// haven't already been provided with them from some other source.
if (!symbol_info->has_end_address()) {
// TODO(benvanik): find a way to remove the need for the scan. A fixup
// scheme acting on branches could go back and modify calls to branches
// if they are within the extents.
int result = scanner_->FindExtents(symbol_info);
if (result) {
return result;
}
}
// NOTE: we only want to do this when required, as it's expensive to build. // NOTE: we only want to do this when required, as it's expensive to build.
if (FLAGS_always_disasm) { if (FLAGS_always_disasm) {
debug_info_flags |= DEBUG_INFO_ALL_DISASM; debug_info_flags |= DEBUG_INFO_ALL_DISASM;
@ -118,6 +106,11 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
debug_info.reset(new DebugInfo()); debug_info.reset(new DebugInfo());
} }
// Scan the function to find its extents and gather debug data.
if (!scanner_->Scan(symbol_info, debug_info.get())) {
return false;
}
// Stash source. // Stash source.
if (debug_info_flags & DEBUG_INFO_SOURCE_DISASM) { if (debug_info_flags & DEBUG_INFO_SOURCE_DISASM) {
DumpSource(symbol_info, &string_buffer_); DumpSource(symbol_info, &string_buffer_);
@ -134,9 +127,8 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
if (debug_info) { if (debug_info) {
emit_flags |= PPCHIRBuilder::EMIT_DEBUG_COMMENTS; emit_flags |= PPCHIRBuilder::EMIT_DEBUG_COMMENTS;
} }
int result = builder_->Emit(symbol_info, emit_flags); if (!builder_->Emit(symbol_info, emit_flags)) {
if (result) { return false;
return result;
} }
// Stash raw HIR. // Stash raw HIR.
@ -147,9 +139,8 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
} }
// Compile/optimize/etc. // Compile/optimize/etc.
result = compiler_->Compile(builder_.get()); if (!compiler_->Compile(builder_.get())) {
if (result) { return false;
return result;
} }
// Stash optimized HIR. // Stash optimized HIR.
@ -160,14 +151,12 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
} }
// Assemble to backend machine code. // Assemble to backend machine code.
result = if (!assembler_->Assemble(symbol_info, builder_.get(), debug_info_flags,
assembler_->Assemble(symbol_info, builder_.get(), debug_info_flags, std::move(debug_info), trace_flags, out_function)) {
std::move(debug_info), trace_flags, out_function); return false;
if (result) {
return result;
} }
return 0; return true;
}; };
void PPCTranslator::DumpSource(FunctionInfo* symbol_info, void PPCTranslator::DumpSource(FunctionInfo* symbol_info,

View File

@ -30,8 +30,8 @@ class PPCTranslator {
PPCTranslator(PPCFrontend* frontend); PPCTranslator(PPCFrontend* frontend);
~PPCTranslator(); ~PPCTranslator();
int Translate(FunctionInfo* symbol_info, uint32_t debug_info_flags, bool Translate(FunctionInfo* symbol_info, uint32_t debug_info_flags,
uint32_t trace_flags, Function** out_function); uint32_t trace_flags, Function** out_function);
private: private:
void DumpSource(FunctionInfo* symbol_info, StringBuffer* string_buffer); void DumpSource(FunctionInfo* symbol_info, StringBuffer* string_buffer);

View File

@ -188,7 +188,7 @@ class TestRunner {
bool Setup(TestSuite& suite) { bool Setup(TestSuite& suite) {
// Load the binary module. // Load the binary module.
auto module = std::make_unique<xe::cpu::RawModule>(processor.get()); auto module = std::make_unique<xe::cpu::RawModule>(processor.get());
if (module->LoadFile(START_ADDRESS, suite.bin_file_path)) { if (!module->LoadFile(START_ADDRESS, suite.bin_file_path)) {
XELOGE("Unable to load test binary %ls", suite.bin_file_path.c_str()); XELOGE("Unable to load test binary %ls", suite.bin_file_path.c_str());
return false; return false;
} }
@ -212,9 +212,8 @@ class TestRunner {
} }
// Execute test. // Execute test.
xe::cpu::Function* fn; xe::cpu::Function* fn = nullptr;
processor->ResolveFunction(test_case.address, &fn); if (!processor->ResolveFunction(test_case.address, &fn)) {
if (!fn) {
XELOGE("Entry function not found"); XELOGE("Entry function not found");
return false; return false;
} }

View File

@ -23,7 +23,7 @@ Function::Function(FunctionInfo* symbol_info)
Function::~Function() = default; Function::~Function() = default;
int Function::AddBreakpoint(Breakpoint* breakpoint) { bool Function::AddBreakpoint(Breakpoint* breakpoint) {
std::lock_guard<std::mutex> guard(lock_); std::lock_guard<std::mutex> guard(lock_);
bool found = false; bool found = false;
for (auto other : breakpoints_) { for (auto other : breakpoints_) {
@ -32,25 +32,25 @@ int Function::AddBreakpoint(Breakpoint* breakpoint) {
break; break;
} }
} }
if (!found) { if (found) {
return true;
} else {
breakpoints_.push_back(breakpoint); breakpoints_.push_back(breakpoint);
AddBreakpointImpl(breakpoint); return AddBreakpointImpl(breakpoint);
} }
return found ? 1 : 0;
} }
int Function::RemoveBreakpoint(Breakpoint* breakpoint) { bool Function::RemoveBreakpoint(Breakpoint* breakpoint) {
std::lock_guard<std::mutex> guard(lock_); std::lock_guard<std::mutex> guard(lock_);
bool found = false;
for (auto it = breakpoints_.begin(); it != breakpoints_.end(); ++it) { for (auto it = breakpoints_.begin(); it != breakpoints_.end(); ++it) {
if (*it == breakpoint) { if (*it == breakpoint) {
if (!RemoveBreakpointImpl(breakpoint)) {
return false;
}
breakpoints_.erase(it); breakpoints_.erase(it);
RemoveBreakpointImpl(breakpoint);
found = true;
break;
} }
} }
return found ? 0 : 1; return false;
} }
Breakpoint* Function::FindBreakpoint(uint32_t address) { Breakpoint* Function::FindBreakpoint(uint32_t address) {
@ -65,7 +65,7 @@ Breakpoint* Function::FindBreakpoint(uint32_t address) {
return result; return result;
} }
int Function::Call(ThreadState* thread_state, uint32_t return_address) { bool Function::Call(ThreadState* thread_state, uint32_t return_address) {
// SCOPE_profile_cpu_f("cpu"); // SCOPE_profile_cpu_f("cpu");
ThreadState* original_thread_state = ThreadState::Get(); ThreadState* original_thread_state = ThreadState::Get();
@ -73,7 +73,7 @@ int Function::Call(ThreadState* thread_state, uint32_t return_address) {
ThreadState::Bind(thread_state); ThreadState::Bind(thread_state);
} }
int result = 0; bool result = true;
if (symbol_info_->behavior() == FunctionInfo::BEHAVIOR_EXTERN) { if (symbol_info_->behavior() == FunctionInfo::BEHAVIOR_EXTERN) {
auto handler = symbol_info_->extern_handler(); auto handler = symbol_info_->extern_handler();
@ -84,7 +84,7 @@ int Function::Call(ThreadState* thread_state, uint32_t return_address) {
} else { } else {
XELOGW("undefined extern call to %.8llX %s", symbol_info_->address(), XELOGW("undefined extern call to %.8llX %s", symbol_info_->address(),
symbol_info_->name().c_str()); symbol_info_->name().c_str());
result = 1; result = false;
} }
} else { } else {
CallImpl(thread_state, return_address); CallImpl(thread_state, return_address);

View File

@ -36,16 +36,16 @@ class Function {
debug_info_ = std::move(debug_info); debug_info_ = std::move(debug_info);
} }
int AddBreakpoint(debug::Breakpoint* breakpoint); bool AddBreakpoint(debug::Breakpoint* breakpoint);
int RemoveBreakpoint(debug::Breakpoint* breakpoint); bool RemoveBreakpoint(debug::Breakpoint* breakpoint);
int Call(ThreadState* thread_state, uint32_t return_address); bool Call(ThreadState* thread_state, uint32_t return_address);
protected: protected:
debug::Breakpoint* FindBreakpoint(uint32_t address); debug::Breakpoint* FindBreakpoint(uint32_t address);
virtual int AddBreakpointImpl(debug::Breakpoint* breakpoint) { return 0; } virtual bool AddBreakpointImpl(debug::Breakpoint* breakpoint) { return 0; }
virtual int RemoveBreakpointImpl(debug::Breakpoint* breakpoint) { return 0; } virtual bool RemoveBreakpointImpl(debug::Breakpoint* breakpoint) { return 0; }
virtual int CallImpl(ThreadState* thread_state, uint32_t return_address) = 0; virtual bool CallImpl(ThreadState* thread_state, uint32_t return_address) = 0;
protected: protected:
uint32_t address_; uint32_t address_;

View File

@ -51,7 +51,7 @@ void HIRBuilder::Reset() {
arena_->Reset(); arena_->Reset();
} }
int HIRBuilder::Finalize() { bool HIRBuilder::Finalize() {
// Scan blocks in order and add fallthrough branches. These are needed for // Scan blocks in order and add fallthrough branches. These are needed for
// analysis passes to work. We may have also added blocks out of order and // analysis passes to work. We may have also added blocks out of order and
// need to ensure they fall through in the right order. // need to ensure they fall through in the right order.
@ -84,7 +84,7 @@ int HIRBuilder::Finalize() {
current_block_ = NULL; current_block_ = NULL;
} }
} }
return 0; return true;
} }
void HIRBuilder::DumpValue(StringBuffer* str, Value* value) { void HIRBuilder::DumpValue(StringBuffer* str, Value* value) {

View File

@ -34,7 +34,7 @@ class HIRBuilder {
virtual ~HIRBuilder(); virtual ~HIRBuilder();
virtual void Reset(); virtual void Reset();
virtual int Finalize(); virtual bool Finalize();
void Dump(StringBuffer* str); void Dump(StringBuffer* str);
void AssertNoCycles(); void AssertNoCycles();

View File

@ -175,7 +175,7 @@ void Module::ForEachFunction(size_t since, size_t& version,
} }
} }
int Module::ReadMap(const char* file_name) { bool Module::ReadMap(const char* file_name) {
std::ifstream infile(file_name); std::ifstream infile(file_name);
// Skip until ' Address'. Skip the next blank line. // Skip until ' Address'. Skip the next blank line.
@ -225,7 +225,7 @@ int Module::ReadMap(const char* file_name) {
if (type_str == "f") { if (type_str == "f") {
// Function. // Function.
FunctionInfo* fn_info; FunctionInfo* fn_info;
if (processor_->LookupFunctionInfo(this, address, &fn_info)) { if (!processor_->LookupFunctionInfo(this, address, &fn_info)) {
continue; continue;
} }
// Don't overwrite names we've set elsewhere. // Don't overwrite names we've set elsewhere.
@ -243,7 +243,7 @@ int Module::ReadMap(const char* file_name) {
} }
} }
return 0; return true;
} }
} // namespace cpu } // namespace cpu

View File

@ -49,7 +49,7 @@ class Module {
void ForEachFunction(size_t since, size_t& version, void ForEachFunction(size_t since, size_t& version,
std::function<void(FunctionInfo*)> callback); std::function<void(FunctionInfo*)> callback);
int ReadMap(const char* file_name); bool ReadMap(const char* file_name);
private: private:
SymbolInfo::Status DeclareSymbol(SymbolInfo::Type type, uint32_t address, SymbolInfo::Status DeclareSymbol(SymbolInfo::Type type, uint32_t address,

View File

@ -98,7 +98,7 @@ Processor::~Processor() {
backend_.reset(); backend_.reset();
} }
int Processor::Setup() { bool Processor::Setup() {
debug_info_flags_ = DEBUG_INFO_DEFAULT; debug_info_flags_ = DEBUG_INFO_DEFAULT;
trace_flags_ = 0; trace_flags_ = 0;
@ -116,7 +116,7 @@ int Processor::Setup() {
modules_.push_back(std::move(builtin_module)); modules_.push_back(std::move(builtin_module));
if (frontend_ || backend_) { if (frontend_ || backend_) {
return 1; return false;
} }
std::unique_ptr<xe::cpu::backend::Backend> backend; std::unique_ptr<xe::cpu::backend::Backend> backend;
@ -136,17 +136,13 @@ int Processor::Setup() {
} }
if (!backend) { if (!backend) {
return 1; return false;
} }
if (!backend->Initialize()) {
int result = backend->Initialize(); return false;
if (result) {
return result;
} }
if (!frontend->Initialize()) {
result = frontend->Initialize(); return false;
if (result) {
return result;
} }
backend_ = std::move(backend); backend_ = std::move(backend);
@ -157,13 +153,13 @@ int Processor::Setup() {
interrupt_thread_block_ = memory_->SystemHeapAlloc(2048); interrupt_thread_block_ = memory_->SystemHeapAlloc(2048);
interrupt_thread_state_->context()->r[13] = interrupt_thread_block_; interrupt_thread_state_->context()->r[13] = interrupt_thread_block_;
return 0; return true;
} }
int Processor::AddModule(std::unique_ptr<Module> module) { bool Processor::AddModule(std::unique_ptr<Module> module) {
std::lock_guard<std::mutex> guard(modules_lock_); std::lock_guard<std::mutex> guard(modules_lock_);
modules_.push_back(std::move(module)); modules_.push_back(std::move(module));
return 0; return true;
} }
Module* Processor::GetModule(const char* name) { Module* Processor::GetModule(const char* name) {
@ -205,7 +201,7 @@ std::vector<Function*> Processor::FindFunctionsWithAddress(uint32_t address) {
return entry_table_.FindWithAddress(address); return entry_table_.FindWithAddress(address);
} }
int Processor::ResolveFunction(uint32_t address, Function** out_function) { bool Processor::ResolveFunction(uint32_t address, Function** out_function) {
*out_function = nullptr; *out_function = nullptr;
Entry* entry; Entry* entry;
Entry::Status status = entry_table_.GetOrCreate(address, &entry); Entry::Status status = entry_table_.GetOrCreate(address, &entry);
@ -214,15 +210,13 @@ int Processor::ResolveFunction(uint32_t address, Function** out_function) {
// Grab symbol declaration. // Grab symbol declaration.
FunctionInfo* symbol_info; FunctionInfo* symbol_info;
int result = LookupFunctionInfo(address, &symbol_info); if (!LookupFunctionInfo(address, &symbol_info)) {
if (result) { return false;
return result;
} }
result = DemandFunction(symbol_info, &entry->function); if (!DemandFunction(symbol_info, &entry->function)) {
if (result) {
entry->status = Entry::STATUS_FAILED; entry->status = Entry::STATUS_FAILED;
return result; return false;
} }
entry->end_address = symbol_info->end_address(); entry->end_address = symbol_info->end_address();
status = entry->status = Entry::STATUS_READY; status = entry->status = Entry::STATUS_READY;
@ -230,15 +224,15 @@ int Processor::ResolveFunction(uint32_t address, Function** out_function) {
if (status == Entry::STATUS_READY) { if (status == Entry::STATUS_READY) {
// Ready to use. // Ready to use.
*out_function = entry->function; *out_function = entry->function;
return 0; return true;
} else { } else {
// Failed or bad state. // Failed or bad state.
return 1; return false;
} }
} }
int Processor::LookupFunctionInfo(uint32_t address, bool Processor::LookupFunctionInfo(uint32_t address,
FunctionInfo** out_symbol_info) { FunctionInfo** out_symbol_info) {
*out_symbol_info = nullptr; *out_symbol_info = nullptr;
// TODO(benvanik): fast reject invalid addresses/log errors. // TODO(benvanik): fast reject invalid addresses/log errors.
@ -258,14 +252,14 @@ int Processor::LookupFunctionInfo(uint32_t address,
} }
if (!code_module) { if (!code_module) {
// No module found that could contain the address. // No module found that could contain the address.
return 1; return false;
} }
return LookupFunctionInfo(code_module, address, out_symbol_info); return LookupFunctionInfo(code_module, address, out_symbol_info);
} }
int Processor::LookupFunctionInfo(Module* module, uint32_t address, bool Processor::LookupFunctionInfo(Module* module, uint32_t address,
FunctionInfo** out_symbol_info) { FunctionInfo** out_symbol_info) {
// Atomic create/lookup symbol in module. // Atomic create/lookup symbol in module.
// If we get back the NEW flag we must declare it now. // If we get back the NEW flag we must declare it now.
FunctionInfo* symbol_info = nullptr; FunctionInfo* symbol_info = nullptr;
@ -273,20 +267,19 @@ int Processor::LookupFunctionInfo(Module* module, uint32_t address,
module->DeclareFunction(address, &symbol_info); module->DeclareFunction(address, &symbol_info);
if (symbol_status == SymbolInfo::STATUS_NEW) { if (symbol_status == SymbolInfo::STATUS_NEW) {
// Symbol is undeclared, so declare now. // Symbol is undeclared, so declare now.
int result = frontend_->DeclareFunction(symbol_info); if (!frontend_->DeclareFunction(symbol_info)) {
if (result) {
symbol_info->set_status(SymbolInfo::STATUS_FAILED); symbol_info->set_status(SymbolInfo::STATUS_FAILED);
return 1; return false;
} }
symbol_info->set_status(SymbolInfo::STATUS_DECLARED); symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
} }
*out_symbol_info = symbol_info; *out_symbol_info = symbol_info;
return 0; return true;
} }
int Processor::DemandFunction(FunctionInfo* symbol_info, bool Processor::DemandFunction(FunctionInfo* symbol_info,
Function** out_function) { Function** out_function) {
*out_function = nullptr; *out_function = nullptr;
// Lock function for generation. If it's already being generated // Lock function for generation. If it's already being generated
@ -296,11 +289,10 @@ int Processor::DemandFunction(FunctionInfo* symbol_info,
if (symbol_status == SymbolInfo::STATUS_NEW) { if (symbol_status == SymbolInfo::STATUS_NEW) {
// Symbol is undefined, so define now. // Symbol is undefined, so define now.
Function* function = nullptr; Function* function = nullptr;
int result = frontend_->DefineFunction(symbol_info, debug_info_flags_, if (!frontend_->DefineFunction(symbol_info, debug_info_flags_, trace_flags_,
trace_flags_, &function); &function)) {
if (result) {
symbol_info->set_status(SymbolInfo::STATUS_FAILED); symbol_info->set_status(SymbolInfo::STATUS_FAILED);
return result; return false;
} }
symbol_info->set_function(function); symbol_info->set_function(function);
@ -313,23 +305,23 @@ int Processor::DemandFunction(FunctionInfo* symbol_info,
if (symbol_status == SymbolInfo::STATUS_FAILED) { if (symbol_status == SymbolInfo::STATUS_FAILED) {
// Symbol likely failed. // Symbol likely failed.
return 1; return false;
} }
*out_function = symbol_info->function(); *out_function = symbol_info->function();
return 0; return true;
} }
int Processor::Execute(ThreadState* thread_state, uint32_t address) { bool Processor::Execute(ThreadState* thread_state, uint32_t address) {
SCOPE_profile_cpu_f("cpu"); SCOPE_profile_cpu_f("cpu");
// Attempt to get the function. // Attempt to get the function.
Function* fn; Function* fn;
if (ResolveFunction(address, &fn)) { if (!ResolveFunction(address, &fn)) {
// Symbol not found in any module. // Symbol not found in any module.
XELOGCPU("Execute(%.8X): failed to find function", address); XELOGCPU("Execute(%.8X): failed to find function", address);
return 1; return false;
} }
PPCContext* context = thread_state->context(); PPCContext* context = thread_state->context();
@ -342,8 +334,7 @@ int Processor::Execute(ThreadState* thread_state, uint32_t address) {
context->lr = lr; context->lr = lr;
// Execute the function. // Execute the function.
fn->Call(thread_state, lr); return fn->Call(thread_state, lr);
return 0;
} }
uint64_t Processor::Execute(ThreadState* thread_state, uint32_t address, uint64_t Processor::Execute(ThreadState* thread_state, uint32_t address,
@ -355,7 +346,7 @@ uint64_t Processor::Execute(ThreadState* thread_state, uint32_t address,
for (size_t i = 0; i < arg_count; ++i) { for (size_t i = 0; i < arg_count; ++i) {
context->r[3 + i] = args[i]; context->r[3 + i] = args[i];
} }
if (Execute(thread_state, address)) { if (!Execute(thread_state, address)) {
return 0xDEADBABE; return 0xDEADBABE;
} }
return context->r[3]; return context->r[3];

View File

@ -52,9 +52,9 @@ class Processor {
backend::Backend* backend() const { return backend_.get(); } backend::Backend* backend() const { return backend_.get(); }
ExportResolver* export_resolver() const { return export_resolver_; } ExportResolver* export_resolver() const { return export_resolver_; }
int Setup(); bool Setup();
int AddModule(std::unique_ptr<Module> module); bool AddModule(std::unique_ptr<Module> module);
Module* GetModule(const char* name); Module* GetModule(const char* name);
Module* GetModule(const std::string& name) { return GetModule(name.c_str()); } Module* GetModule(const std::string& name) { return GetModule(name.c_str()); }
std::vector<Module*> GetModules(); std::vector<Module*> GetModules();
@ -66,12 +66,12 @@ class Processor {
std::vector<Function*> FindFunctionsWithAddress(uint32_t address); std::vector<Function*> FindFunctionsWithAddress(uint32_t address);
int LookupFunctionInfo(uint32_t address, FunctionInfo** out_symbol_info); bool LookupFunctionInfo(uint32_t address, FunctionInfo** out_symbol_info);
int LookupFunctionInfo(Module* module, uint32_t address, bool LookupFunctionInfo(Module* module, uint32_t address,
FunctionInfo** out_symbol_info); FunctionInfo** out_symbol_info);
int ResolveFunction(uint32_t address, Function** out_function); bool ResolveFunction(uint32_t address, Function** out_function);
int Execute(ThreadState* thread_state, uint32_t address); bool Execute(ThreadState* thread_state, uint32_t address);
uint64_t Execute(ThreadState* thread_state, uint32_t address, uint64_t args[], uint64_t Execute(ThreadState* thread_state, uint32_t address, uint64_t args[],
size_t arg_count); size_t arg_count);
@ -82,7 +82,7 @@ class Processor {
size_t arg_count); size_t arg_count);
private: private:
int DemandFunction(FunctionInfo* symbol_info, Function** out_function); bool DemandFunction(FunctionInfo* symbol_info, Function** out_function);
Memory* memory_; Memory* memory_;

View File

@ -20,7 +20,7 @@ RawModule::RawModule(Processor* processor)
RawModule::~RawModule() {} RawModule::~RawModule() {}
int RawModule::LoadFile(uint32_t base_address, const std::wstring& path) { bool RawModule::LoadFile(uint32_t base_address, const std::wstring& path) {
auto fixed_path = xe::to_string(xe::fix_path_separators(path)); auto fixed_path = xe::to_string(xe::fix_path_separators(path));
FILE* file = fopen(fixed_path.c_str(), "rb"); FILE* file = fopen(fixed_path.c_str(), "rb");
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
@ -49,7 +49,7 @@ int RawModule::LoadFile(uint32_t base_address, const std::wstring& path) {
low_address_ = base_address; low_address_ = base_address;
high_address_ = base_address + file_length; high_address_ = base_address + file_length;
return 0; return true;
} }
bool RawModule::ContainsAddress(uint32_t address) { bool RawModule::ContainsAddress(uint32_t address) {

View File

@ -22,7 +22,7 @@ class RawModule : public Module {
RawModule(Processor* processor); RawModule(Processor* processor);
~RawModule() override; ~RawModule() override;
int LoadFile(uint32_t base_address, const std::wstring& path); bool LoadFile(uint32_t base_address, const std::wstring& path);
const std::string& name() const override { return name_; } const std::string& name() const override { return name_; }

View File

@ -36,9 +36,9 @@ class ThreadState {
uint32_t thread_state_address() const { return thread_state_address_; } uint32_t thread_state_address() const { return thread_state_address_; }
xe::cpu::frontend::PPCContext* context() const { return context_; } xe::cpu::frontend::PPCContext* context() const { return context_; }
int Suspend() { return Suspend(~0); } bool Suspend() { return Suspend(~0); }
int Suspend(uint32_t timeout_ms) { return 1; } bool Suspend(uint32_t timeout_ms) { return false; }
int Resume(bool force = false) { return 1; } bool Resume(bool force = false) { return false; }
static void Bind(ThreadState* thread_state); static void Bind(ThreadState* thread_state);
static ThreadState* Get(); static ThreadState* Get();

View File

@ -40,10 +40,8 @@ XexModule::XexModule(Processor* processor)
XexModule::~XexModule() { xe_xex2_dealloc(xex_); } XexModule::~XexModule() { xe_xex2_dealloc(xex_); }
int XexModule::Load(const std::string& name, const std::string& path, bool XexModule::Load(const std::string& name, const std::string& path,
xe_xex2_ref xex) { xe_xex2_ref xex) {
int result;
xex_ = xex; xex_ = xex;
const xe_xex2_header_t* header = xe_xex2_get_header(xex); const xe_xex2_header_t* header = xe_xex2_get_header(xex);
@ -66,17 +64,15 @@ int XexModule::Load(const std::string& name, const std::string& path,
// Add all imports (variables/functions). // Add all imports (variables/functions).
for (size_t n = 0; n < header->import_library_count; n++) { for (size_t n = 0; n < header->import_library_count; n++) {
result = SetupLibraryImports(&header->import_libraries[n]); if (!SetupLibraryImports(&header->import_libraries[n])) {
if (result) { return false;
return result;
} }
} }
// Find __savegprlr_* and __restgprlr_* and the others. // Find __savegprlr_* and __restgprlr_* and the others.
// We can flag these for special handling (inlining/etc). // We can flag these for special handling (inlining/etc).
result = FindSaveRest(); if (!FindSaveRest()) {
if (result) { return false;
return result;
} }
// Setup debug info. // Setup debug info.
@ -86,20 +82,22 @@ int XexModule::Load(const std::string& name, const std::string& path,
// Load a specified module map and diff. // Load a specified module map and diff.
if (FLAGS_load_module_map.size()) { if (FLAGS_load_module_map.size()) {
ReadMap(FLAGS_load_module_map.c_str()); if (!ReadMap(FLAGS_load_module_map.c_str())) {
return false;
}
} }
return 0; return true;
} }
int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) { bool XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
ExportResolver* export_resolver = processor_->export_resolver(); ExportResolver* export_resolver = processor_->export_resolver();
xe_xex2_import_info_t* import_infos; xe_xex2_import_info_t* import_infos;
size_t import_info_count; size_t import_info_count;
if (xe_xex2_get_import_infos(xex_, library, &import_infos, if (xe_xex2_get_import_infos(xex_, library, &import_infos,
&import_info_count)) { &import_info_count)) {
return 1; return false;
} }
char name[128]; char name[128];
@ -203,14 +201,14 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
} }
} }
return 0; return true;
} }
bool XexModule::ContainsAddress(uint32_t address) { bool XexModule::ContainsAddress(uint32_t address) {
return address >= low_address_ && address < high_address_; return address >= low_address_ && address < high_address_;
} }
int XexModule::FindSaveRest() { bool XexModule::FindSaveRest() {
// Special stack save/restore functions. // Special stack save/restore functions.
// http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md/ppc/xxx.s.htm // http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md/ppc/xxx.s.htm
// It'd be nice to stash these away and mark them as such to allow for // It'd be nice to stash these away and mark them as such to allow for
@ -523,7 +521,7 @@ int XexModule::FindSaveRest() {
} }
} }
return 0; return true;
} }
} // namespace cpu } // namespace cpu

View File

@ -27,16 +27,16 @@ class XexModule : public xe::cpu::Module {
xe_xex2_ref xex() const { return xex_; } xe_xex2_ref xex() const { return xex_; }
int Load(const std::string& name, const std::string& path, xe_xex2_ref xex); bool Load(const std::string& name, const std::string& path, xe_xex2_ref xex);
const std::string& name() const override { return name_; } const std::string& name() const override { return name_; }
bool ContainsAddress(uint32_t address) override; bool ContainsAddress(uint32_t address) override;
private: private:
int SetupImports(xe_xex2_ref xex); bool SetupImports(xe_xex2_ref xex);
int SetupLibraryImports(const xe_xex2_import_library_t* library); bool SetupLibraryImports(const xe_xex2_import_library_t* library);
int FindSaveRest(); bool FindSaveRest();
private: private:
Processor* processor_; Processor* processor_;

View File

@ -5,7 +5,5 @@
'debug_server.h', 'debug_server.h',
'debugger.cc', 'debugger.cc',
'debugger.h', 'debugger.h',
'trace_writer.cc',
'trace_writer.h',
], ],
} }

View File

@ -1,18 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2015 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/debug/trace_writer.h"
namespace xe {
namespace debug {
//
} // namespace debug
} // namespace xe

View File

@ -1,29 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2015 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_DEBUG_TRACE_WRITER_H_
#define XENIA_DEBUG_TRACE_WRITER_H_
namespace xe {
namespace debug {
enum TraceFlags {
kTraceFunctionInfo = 1 << 0,
kTraceInstructionReferences = 1 << 1,
kTraceInstructionResults = 1 << 2,
};
class TraceWriter {
public:
};
} // namespace debug
} // namespace xe
#endif // XENIA_DEBUG_TRACE_WRITER_H_

View File

@ -100,8 +100,7 @@ X_STATUS Emulator::Setup() {
} }
// Setup the core components. // Setup the core components.
result = processor_->Setup(); if (!processor_->Setup()) {
if (result) {
return result; return result;
} }
result = audio_system_->Setup(); result = audio_system_->Setup();

View File

@ -130,10 +130,10 @@ X_STATUS XUserModule::LoadFromMemory(const void* addr, const size_t length) {
// Prepare the module for execution. // Prepare the module for execution.
// Runtime takes ownership. // Runtime takes ownership.
auto xex_module = std::make_unique<XexModule>(processor); auto xex_module = std::make_unique<XexModule>(processor);
if (xex_module->Load(name_, path_, xex_)) { if (!xex_module->Load(name_, path_, xex_)) {
return X_STATUS_UNSUCCESSFUL; return X_STATUS_UNSUCCESSFUL;
} }
if (processor->AddModule(std::move(xex_module))) { if (!processor->AddModule(std::move(xex_module))) {
return X_STATUS_UNSUCCESSFUL; return X_STATUS_UNSUCCESSFUL;
} }