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(); }
int Assembler::Initialize() { return 0; }
bool Assembler::Initialize() { return true; }
void Assembler::Reset() {}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,10 +24,9 @@ X64Backend::X64Backend(Processor* processor)
X64Backend::~X64Backend() { delete code_cache_; }
int X64Backend::Initialize() {
int result = Backend::Initialize();
if (result) {
return result;
bool X64Backend::Initialize() {
if (!Backend::Initialize()) {
return false;
}
RegisterSequences();
@ -42,9 +41,8 @@ int X64Backend::Initialize() {
};
code_cache_ = new X64CodeCache();
result = code_cache_->Initialize();
if (result) {
return result;
if (!code_cache_->Initialize()) {
return false;
}
// 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();
guest_to_host_thunk_ = thunk_emitter->EmitGuestToHostThunk();
return result;
return true;
}
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_; }
GuestToHostThunk guest_to_host_thunk() const { return guest_to_host_thunk_; }
int Initialize() override;
bool Initialize() override;
std::unique_ptr<Assembler> CreateAssembler() override;

View File

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

View File

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

View File

@ -70,13 +70,11 @@ X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator)
trace_flags_(0),
cpu_() {}
X64Emitter::~X64Emitter() {}
X64Emitter::~X64Emitter() = default;
int X64Emitter::Initialize() { return 0; }
int X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags,
DebugInfo* debug_info, uint32_t trace_flags,
void*& out_code_address, size_t& out_code_size) {
bool X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags,
DebugInfo* debug_info, uint32_t trace_flags,
void*& out_code_address, size_t& out_code_size) {
SCOPE_profile_cpu_f("cpu");
// Reset.
@ -88,9 +86,8 @@ int X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags,
// Fill the generator with code.
size_t stack_size = 0;
int result = Emit(builder, stack_size);
if (result) {
return result;
if (!Emit(builder, stack_size)) {
return false;
}
// 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());
}
return 0;
return true;
}
void* X64Emitter::Emplace(size_t stack_size) {
@ -120,7 +117,7 @@ void* X64Emitter::Emplace(size_t stack_size) {
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.
// This could be much better (sort by type/etc).
auto locals = builder->locals();
@ -204,7 +201,7 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) {
nop();
#endif // XE_DEBUG
return 0;
return true;
}
void X64Emitter::MarkSourceOffset(const Instr* i) {

View File

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

View File

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

View File

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

View File

@ -27,18 +27,18 @@ void Compiler::AddPass(std::unique_ptr<CompilerPass> pass) {
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
// stop changing things, etc.
for (size_t i = 0; i < passes_.size(); ++i) {
auto& pass = passes_[i];
scratch_arena_.Reset();
if (pass->Run(builder)) {
return 1;
if (!pass->Run(builder)) {
return false;
}
}
return 0;
return true;
}
} // namespace compiler

View File

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

View File

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

View File

@ -30,9 +30,9 @@ class CompilerPass {
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:
Arena* scratch_arena() const;

View File

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

View File

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

View File

@ -36,9 +36,9 @@ ContextPromotionPass::ContextPromotionPass() : CompilerPass() {}
ContextPromotionPass::~ContextPromotionPass() {}
int ContextPromotionPass::Initialize(Compiler* compiler) {
if (CompilerPass::Initialize(compiler)) {
return 1;
bool ContextPromotionPass::Initialize(Compiler* compiler) {
if (!CompilerPass::Initialize(compiler)) {
return false;
}
// This is a terrible implementation.
@ -46,10 +46,10 @@ int ContextPromotionPass::Initialize(Compiler* compiler) {
context_values_.resize(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
// check and convert LoadContext/StoreContext into value operations.
// Example of load->value promotion:
@ -82,7 +82,7 @@ int ContextPromotionPass::Run(HIRBuilder* builder) {
}
}
return 0;
return true;
}
void ContextPromotionPass::PromoteBlock(Block* block) {

View File

@ -34,9 +34,9 @@ class ContextPromotionPass : public CompilerPass {
ContextPromotionPass();
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:
void PromoteBlock(hir::Block* block);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -27,7 +27,7 @@ DeadCodeEliminationPass::DeadCodeEliminationPass() : CompilerPass() {}
DeadCodeEliminationPass::~DeadCodeEliminationPass() {}
int DeadCodeEliminationPass::Run(HIRBuilder* builder) {
bool DeadCodeEliminationPass::Run(HIRBuilder* builder) {
// ContextPromotion/DSE will likely leave around a lot of dead statements.
// Code generated for comparison/testing produces many unused statements and
// 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) {

View File

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

View File

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

View File

@ -22,7 +22,7 @@ class FinalizationPass : public CompilerPass {
FinalizationPass();
~FinalizationPass() override;
int Run(hir::HIRBuilder* builder) override;
bool Run(hir::HIRBuilder* builder) override;
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.
// Registers do not move across blocks, though this could be
// 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.
XELOGE("Unable to spill any registers");
assert_always();
return 1;
return false;
}
// Demand allocation.
@ -159,7 +159,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) {
// Boned.
XELOGE("Register allocation failed");
assert_always();
return 1;
return false;
}
}
}
@ -169,7 +169,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) {
block = block->next;
}
return 0;
return true;
}
void RegisterAllocationPass::DumpUsage(const char* name) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -58,7 +58,7 @@ void ValueReductionPass::ComputeLastUse(Value* value) {
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.
llvm::BitVector ordinals(builder->max_value_ordinal());
@ -139,7 +139,7 @@ int ValueReductionPass::Run(HIRBuilder* builder) {
block = block->next;
}
return 0;
return true;
}
} // namespace passes

View File

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

View File

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

View File

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

View File

@ -36,7 +36,7 @@ class PPCHIRBuilder : public hir::HIRBuilder {
// Emit comment nodes.
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* LookupFunction(uint32_t address);

View File

@ -35,13 +35,13 @@ PPCScanner::~PPCScanner() {}
bool PPCScanner::IsRestGprLr(uint32_t address) {
FunctionInfo* symbol_info;
if (frontend_->processor()->LookupFunctionInfo(address, &symbol_info)) {
if (!frontend_->processor()->LookupFunctionInfo(address, &symbol_info)) {
return false;
}
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
// end address looking for branches. Each span of instructions between
// 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
LOGPPC("Finished analyzing %.8X", start_address);
return 0;
return true;
}
std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {

View File

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

View File

@ -86,9 +86,9 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
PPCTranslator::~PPCTranslator() = default;
int PPCTranslator::Translate(FunctionInfo* symbol_info,
uint32_t debug_info_flags, uint32_t trace_flags,
Function** out_function) {
bool PPCTranslator::Translate(FunctionInfo* symbol_info,
uint32_t debug_info_flags, uint32_t trace_flags,
Function** out_function) {
SCOPE_profile_cpu_f("cpu");
// 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(&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.
if (FLAGS_always_disasm) {
debug_info_flags |= DEBUG_INFO_ALL_DISASM;
@ -118,6 +106,11 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
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.
if (debug_info_flags & DEBUG_INFO_SOURCE_DISASM) {
DumpSource(symbol_info, &string_buffer_);
@ -134,9 +127,8 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
if (debug_info) {
emit_flags |= PPCHIRBuilder::EMIT_DEBUG_COMMENTS;
}
int result = builder_->Emit(symbol_info, emit_flags);
if (result) {
return result;
if (!builder_->Emit(symbol_info, emit_flags)) {
return false;
}
// Stash raw HIR.
@ -147,9 +139,8 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
}
// Compile/optimize/etc.
result = compiler_->Compile(builder_.get());
if (result) {
return result;
if (!compiler_->Compile(builder_.get())) {
return false;
}
// Stash optimized HIR.
@ -160,14 +151,12 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
}
// Assemble to backend machine code.
result =
assembler_->Assemble(symbol_info, builder_.get(), debug_info_flags,
std::move(debug_info), trace_flags, out_function);
if (result) {
return result;
if (!assembler_->Assemble(symbol_info, builder_.get(), debug_info_flags,
std::move(debug_info), trace_flags, out_function)) {
return false;
}
return 0;
return true;
};
void PPCTranslator::DumpSource(FunctionInfo* symbol_info,

View File

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

View File

@ -188,7 +188,7 @@ class TestRunner {
bool Setup(TestSuite& suite) {
// Load the binary module.
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());
return false;
}
@ -212,9 +212,8 @@ class TestRunner {
}
// Execute test.
xe::cpu::Function* fn;
processor->ResolveFunction(test_case.address, &fn);
if (!fn) {
xe::cpu::Function* fn = nullptr;
if (!processor->ResolveFunction(test_case.address, &fn)) {
XELOGE("Entry function not found");
return false;
}

View File

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

View File

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

View File

@ -51,7 +51,7 @@ void HIRBuilder::Reset() {
arena_->Reset();
}
int HIRBuilder::Finalize() {
bool HIRBuilder::Finalize() {
// 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
// need to ensure they fall through in the right order.
@ -84,7 +84,7 @@ int HIRBuilder::Finalize() {
current_block_ = NULL;
}
}
return 0;
return true;
}
void HIRBuilder::DumpValue(StringBuffer* str, Value* value) {

View File

@ -34,7 +34,7 @@ class HIRBuilder {
virtual ~HIRBuilder();
virtual void Reset();
virtual int Finalize();
virtual bool Finalize();
void Dump(StringBuffer* str);
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);
// Skip until ' Address'. Skip the next blank line.
@ -225,7 +225,7 @@ int Module::ReadMap(const char* file_name) {
if (type_str == "f") {
// Function.
FunctionInfo* fn_info;
if (processor_->LookupFunctionInfo(this, address, &fn_info)) {
if (!processor_->LookupFunctionInfo(this, address, &fn_info)) {
continue;
}
// 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

View File

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

View File

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

View File

@ -52,9 +52,9 @@ class Processor {
backend::Backend* backend() const { return backend_.get(); }
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 std::string& name) { return GetModule(name.c_str()); }
std::vector<Module*> GetModules();
@ -66,12 +66,12 @@ class Processor {
std::vector<Function*> FindFunctionsWithAddress(uint32_t address);
int LookupFunctionInfo(uint32_t address, FunctionInfo** out_symbol_info);
int LookupFunctionInfo(Module* module, uint32_t address,
FunctionInfo** out_symbol_info);
int ResolveFunction(uint32_t address, Function** out_function);
bool LookupFunctionInfo(uint32_t address, FunctionInfo** out_symbol_info);
bool LookupFunctionInfo(Module* module, uint32_t address,
FunctionInfo** out_symbol_info);
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[],
size_t arg_count);
@ -82,7 +82,7 @@ class Processor {
size_t arg_count);
private:
int DemandFunction(FunctionInfo* symbol_info, Function** out_function);
bool DemandFunction(FunctionInfo* symbol_info, Function** out_function);
Memory* memory_;

View File

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

View File

@ -22,7 +22,7 @@ class RawModule : public Module {
RawModule(Processor* processor);
~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_; }

View File

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

View File

@ -40,10 +40,8 @@ XexModule::XexModule(Processor* processor)
XexModule::~XexModule() { xe_xex2_dealloc(xex_); }
int XexModule::Load(const std::string& name, const std::string& path,
xe_xex2_ref xex) {
int result;
bool XexModule::Load(const std::string& name, const std::string& path,
xe_xex2_ref xex) {
xex_ = 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).
for (size_t n = 0; n < header->import_library_count; n++) {
result = SetupLibraryImports(&header->import_libraries[n]);
if (result) {
return result;
if (!SetupLibraryImports(&header->import_libraries[n])) {
return false;
}
}
// Find __savegprlr_* and __restgprlr_* and the others.
// We can flag these for special handling (inlining/etc).
result = FindSaveRest();
if (result) {
return result;
if (!FindSaveRest()) {
return false;
}
// 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.
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();
xe_xex2_import_info_t* import_infos;
size_t import_info_count;
if (xe_xex2_get_import_infos(xex_, library, &import_infos,
&import_info_count)) {
return 1;
return false;
}
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) {
return address >= low_address_ && address < high_address_;
}
int XexModule::FindSaveRest() {
bool XexModule::FindSaveRest() {
// Special stack save/restore functions.
// 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
@ -523,7 +521,7 @@ int XexModule::FindSaveRest() {
}
}
return 0;
return true;
}
} // namespace cpu

View File

@ -27,16 +27,16 @@ class XexModule : public xe::cpu::Module {
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_; }
bool ContainsAddress(uint32_t address) override;
private:
int SetupImports(xe_xex2_ref xex);
int SetupLibraryImports(const xe_xex2_import_library_t* library);
int FindSaveRest();
bool SetupImports(xe_xex2_ref xex);
bool SetupLibraryImports(const xe_xex2_import_library_t* library);
bool FindSaveRest();
private:
Processor* processor_;

View File

@ -5,7 +5,5 @@
'debug_server.h',
'debugger.cc',
'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.
result = processor_->Setup();
if (result) {
if (!processor_->Setup()) {
return result;
}
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.
// Runtime takes ownership.
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;
}
if (processor->AddModule(std::move(xex_module))) {
if (!processor->AddModule(std::move(xex_module))) {
return X_STATUS_UNSUCCESSFUL;
}