Refactoring SymbolInfo/FunctionInfo/Function into Symbol/Function.
This commit is contained in:
@@ -53,7 +53,7 @@ int InstrEmit_branch(PPCHIRBuilder& f, const char* src, uint64_t cia,
|
||||
// recursion.
|
||||
uint32_t nia_value = nia->AsUint64() & 0xFFFFFFFF;
|
||||
bool is_recursion = false;
|
||||
if (nia_value == f.symbol_info()->address() && lk) {
|
||||
if (nia_value == f.function()->address() && lk) {
|
||||
is_recursion = true;
|
||||
}
|
||||
Label* label = is_recursion ? NULL : f.LookupLabel(nia_value);
|
||||
@@ -71,14 +71,14 @@ int InstrEmit_branch(PPCHIRBuilder& f, const char* src, uint64_t cia,
|
||||
}
|
||||
} else {
|
||||
// Call function.
|
||||
auto symbol_info = f.LookupFunction(nia_value);
|
||||
auto function = f.LookupFunction(nia_value);
|
||||
if (cond) {
|
||||
if (!expect_true) {
|
||||
cond = f.IsFalse(cond);
|
||||
}
|
||||
f.CallTrue(cond, symbol_info, call_flags);
|
||||
f.CallTrue(cond, function, call_flags);
|
||||
} else {
|
||||
f.Call(symbol_info, call_flags);
|
||||
f.Call(function, call_flags);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -419,7 +419,7 @@ XEEMITTER(mcrf, 0x4C000000, XL)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// System linkage (A-24)
|
||||
|
||||
XEEMITTER(sc, 0x44000002, SC)(PPCHIRBuilder& f, InstrData& i) {
|
||||
f.CallExtern(f.symbol_info());
|
||||
f.CallExtern(f.function());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ bool PPCFrontend::Initialize() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PPCFrontend::DeclareFunction(FunctionInfo* symbol_info) {
|
||||
bool PPCFrontend::DeclareFunction(GuestFunction* function) {
|
||||
// Could scan or something here.
|
||||
// Could also check to see if it's a well-known function type and classify
|
||||
// for later.
|
||||
@@ -95,12 +95,10 @@ bool PPCFrontend::DeclareFunction(FunctionInfo* symbol_info) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PPCFrontend::DefineFunction(FunctionInfo* symbol_info,
|
||||
uint32_t debug_info_flags,
|
||||
Function** out_function) {
|
||||
PPCTranslator* translator = translator_pool_.Allocate(this);
|
||||
bool result =
|
||||
translator->Translate(symbol_info, debug_info_flags, out_function);
|
||||
bool PPCFrontend::DefineFunction(GuestFunction* function,
|
||||
uint32_t debug_info_flags) {
|
||||
auto translator = translator_pool_.Allocate(this);
|
||||
bool result = translator->Translate(function, debug_info_flags);
|
||||
translator_pool_.Release(translator);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "xenia/base/type_pool.h"
|
||||
#include "xenia/cpu/frontend/context_info.h"
|
||||
#include "xenia/cpu/function.h"
|
||||
#include "xenia/cpu/symbol_info.h"
|
||||
#include "xenia/memory.h"
|
||||
|
||||
namespace xe {
|
||||
@@ -35,8 +34,8 @@ class PPCTranslator;
|
||||
struct PPCBuiltins {
|
||||
xe::mutex global_lock;
|
||||
bool global_lock_taken;
|
||||
FunctionInfo* check_global_lock;
|
||||
FunctionInfo* handle_global_lock;
|
||||
Function* check_global_lock;
|
||||
Function* handle_global_lock;
|
||||
};
|
||||
|
||||
class PPCFrontend {
|
||||
@@ -51,9 +50,8 @@ class PPCFrontend {
|
||||
ContextInfo* context_info() const { return context_info_.get(); }
|
||||
PPCBuiltins* builtins() { return &builtins_; }
|
||||
|
||||
bool DeclareFunction(FunctionInfo* symbol_info);
|
||||
bool DefineFunction(FunctionInfo* symbol_info, uint32_t debug_info_flags,
|
||||
Function** out_function);
|
||||
bool DeclareFunction(GuestFunction* function);
|
||||
bool DefineFunction(GuestFunction* function, uint32_t debug_info_flags);
|
||||
|
||||
private:
|
||||
Processor* processor_;
|
||||
|
||||
@@ -40,27 +40,29 @@ PPCHIRBuilder::PPCHIRBuilder(PPCFrontend* frontend)
|
||||
PPCHIRBuilder::~PPCHIRBuilder() = default;
|
||||
|
||||
void PPCHIRBuilder::Reset() {
|
||||
function_ = nullptr;
|
||||
start_address_ = 0;
|
||||
instr_count_ = 0;
|
||||
instr_offset_list_ = NULL;
|
||||
label_list_ = NULL;
|
||||
with_debug_info_ = false;
|
||||
HIRBuilder::Reset();
|
||||
}
|
||||
|
||||
bool PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
|
||||
bool PPCHIRBuilder::Emit(GuestFunction* function, uint32_t flags) {
|
||||
SCOPE_profile_cpu_f("cpu");
|
||||
|
||||
Memory* memory = frontend_->memory();
|
||||
|
||||
symbol_info_ = symbol_info;
|
||||
start_address_ = symbol_info->address();
|
||||
instr_count_ = (symbol_info->end_address() - symbol_info->address()) / 4 + 1;
|
||||
function_ = function;
|
||||
start_address_ = function_->address();
|
||||
instr_count_ = (function_->end_address() - function_->address()) / 4 + 1;
|
||||
|
||||
with_debug_info_ = (flags & EMIT_DEBUG_COMMENTS) == EMIT_DEBUG_COMMENTS;
|
||||
if (with_debug_info_) {
|
||||
CommentFormat("%s fn %.8X-%.8X %s", symbol_info->module()->name().c_str(),
|
||||
symbol_info->address(), symbol_info->end_address(),
|
||||
symbol_info->name().c_str());
|
||||
CommentFormat("%s fn %.8X-%.8X %s", function_->module()->name().c_str(),
|
||||
function_->address(), function_->end_address(),
|
||||
function_->name().c_str());
|
||||
}
|
||||
|
||||
// Allocate offset list.
|
||||
@@ -78,8 +80,8 @@ bool PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
|
||||
// Always mark entry with label.
|
||||
label_list_[0] = NewLabel();
|
||||
|
||||
uint32_t start_address = symbol_info->address();
|
||||
uint32_t end_address = symbol_info->end_address();
|
||||
uint32_t start_address = function_->address();
|
||||
uint32_t end_address = function_->end_address();
|
||||
InstrData i;
|
||||
for (uint32_t address = start_address, offset = 0; address <= end_address;
|
||||
address += 4, offset++) {
|
||||
@@ -165,13 +167,8 @@ void PPCHIRBuilder::AnnotateLabel(uint32_t address, Label* label) {
|
||||
memcpy(label->name, name_buffer, sizeof(name_buffer));
|
||||
}
|
||||
|
||||
FunctionInfo* PPCHIRBuilder::LookupFunction(uint32_t address) {
|
||||
Processor* processor = frontend_->processor();
|
||||
FunctionInfo* symbol_info;
|
||||
if (!processor->LookupFunctionInfo(address, &symbol_info)) {
|
||||
return nullptr;
|
||||
}
|
||||
return symbol_info;
|
||||
Function* PPCHIRBuilder::LookupFunction(uint32_t address) {
|
||||
return frontend_->processor()->LookupFunction(address);
|
||||
}
|
||||
|
||||
Label* PPCHIRBuilder::LookupLabel(uint32_t address) {
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "xenia/base/string_buffer.h"
|
||||
#include "xenia/cpu/hir/hir_builder.h"
|
||||
#include "xenia/cpu/function.h"
|
||||
#include "xenia/cpu/symbol_info.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
@@ -28,18 +27,18 @@ class PPCHIRBuilder : public hir::HIRBuilder {
|
||||
|
||||
public:
|
||||
PPCHIRBuilder(PPCFrontend* frontend);
|
||||
virtual ~PPCHIRBuilder();
|
||||
~PPCHIRBuilder() override;
|
||||
|
||||
virtual void Reset();
|
||||
void Reset() override;
|
||||
|
||||
enum EmitFlags {
|
||||
// Emit comment nodes.
|
||||
EMIT_DEBUG_COMMENTS = 1 << 0,
|
||||
};
|
||||
bool Emit(FunctionInfo* symbol_info, uint32_t flags);
|
||||
bool Emit(GuestFunction* function, uint32_t flags);
|
||||
|
||||
FunctionInfo* symbol_info() const { return symbol_info_; }
|
||||
FunctionInfo* LookupFunction(uint32_t address);
|
||||
GuestFunction* function() const { return function_; }
|
||||
Function* LookupFunction(uint32_t address);
|
||||
Label* LookupLabel(uint32_t address);
|
||||
|
||||
Value* LoadLR();
|
||||
@@ -83,7 +82,6 @@ class PPCHIRBuilder : public hir::HIRBuilder {
|
||||
private:
|
||||
void AnnotateLabel(uint32_t address, Label* label);
|
||||
|
||||
private:
|
||||
PPCFrontend* frontend_;
|
||||
|
||||
// Reset whenever needed:
|
||||
@@ -91,7 +89,7 @@ class PPCHIRBuilder : public hir::HIRBuilder {
|
||||
|
||||
// Reset each Emit:
|
||||
bool with_debug_info_;
|
||||
FunctionInfo* symbol_info_;
|
||||
GuestFunction* function_;
|
||||
uint64_t start_address_;
|
||||
uint64_t instr_count_;
|
||||
Instr** instr_offset_list_;
|
||||
|
||||
@@ -35,11 +35,10 @@ PPCScanner::~PPCScanner() {}
|
||||
|
||||
bool PPCScanner::IsRestGprLr(uint32_t address) {
|
||||
auto function = frontend_->processor()->QueryFunction(address);
|
||||
return function &&
|
||||
function->symbol_info()->behavior() == FunctionBehavior::kEpilogReturn;
|
||||
return function && function->behavior() == Function::Behavior::kEpilogReturn;
|
||||
}
|
||||
|
||||
bool PPCScanner::Scan(FunctionInfo* symbol_info, DebugInfo* debug_info) {
|
||||
bool PPCScanner::Scan(GuestFunction* function, 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
|
||||
@@ -49,14 +48,14 @@ bool PPCScanner::Scan(FunctionInfo* symbol_info, DebugInfo* debug_info) {
|
||||
|
||||
Memory* memory = frontend_->memory();
|
||||
|
||||
LOGPPC("Analyzing function %.8X...", symbol_info->address());
|
||||
LOGPPC("Analyzing function %.8X...", function->address());
|
||||
|
||||
// For debug info, only if needed.
|
||||
uint32_t address_reference_count = 0;
|
||||
uint32_t instruction_result_count = 0;
|
||||
|
||||
uint32_t start_address = static_cast<uint32_t>(symbol_info->address());
|
||||
uint32_t end_address = static_cast<uint32_t>(symbol_info->end_address());
|
||||
uint32_t start_address = static_cast<uint32_t>(function->address());
|
||||
uint32_t end_address = static_cast<uint32_t>(function->end_address());
|
||||
uint32_t address = start_address;
|
||||
uint32_t furthest_target = start_address;
|
||||
size_t blocks_found = 0;
|
||||
@@ -270,7 +269,7 @@ bool PPCScanner::Scan(FunctionInfo* symbol_info, DebugInfo* debug_info) {
|
||||
LOGPPC("Function ran under: %.8X-%.8X ended at %.8X", start_address,
|
||||
end_address, address + 4);
|
||||
}
|
||||
symbol_info->set_end_address(address);
|
||||
function->set_end_address(address);
|
||||
|
||||
// If there's spare bits at the end, split the function.
|
||||
// TODO(benvanik): splitting?
|
||||
@@ -289,13 +288,13 @@ bool PPCScanner::Scan(FunctionInfo* symbol_info, DebugInfo* debug_info) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
|
||||
std::vector<BlockInfo> PPCScanner::FindBlocks(GuestFunction* function) {
|
||||
Memory* memory = frontend_->memory();
|
||||
|
||||
std::map<uint32_t, BlockInfo> block_map;
|
||||
|
||||
uint32_t start_address = symbol_info->address();
|
||||
uint32_t end_address = symbol_info->end_address();
|
||||
uint32_t start_address = function->address();
|
||||
uint32_t end_address = function->end_address();
|
||||
bool in_block = false;
|
||||
uint32_t block_start = 0;
|
||||
InstrData i;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "xenia/cpu/debug_info.h"
|
||||
#include "xenia/cpu/symbol_info.h"
|
||||
#include "xenia/cpu/function.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
@@ -21,25 +21,24 @@ namespace frontend {
|
||||
|
||||
class PPCFrontend;
|
||||
|
||||
typedef struct BlockInfo_t {
|
||||
struct BlockInfo {
|
||||
uint32_t start_address;
|
||||
uint32_t end_address;
|
||||
} BlockInfo;
|
||||
};
|
||||
|
||||
class PPCScanner {
|
||||
public:
|
||||
PPCScanner(PPCFrontend* frontend);
|
||||
~PPCScanner();
|
||||
|
||||
bool Scan(FunctionInfo* symbol_info, DebugInfo* debug_info);
|
||||
bool Scan(GuestFunction* function, DebugInfo* debug_info);
|
||||
|
||||
std::vector<BlockInfo> FindBlocks(FunctionInfo* symbol_info);
|
||||
std::vector<BlockInfo> FindBlocks(GuestFunction* function);
|
||||
|
||||
private:
|
||||
bool IsRestGprLr(uint32_t address);
|
||||
|
||||
private:
|
||||
PPCFrontend* frontend_;
|
||||
PPCFrontend* frontend_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace frontend
|
||||
|
||||
@@ -99,9 +99,8 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
|
||||
|
||||
PPCTranslator::~PPCTranslator() = default;
|
||||
|
||||
bool PPCTranslator::Translate(FunctionInfo* symbol_info,
|
||||
uint32_t debug_info_flags,
|
||||
Function** out_function) {
|
||||
bool PPCTranslator::Translate(GuestFunction* function,
|
||||
uint32_t debug_info_flags) {
|
||||
SCOPE_profile_cpu_f("cpu");
|
||||
|
||||
// Reset() all caching when we leave.
|
||||
@@ -137,7 +136,7 @@ bool PPCTranslator::Translate(FunctionInfo* symbol_info,
|
||||
}
|
||||
|
||||
// Scan the function to find its extents and gather debug data.
|
||||
if (!scanner_->Scan(symbol_info, debug_info.get())) {
|
||||
if (!scanner_->Scan(function, debug_info.get())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -153,19 +152,19 @@ bool PPCTranslator::Translate(FunctionInfo* symbol_info,
|
||||
if (debug_info_flags & DebugInfoFlags::kDebugInfoTraceFunctionCoverage) {
|
||||
// Additional space for instruction coverage counts.
|
||||
trace_data_size += debug::FunctionTraceData::SizeOfInstructionCounts(
|
||||
symbol_info->address(), symbol_info->end_address());
|
||||
function->address(), function->end_address());
|
||||
}
|
||||
uint8_t* trace_data = debugger->AllocateFunctionTraceData(trace_data_size);
|
||||
if (trace_data) {
|
||||
debug_info->trace_data().Reset(trace_data, trace_data_size,
|
||||
symbol_info->address(),
|
||||
symbol_info->end_address());
|
||||
function->trace_data().Reset(trace_data, trace_data_size,
|
||||
function->address(),
|
||||
function->end_address());
|
||||
}
|
||||
}
|
||||
|
||||
// Stash source.
|
||||
if (debug_info_flags & DebugInfoFlags::kDebugInfoDisasmSource) {
|
||||
DumpSource(symbol_info, &string_buffer_);
|
||||
DumpSource(function, &string_buffer_);
|
||||
debug_info->set_source_disasm(string_buffer_.ToString());
|
||||
string_buffer_.Reset();
|
||||
}
|
||||
@@ -179,7 +178,7 @@ bool PPCTranslator::Translate(FunctionInfo* symbol_info,
|
||||
if (debug_info) {
|
||||
emit_flags |= PPCHIRBuilder::EMIT_DEBUG_COMMENTS;
|
||||
}
|
||||
if (!builder_->Emit(symbol_info, emit_flags)) {
|
||||
if (!builder_->Emit(function, emit_flags)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -203,27 +202,26 @@ bool PPCTranslator::Translate(FunctionInfo* symbol_info,
|
||||
}
|
||||
|
||||
// Assemble to backend machine code.
|
||||
if (!assembler_->Assemble(symbol_info, builder_.get(), debug_info_flags,
|
||||
std::move(debug_info), out_function)) {
|
||||
if (!assembler_->Assemble(function, builder_.get(), debug_info_flags,
|
||||
std::move(debug_info))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
void PPCTranslator::DumpSource(FunctionInfo* symbol_info,
|
||||
void PPCTranslator::DumpSource(GuestFunction* function,
|
||||
StringBuffer* string_buffer) {
|
||||
Memory* memory = frontend_->memory();
|
||||
|
||||
string_buffer->AppendFormat(
|
||||
"%s fn %.8X-%.8X %s\n", symbol_info->module()->name().c_str(),
|
||||
symbol_info->address(), symbol_info->end_address(),
|
||||
symbol_info->name().c_str());
|
||||
"%s fn %.8X-%.8X %s\n", function->module()->name().c_str(),
|
||||
function->address(), function->end_address(), function->name().c_str());
|
||||
|
||||
auto blocks = scanner_->FindBlocks(symbol_info);
|
||||
auto blocks = scanner_->FindBlocks(function);
|
||||
|
||||
uint32_t start_address = symbol_info->address();
|
||||
uint32_t end_address = symbol_info->end_address();
|
||||
uint32_t start_address = function->address();
|
||||
uint32_t end_address = function->end_address();
|
||||
InstrData i;
|
||||
auto block_it = blocks.begin();
|
||||
for (uint32_t address = start_address, offset = 0; address <= end_address;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "xenia/base/string_buffer.h"
|
||||
#include "xenia/cpu/backend/assembler.h"
|
||||
#include "xenia/cpu/compiler/compiler.h"
|
||||
#include "xenia/cpu/symbol_info.h"
|
||||
#include "xenia/cpu/function.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
@@ -30,13 +30,11 @@ class PPCTranslator {
|
||||
PPCTranslator(PPCFrontend* frontend);
|
||||
~PPCTranslator();
|
||||
|
||||
bool Translate(FunctionInfo* symbol_info, uint32_t debug_info_flags,
|
||||
Function** out_function);
|
||||
bool Translate(GuestFunction* function, uint32_t debug_info_flags);
|
||||
|
||||
private:
|
||||
void DumpSource(FunctionInfo* symbol_info, StringBuffer* string_buffer);
|
||||
void DumpSource(GuestFunction* function, StringBuffer* string_buffer);
|
||||
|
||||
private:
|
||||
PPCFrontend* frontend_;
|
||||
std::unique_ptr<PPCScanner> scanner_;
|
||||
std::unique_ptr<PPCHIRBuilder> builder_;
|
||||
|
||||
@@ -224,8 +224,8 @@ class TestRunner {
|
||||
}
|
||||
|
||||
// Execute test.
|
||||
xe::cpu::Function* fn = nullptr;
|
||||
if (!processor->ResolveFunction(test_case.address, &fn)) {
|
||||
auto fn = processor->ResolveFunction(test_case.address);
|
||||
if (!fn) {
|
||||
XELOGE("Entry function not found");
|
||||
return false;
|
||||
}
|
||||
@@ -238,7 +238,9 @@ class TestRunner {
|
||||
bool result = CheckTestResults(test_case);
|
||||
if (!result) {
|
||||
// Also dump all disasm/etc.
|
||||
fn->debug_info()->Dump();
|
||||
if (fn->is_guest()) {
|
||||
static_cast<xe::cpu::GuestFunction*>(fn)->debug_info()->Dump();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user