bool-ifying xe::cpu
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user