diff --git a/src/xenia/cpu/debug_info.cc b/src/xenia/cpu/debug_info.cc
index 8df03b4c9..927640ed9 100644
--- a/src/xenia/cpu/debug_info.cc
+++ b/src/xenia/cpu/debug_info.cc
@@ -71,5 +71,21 @@ SourceMapEntry* DebugInfo::LookupCodeOffset(uint32_t offset) {
return nullptr;
}
+void DebugInfo::Dump() {
+ if (source_disasm_) {
+ printf("PPC:\n%s\n", source_disasm_);
+ }
+ if (raw_hir_disasm_) {
+ printf("Unoptimized HIR:\n%s\n", raw_hir_disasm_);
+ }
+ if (hir_disasm_) {
+ printf("Optimized HIR:\n%s\n", hir_disasm_);
+ }
+ if (machine_code_disasm_) {
+ printf("Machine Code:\n%s\n", machine_code_disasm_);
+ }
+ fflush(stdout);
+}
+
} // namespace cpu
} // namespace xe
diff --git a/src/xenia/cpu/debug_info.h b/src/xenia/cpu/debug_info.h
index d18b249cb..34d6cacf8 100644
--- a/src/xenia/cpu/debug_info.h
+++ b/src/xenia/cpu/debug_info.h
@@ -31,6 +31,10 @@ enum DebugInfoFlags {
kDebugInfoTraceFunctionCoverage = (1 << 7) | kDebugInfoTraceFunctions,
kDebugInfoTraceFunctionReferences = (1 << 8) | kDebugInfoTraceFunctions,
kDebugInfoTraceFunctionData = (1 << 9) | kDebugInfoTraceFunctions,
+
+ kDebugInfoAllTracing =
+ kDebugInfoTraceFunctions | kDebugInfoTraceFunctionCoverage |
+ kDebugInfoTraceFunctionReferences | kDebugInfoTraceFunctionData,
kDebugInfoAll = 0xFFFFFFFF,
};
@@ -72,6 +76,8 @@ class DebugInfo {
SourceMapEntry* LookupHIROffset(uint32_t offset);
SourceMapEntry* LookupCodeOffset(uint32_t offset);
+ void Dump();
+
private:
uint32_t address_reference_count_;
uint32_t instruction_result_count_;
diff --git a/src/xenia/cpu/frontend/ppc_translator.cc b/src/xenia/cpu/frontend/ppc_translator.cc
index bd3f37fa2..e8a552675 100644
--- a/src/xenia/cpu/frontend/ppc_translator.cc
+++ b/src/xenia/cpu/frontend/ppc_translator.cc
@@ -124,6 +124,11 @@ bool PPCTranslator::Translate(FunctionInfo* symbol_info,
return false;
}
+ auto debugger = frontend_->processor()->debugger();
+ if (!debugger) {
+ debug_info_flags &= ~DebugInfoFlags::kDebugInfoAllTracing;
+ }
+
// Setup trace data, if needed.
if (debug_info_flags & DebugInfoFlags::kDebugInfoTraceFunctions) {
// Base trace data.
@@ -133,9 +138,7 @@ bool PPCTranslator::Translate(FunctionInfo* symbol_info,
trace_data_size += debug::FunctionTraceData::SizeOfInstructionCounts(
symbol_info->address(), symbol_info->end_address());
}
- uint8_t* trace_data =
- frontend_->processor()->debugger()->AllocateFunctionTraceData(
- trace_data_size);
+ 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(),
diff --git a/src/xenia/cpu/frontend/test/sequence_branch_carry.s b/src/xenia/cpu/frontend/test/sequence_branch_carry.s
new file mode 100644
index 000000000..23ed8c0ba
--- /dev/null
+++ b/src/xenia/cpu/frontend/test/sequence_branch_carry.s
@@ -0,0 +1,41 @@
+test_equiv_1:
+ #_ REGISTER_IN r11 0x9E2A83C1
+ lis r9, -0x61D6 # 0x9E2A83C1
+ ori r30, r9, 0x83C1 # 0x9E2A83C1
+ subf r8, r11, r30
+ addic r7, r8, -1
+ subfe. r31, r7, r8
+ beq .test_equiv_1_good
+ li r12, 0
+ blr
+.test_equiv_1_good:
+ li r12, 1
+ blr
+ #_ REGISTER_OUT r7 0xfffffffeffffffff
+ #_ REGISTER_OUT r8 0xffffffff00000000
+ #_ REGISTER_OUT r9 0xffffffff9e2a0000
+ #_ REGISTER_OUT r30 0xffffffff9e2a83c1
+ #_ REGISTER_OUT r31 0
+ #_ REGISTER_OUT r11 0x000000009e2a83c1
+ #_ REGISTER_OUT r12 1
+
+test_equiv_2:
+ #_ REGISTER_IN r11 0xffffffff9e2a83c1
+ lis r9, -0x61D6 # 0x9E2A83C1
+ ori r30, r9, 0x83C1 # 0x9E2A83C1
+ subf r8, r11, r30
+ addic r7, r8, -1
+ subfe. r31, r7, r8
+ beq .test_equiv_2_good
+ li r12, 0
+ blr
+.test_equiv_2_good:
+ li r12, 1
+ blr
+ #_ REGISTER_OUT r7 0xffffffffffffffff
+ #_ REGISTER_OUT r8 0xffffffff00000000
+ #_ REGISTER_OUT r9 0xffffffff9e2a0000
+ #_ REGISTER_OUT r30 0xffffffff9e2a83c1
+ #_ REGISTER_OUT r31 0
+ #_ REGISTER_OUT r11 0xffffffff9e2a83c1
+ #_ REGISTER_OUT r12 1
diff --git a/src/xenia/cpu/frontend/test/xe-cpu-ppc-test.cc b/src/xenia/cpu/frontend/test/xe-cpu-ppc-test.cc
index e43f199f5..e4eb6444e 100644
--- a/src/xenia/cpu/frontend/test/xe-cpu-ppc-test.cc
+++ b/src/xenia/cpu/frontend/test/xe-cpu-ppc-test.cc
@@ -177,6 +177,7 @@ class TestRunner {
processor.reset(new Processor(memory.get(), nullptr, nullptr));
processor->Setup();
+ processor->set_debug_info_flags(DebugInfoFlags::kDebugInfoAll);
}
~TestRunner() {
@@ -228,6 +229,10 @@ class TestRunner {
// Assert test state expectations.
bool result = CheckTestResults(test_case);
+ if (!result) {
+ // Also dump all disasm/etc.
+ fn->debug_info()->Dump();
+ }
return result;
}
diff --git a/src/xenia/cpu/frontend/test/xe-cpu-ppc-test.vcxproj b/src/xenia/cpu/frontend/test/xe-cpu-ppc-test.vcxproj
index ac2d50db0..fd62b6abd 100644
--- a/src/xenia/cpu/frontend/test/xe-cpu-ppc-test.vcxproj
+++ b/src/xenia/cpu/frontend/test/xe-cpu-ppc-test.vcxproj
@@ -208,6 +208,7 @@
+
diff --git a/src/xenia/cpu/frontend/test/xe-cpu-ppc-test.vcxproj.filters b/src/xenia/cpu/frontend/test/xe-cpu-ppc-test.vcxproj.filters
index 771f18e12..fef3b19f3 100644
--- a/src/xenia/cpu/frontend/test/xe-cpu-ppc-test.vcxproj.filters
+++ b/src/xenia/cpu/frontend/test/xe-cpu-ppc-test.vcxproj.filters
@@ -94,6 +94,7 @@
+
diff --git a/src/xenia/cpu/processor.h b/src/xenia/cpu/processor.h
index 871922354..c48dd144e 100644
--- a/src/xenia/cpu/processor.h
+++ b/src/xenia/cpu/processor.h
@@ -51,6 +51,10 @@ class Processor {
bool Setup();
+ void set_debug_info_flags(uint32_t debug_info_flags) {
+ debug_info_flags_ = debug_info_flags;
+ }
+
bool AddModule(std::unique_ptr module);
Module* GetModule(const char* name);
Module* GetModule(const std::string& name) { return GetModule(name.c_str()); }