From d816d8019079a4c6daea64510cc8b514122debef Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 31 May 2015 14:35:30 -0700 Subject: [PATCH] StringBuffer cleanup. --- src/xenia/base/string_buffer.cc | 10 +- src/xenia/base/string_buffer.h | 4 +- src/xenia/cpu/backend/x64/x64_assembler.cc | 4 +- src/xenia/cpu/frontend/ppc_disasm.cc | 253 +++++----- src/xenia/cpu/frontend/ppc_instr.cc | 3 +- src/xenia/cpu/frontend/ppc_translator.cc | 15 +- src/xenia/cpu/hir/hir_builder.cc | 72 +-- src/xenia/gpu/ucode_disassembler.cc | 555 ++++++++++----------- 8 files changed, 460 insertions(+), 456 deletions(-) diff --git a/src/xenia/base/string_buffer.cc b/src/xenia/base/string_buffer.cc index 98a16878b..22a5a47c8 100644 --- a/src/xenia/base/string_buffer.cc +++ b/src/xenia/base/string_buffer.cc @@ -32,11 +32,19 @@ void StringBuffer::Grow(size_t additional_length) { buffer_.reserve(new_capacity); } +void StringBuffer::Append(char c) { + AppendBytes(reinterpret_cast(&c), 1); +} + +void StringBuffer::Append(const char* value) { + AppendBytes(reinterpret_cast(value), std::strlen(value)); +} + void StringBuffer::Append(const std::string& value) { AppendBytes(reinterpret_cast(value.data()), value.size()); } -void StringBuffer::Append(const char* format, ...) { +void StringBuffer::AppendFormat(const char* format, ...) { va_list args; va_start(args, format); AppendVarargs(format, args); diff --git a/src/xenia/base/string_buffer.h b/src/xenia/base/string_buffer.h index 3a9938b7f..f54501299 100644 --- a/src/xenia/base/string_buffer.h +++ b/src/xenia/base/string_buffer.h @@ -25,8 +25,10 @@ class StringBuffer { void Reset(); + void Append(char c); + void Append(const char* value); void Append(const std::string& value); - void Append(const char* format, ...); + void AppendFormat(const char* format, ...); void AppendVarargs(const char* format, va_list args); void AppendBytes(const uint8_t* buffer, size_t length); diff --git a/src/xenia/cpu/backend/x64/x64_assembler.cc b/src/xenia/cpu/backend/x64/x64_assembler.cc index 2f0019094..3b4f73394 100644 --- a/src/xenia/cpu/backend/x64/x64_assembler.cc +++ b/src/xenia/cpu/backend/x64/x64_assembler.cc @@ -117,7 +117,7 @@ void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code, if (map_entry->source_offset == prev_source_offset) { str->Append(" "); } else { - str->Append("%.8X ", map_entry->source_offset); + str->AppendFormat("%.8X ", map_entry->source_offset); prev_source_offset = map_entry->source_offset; } } else { @@ -128,7 +128,7 @@ void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code, if (len == BE::UNKNOWN_OPCODE) { break; } - str->Append("%p %s\n", disasm.EIP, disasm.CompleteInstr); + str->AppendFormat("%p %s\n", disasm.EIP, disasm.CompleteInstr); disasm.EIP += len; } } diff --git a/src/xenia/cpu/frontend/ppc_disasm.cc b/src/xenia/cpu/frontend/ppc_disasm.cc index cd1773105..d354c1594 100644 --- a/src/xenia/cpu/frontend/ppc_disasm.cc +++ b/src/xenia/cpu/frontend/ppc_disasm.cc @@ -18,113 +18,116 @@ namespace cpu { namespace frontend { void Disasm_0(InstrData& i, StringBuffer* str) { - str->Append("%-8s ???", i.type->name); + str->AppendFormat("%-8s ???", i.type->name); } void Disasm__(InstrData& i, StringBuffer* str) { - str->Append("%-8s", i.type->name); + str->AppendFormat("%-8s", i.type->name); } void Disasm_X_FRT_FRB(InstrData& i, StringBuffer* str) { - str->Append("%*s%s f%d, f%d", i.X.Rc ? -7 : -8, i.type->name, - i.X.Rc ? "." : "", i.X.RT, i.X.RB); + str->AppendFormat("%*s%s f%d, f%d", i.X.Rc ? -7 : -8, i.type->name, + i.X.Rc ? "." : "", i.X.RT, i.X.RB); } void Disasm_A_FRT_FRB(InstrData& i, StringBuffer* str) { - str->Append("%*s%s f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, - i.A.Rc ? "." : "", i.A.FRT, i.A.FRB); + str->AppendFormat("%*s%s f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, + i.A.Rc ? "." : "", i.A.FRT, i.A.FRB); } void Disasm_A_FRT_FRA_FRB(InstrData& i, StringBuffer* str) { - str->Append("%*s%s f%d, f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, - i.A.Rc ? "." : "", i.A.FRT, i.A.FRA, i.A.FRB); + str->AppendFormat("%*s%s f%d, f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, + i.A.Rc ? "." : "", i.A.FRT, i.A.FRA, i.A.FRB); } void Disasm_A_FRT_FRA_FRB_FRC(InstrData& i, StringBuffer* str) { - str->Append("%*s%s f%d, f%d, f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, - i.A.Rc ? "." : "", i.A.FRT, i.A.FRA, i.A.FRB, i.A.FRC); + str->AppendFormat("%*s%s f%d, f%d, f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, + i.A.Rc ? "." : "", i.A.FRT, i.A.FRA, i.A.FRB, i.A.FRC); } void Disasm_X_RT_RA_RB(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d, r%d, r%d", i.type->name, i.X.RT, i.X.RA, i.X.RB); + str->AppendFormat("%-8s r%d, r%d, r%d", i.type->name, i.X.RT, i.X.RA, i.X.RB); } void Disasm_X_RT_RA0_RB(InstrData& i, StringBuffer* str) { if (i.X.RA) { - str->Append("%-8s r%d, r%d, r%d", i.type->name, i.X.RT, i.X.RA, i.X.RB); + str->AppendFormat("%-8s r%d, r%d, r%d", i.type->name, i.X.RT, i.X.RA, + i.X.RB); } else { - str->Append("%-8s r%d, 0, r%d", i.type->name, i.X.RT, i.X.RB); + str->AppendFormat("%-8s r%d, 0, r%d", i.type->name, i.X.RT, i.X.RB); } } void Disasm_X_FRT_RA_RB(InstrData& i, StringBuffer* str) { - str->Append("%-8s f%d, r%d, r%d", i.type->name, i.X.RT, i.X.RA, i.X.RB); + str->AppendFormat("%-8s f%d, r%d, r%d", i.type->name, i.X.RT, i.X.RA, i.X.RB); } void Disasm_X_FRT_RA0_RB(InstrData& i, StringBuffer* str) { if (i.X.RA) { - str->Append("%-8s f%d, r%d, r%d", i.type->name, i.X.RT, i.X.RA, i.X.RB); + str->AppendFormat("%-8s f%d, r%d, r%d", i.type->name, i.X.RT, i.X.RA, + i.X.RB); } else { - str->Append("%-8s f%d, 0, r%d", i.type->name, i.X.RT, i.X.RB); + str->AppendFormat("%-8s f%d, 0, r%d", i.type->name, i.X.RT, i.X.RB); } } void Disasm_D_RT_RA_I(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d, r%d, %d", i.type->name, i.D.RT, i.D.RA, - (int32_t)(int16_t) XEEXTS16(i.D.DS)); + str->AppendFormat("%-8s r%d, r%d, %d", i.type->name, i.D.RT, i.D.RA, + (int32_t)(int16_t) XEEXTS16(i.D.DS)); } void Disasm_D_RT_RA0_I(InstrData& i, StringBuffer* str) { if (i.D.RA) { - str->Append("%-8s r%d, r%d, %d", i.type->name, i.D.RT, i.D.RA, - (int32_t)(int16_t) XEEXTS16(i.D.DS)); + str->AppendFormat("%-8s r%d, r%d, %d", i.type->name, i.D.RT, i.D.RA, + (int32_t)(int16_t) XEEXTS16(i.D.DS)); } else { - str->Append("%-8s r%d, 0, %d", i.type->name, i.D.RT, - (int32_t)(int16_t) XEEXTS16(i.D.DS)); + str->AppendFormat("%-8s r%d, 0, %d", i.type->name, i.D.RT, + (int32_t)(int16_t) XEEXTS16(i.D.DS)); } } void Disasm_D_FRT_RA_I(InstrData& i, StringBuffer* str) { - str->Append("%-8s f%d, r%d, %d", i.type->name, i.D.RT, i.D.RA, - (int32_t)(int16_t) XEEXTS16(i.D.DS)); + str->AppendFormat("%-8s f%d, r%d, %d", i.type->name, i.D.RT, i.D.RA, + (int32_t)(int16_t) XEEXTS16(i.D.DS)); } void Disasm_D_FRT_RA0_I(InstrData& i, StringBuffer* str) { if (i.D.RA) { - str->Append("%-8s f%d, r%d, %d", i.type->name, i.D.RT, i.D.RA, - (int32_t)(int16_t) XEEXTS16(i.D.DS)); + str->AppendFormat("%-8s f%d, r%d, %d", i.type->name, i.D.RT, i.D.RA, + (int32_t)(int16_t) XEEXTS16(i.D.DS)); } else { - str->Append("%-8s f%d, 0, %d", i.type->name, i.D.RT, - (int32_t)(int16_t) XEEXTS16(i.D.DS)); + str->AppendFormat("%-8s f%d, 0, %d", i.type->name, i.D.RT, + (int32_t)(int16_t) XEEXTS16(i.D.DS)); } } void Disasm_DS_RT_RA_I(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d, r%d, %d", i.type->name, i.DS.RT, i.DS.RA, - (int32_t)(int16_t) XEEXTS16(i.DS.DS << 2)); + str->AppendFormat("%-8s r%d, r%d, %d", i.type->name, i.DS.RT, i.DS.RA, + (int32_t)(int16_t) XEEXTS16(i.DS.DS << 2)); } void Disasm_DS_RT_RA0_I(InstrData& i, StringBuffer* str) { if (i.DS.RA) { - str->Append("%-8s r%d, r%d, %d", i.type->name, i.DS.RT, i.DS.RA, - (int32_t)(int16_t) XEEXTS16(i.DS.DS << 2)); + str->AppendFormat("%-8s r%d, r%d, %d", i.type->name, i.DS.RT, i.DS.RA, + (int32_t)(int16_t) XEEXTS16(i.DS.DS << 2)); } else { - str->Append("%-8s r%d, 0, %d", i.type->name, i.DS.RT, - (int32_t)(int16_t) XEEXTS16(i.DS.DS << 2)); + str->AppendFormat("%-8s r%d, 0, %d", i.type->name, i.DS.RT, + (int32_t)(int16_t) XEEXTS16(i.DS.DS << 2)); } } void Disasm_D_RA(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d", i.type->name, i.D.RA); + str->AppendFormat("%-8s r%d", i.type->name, i.D.RA); } void Disasm_X_RA_RB(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d, r%d", i.type->name, i.X.RA, i.X.RB); + str->AppendFormat("%-8s r%d, r%d", i.type->name, i.X.RA, i.X.RB); } void Disasm_XO_RT_RA_RB(InstrData& i, StringBuffer* str) { - str->Append("%*s%s%s r%d, r%d, r%d", i.XO.Rc ? -7 : -8, i.type->name, - i.XO.OE ? "o" : "", i.XO.Rc ? "." : "", i.XO.RT, i.XO.RA, - i.XO.RB); + str->AppendFormat("%*s%s%s r%d, r%d, r%d", i.XO.Rc ? -7 : -8, i.type->name, + i.XO.OE ? "o" : "", i.XO.Rc ? "." : "", i.XO.RT, i.XO.RA, + i.XO.RB); } void Disasm_XO_RT_RA(InstrData& i, StringBuffer* str) { - str->Append("%*s%s%s r%d, r%d", i.XO.Rc ? -7 : -8, i.type->name, - i.XO.OE ? "o" : "", i.XO.Rc ? "." : "", i.XO.RT, i.XO.RA); + str->AppendFormat("%*s%s%s r%d, r%d", i.XO.Rc ? -7 : -8, i.type->name, + i.XO.OE ? "o" : "", i.XO.Rc ? "." : "", i.XO.RT, i.XO.RA); } void Disasm_X_RA_RT_RB(InstrData& i, StringBuffer* str) { - str->Append("%*s%s r%d, r%d, r%d", i.X.Rc ? -7 : -8, i.type->name, - i.X.Rc ? "." : "", i.X.RA, i.X.RT, i.X.RB); + str->AppendFormat("%*s%s r%d, r%d, r%d", i.X.Rc ? -7 : -8, i.type->name, + i.X.Rc ? "." : "", i.X.RA, i.X.RT, i.X.RB); } void Disasm_D_RA_RT_I(InstrData& i, StringBuffer* str) { - str->Append("%-7s. r%d, r%d, %.4Xh", i.type->name, i.D.RA, i.D.RT, i.D.DS); + str->AppendFormat("%-7s. r%d, r%d, %.4Xh", i.type->name, i.D.RA, i.D.RT, + i.D.DS); } void Disasm_X_RA_RT(InstrData& i, StringBuffer* str) { - str->Append("%*s%s r%d, r%d", i.X.Rc ? -7 : -8, i.type->name, - i.X.Rc ? "." : "", i.X.RA, i.X.RT); + str->AppendFormat("%*s%s r%d, r%d", i.X.Rc ? -7 : -8, i.type->name, + i.X.Rc ? "." : "", i.X.RA, i.X.RT); } #define OP(x) ((((uint32_t)(x)) & 0x3f) << 26) @@ -163,56 +166,58 @@ void Disasm_X_RA_RT(InstrData& i, StringBuffer* str) { void Disasm_X_VX_RA0_RB(InstrData& i, StringBuffer* str) { if (i.X.RA) { - str->Append("%-8s v%d, r%d, r%d", i.type->name, i.X.RT, i.X.RA, i.X.RB); + str->AppendFormat("%-8s v%d, r%d, r%d", i.type->name, i.X.RT, i.X.RA, + i.X.RB); } else { - str->Append("%-8s v%d, 0, r%d", i.type->name, i.X.RT, i.X.RB); + str->AppendFormat("%-8s v%d, 0, r%d", i.type->name, i.X.RT, i.X.RB); } } void Disasm_VX1281_VD_RA0_RB(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_1_VD128; if (i.VX128_1.RA) { - str->Append("%-8s v%d, r%d, r%d", i.type->name, vd, i.VX128_1.RA, - i.VX128_1.RB); + str->AppendFormat("%-8s v%d, r%d, r%d", i.type->name, vd, i.VX128_1.RA, + i.VX128_1.RB); } else { - str->Append("%-8s v%d, 0, r%d", i.type->name, vd, i.VX128_1.RB); + str->AppendFormat("%-8s v%d, 0, r%d", i.type->name, vd, i.VX128_1.RB); } } void Disasm_VX1283_VD_VB(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_3_VD128; const uint32_t vb = VX128_3_VB128; - str->Append("%-8s v%d, v%d", i.type->name, vd, vb); + str->AppendFormat("%-8s v%d, v%d", i.type->name, vd, vb); } void Disasm_VX1283_VD_VB_I(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_VD128; const uint32_t va = VX128_VA128; const uint32_t uimm = i.VX128_3.IMM; - str->Append("%-8s v%d, v%d, %.2Xh", i.type->name, vd, va, uimm); + str->AppendFormat("%-8s v%d, v%d, %.2Xh", i.type->name, vd, va, uimm); } void Disasm_VX_VD_VA_VB(InstrData& i, StringBuffer* str) { - str->Append("%-8s v%d, v%d, v%d", i.type->name, i.VX.VD, i.VX.VA, i.VX.VB); + str->AppendFormat("%-8s v%d, v%d, v%d", i.type->name, i.VX.VD, i.VX.VA, + i.VX.VB); } void Disasm_VX128_VD_VA_VB(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_VD128; const uint32_t va = VX128_VA128; const uint32_t vb = VX128_VB128; - str->Append("%-8s v%d, v%d, v%d", i.type->name, vd, va, vb); + str->AppendFormat("%-8s v%d, v%d, v%d", i.type->name, vd, va, vb); } void Disasm_VX128_VD_VA_VD_VB(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_VD128; const uint32_t va = VX128_VA128; const uint32_t vb = VX128_VB128; - str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, vd, va, vd, vb); + str->AppendFormat("%-8s v%d, v%d, v%d, v%d", i.type->name, vd, va, vd, vb); } void Disasm_VX1282_VD_VA_VB_VC(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_2_VD128; const uint32_t va = VX128_2_VA128; const uint32_t vb = VX128_2_VB128; const uint32_t vc = i.VX128_2.VC; - str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, vd, va, vb, vc); + str->AppendFormat("%-8s v%d, v%d, v%d, v%d", i.type->name, vd, va, vb, vc); } void Disasm_VXA_VD_VA_VB_VC(InstrData& i, StringBuffer* str) { - str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, i.VXA.VD, i.VXA.VA, - i.VXA.VB, i.VXA.VC); + str->AppendFormat("%-8s v%d, v%d, v%d, v%d", i.type->name, i.VXA.VD, i.VXA.VA, + i.VXA.VB, i.VXA.VC); } void Disasm_sync(InstrData& i, StringBuffer* str) { @@ -231,7 +236,7 @@ void Disasm_sync(InstrData& i, StringBuffer* str) { name = "sync"; break; } - str->Append("%-8s %.2X", name, L); + str->AppendFormat("%-8s %.2X", name, L); } void Disasm_dcbf(InstrData& i, StringBuffer* str) { @@ -253,25 +258,26 @@ void Disasm_dcbf(InstrData& i, StringBuffer* str) { name = "dcbf.??"; break; } - str->Append("%-8s r%d, r%d", name, i.X.RA, i.X.RB); + str->AppendFormat("%-8s r%d, r%d", name, i.X.RA, i.X.RB); } void Disasm_dcbz(InstrData& i, StringBuffer* str) { // or dcbz128 0x7C2007EC if (i.X.RA) { - str->Append("%-8s r%d, r%d", i.type->name, i.X.RA, i.X.RB); + str->AppendFormat("%-8s r%d, r%d", i.type->name, i.X.RA, i.X.RB); } else { - str->Append("%-8s 0, r%d", i.type->name, i.X.RB); + str->AppendFormat("%-8s 0, r%d", i.type->name, i.X.RB); } } void Disasm_fcmp(InstrData& i, StringBuffer* str) { - str->Append("%-8s cr%d, f%d, f%d", i.type->name, i.X.RT >> 2, i.X.RA, i.X.RB); + str->AppendFormat("%-8s cr%d, f%d, f%d", i.type->name, i.X.RT >> 2, i.X.RA, + i.X.RB); } void Disasm_mffsx(InstrData& i, StringBuffer* str) { - str->Append("%*s%s f%d, FPSCR", i.X.Rc ? -7 : -8, i.type->name, - i.X.Rc ? "." : "", i.X.RT); + str->AppendFormat("%*s%s f%d, FPSCR", i.X.Rc ? -7 : -8, i.type->name, + i.X.Rc ? "." : "", i.X.RT); } void Disasm_bx(InstrData& i, StringBuffer* str) { @@ -282,7 +288,7 @@ void Disasm_bx(InstrData& i, StringBuffer* str) { } else { nia = (uint32_t)(i.address + XEEXTS26(i.I.LI << 2)); } - str->Append("%-8s %.8X", name, nia); + str->AppendFormat("%-8s %.8X", name, nia); // TODO(benvanik): resolve target name? } void Disasm_bcx(InstrData& i, StringBuffer* str) { @@ -303,7 +309,7 @@ void Disasm_bcx(InstrData& i, StringBuffer* str) { } else { nia = (uint32_t)(i.address + XEEXTS16(i.B.BD << 2)); } - str->Append("%-8s %s%s%s%.8X", i.type->name, s0, s1, s2, nia); + str->AppendFormat("%-8s %s%s%s%.8X", i.type->name, s0, s1, s2, nia); // TODO(benvanik): resolve target name? } void Disasm_bcctrx(InstrData& i, StringBuffer* str) { @@ -313,7 +319,7 @@ void Disasm_bcctrx(InstrData& i, StringBuffer* str) { if (!select_bits(i.XL.BO, 4, 4)) { snprintf(s2, xe::countof(s2), "cr%d, ", i.XL.BI >> 2); } - str->Append("%-8s %s%sctr", i.type->name, s0, s2); + str->AppendFormat("%-8s %s%sctr", i.type->name, s0, s2); // TODO(benvanik): resolve target name? } void Disasm_bclrx(InstrData& i, StringBuffer* str) { @@ -331,11 +337,11 @@ void Disasm_bclrx(InstrData& i, StringBuffer* str) { if (!select_bits(i.XL.BO, 4, 4)) { snprintf(s2, xe::countof(s2), "cr%d, ", i.XL.BI >> 2); } - str->Append("%-8s %s%s", name, s1, s2); + str->AppendFormat("%-8s %s%s", name, s1, s2); } void Disasm_mfcr(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d, cr", i.type->name, i.X.RT); + str->AppendFormat("%-8s r%d, cr", i.type->name, i.X.RT); } const char* Disasm_spr_name(uint32_t n) { const char* reg = "???"; @@ -355,139 +361,144 @@ const char* Disasm_spr_name(uint32_t n) { void Disasm_mfspr(InstrData& i, StringBuffer* str) { const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F); const char* reg = Disasm_spr_name(n); - str->Append("%-8s r%d, %s", i.type->name, i.XFX.RT, reg); + str->AppendFormat("%-8s r%d, %s", i.type->name, i.XFX.RT, reg); } void Disasm_mtspr(InstrData& i, StringBuffer* str) { const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F); const char* reg = Disasm_spr_name(n); - str->Append("%-8s %s, r%d", i.type->name, reg, i.XFX.RT); + str->AppendFormat("%-8s %s, r%d", i.type->name, reg, i.XFX.RT); } void Disasm_mftb(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d, tb", i.type->name, i.XFX.RT); + str->AppendFormat("%-8s r%d, tb", i.type->name, i.XFX.RT); } void Disasm_mfmsr(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d", i.type->name, i.X.RT); + str->AppendFormat("%-8s r%d", i.type->name, i.X.RT); } void Disasm_mtmsr(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d, %d", i.type->name, i.X.RT, (i.X.RA & 16) ? 1 : 0); + str->AppendFormat("%-8s r%d, %d", i.type->name, i.X.RT, + (i.X.RA & 16) ? 1 : 0); } void Disasm_cmp(InstrData& i, StringBuffer* str) { - str->Append("%-8s cr%d, %.2X, r%d, r%d", i.type->name, i.X.RT >> 2, - i.X.RT & 1, i.X.RA, i.X.RB); + str->AppendFormat("%-8s cr%d, %.2X, r%d, r%d", i.type->name, i.X.RT >> 2, + i.X.RT & 1, i.X.RA, i.X.RB); } void Disasm_cmpi(InstrData& i, StringBuffer* str) { - str->Append("%-8s cr%d, %.2X, r%d, %d", i.type->name, i.D.RT >> 2, i.D.RT & 1, - i.D.RA, XEEXTS16(i.D.DS)); + str->AppendFormat("%-8s cr%d, %.2X, r%d, %d", i.type->name, i.D.RT >> 2, + i.D.RT & 1, i.D.RA, XEEXTS16(i.D.DS)); } void Disasm_cmpli(InstrData& i, StringBuffer* str) { - str->Append("%-8s cr%d, %.2X, r%d, %.2X", i.type->name, i.D.RT >> 2, - i.D.RT & 1, i.D.RA, XEEXTS16(i.D.DS)); + str->AppendFormat("%-8s cr%d, %.2X, r%d, %.2X", i.type->name, i.D.RT >> 2, + i.D.RT & 1, i.D.RA, XEEXTS16(i.D.DS)); } void Disasm_rld(InstrData& i, StringBuffer* str) { if (i.MD.idx == 0) { // XEDISASMR(rldiclx, 0x78000000, MD ) - str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldicl", - i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH, - (i.MD.MB5 << 5) | i.MD.MB); + str->AppendFormat("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldicl", + i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, + (i.MD.SH5 << 5) | i.MD.SH, (i.MD.MB5 << 5) | i.MD.MB); } else if (i.MD.idx == 1) { // XEDISASMR(rldicrx, 0x78000004, MD ) - str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldicr", - i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH, - (i.MD.MB5 << 5) | i.MD.MB); + str->AppendFormat("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldicr", + i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, + (i.MD.SH5 << 5) | i.MD.SH, (i.MD.MB5 << 5) | i.MD.MB); } else if (i.MD.idx == 2) { // XEDISASMR(rldicx, 0x78000008, MD ) uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH; uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB; const char* name = (mb == 0x3E) ? "sldi" : "rldic"; - str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, name, - i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, sh, mb); + str->AppendFormat("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, name, + i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, sh, mb); } else if (i.MDS.idx == 8) { // XEDISASMR(rldclx, 0x78000010, MDS) - str->Append("%*s%s r%d, r%d, %d, %d", i.MDS.Rc ? -7 : -8, "rldcl", - i.MDS.Rc ? "." : "", i.MDS.RA, i.MDS.RT, i.MDS.RB, - (i.MDS.MB5 << 5) | i.MDS.MB); + str->AppendFormat("%*s%s r%d, r%d, %d, %d", i.MDS.Rc ? -7 : -8, "rldcl", + i.MDS.Rc ? "." : "", i.MDS.RA, i.MDS.RT, i.MDS.RB, + (i.MDS.MB5 << 5) | i.MDS.MB); } else if (i.MDS.idx == 9) { // XEDISASMR(rldcrx, 0x78000012, MDS) - str->Append("%*s%s r%d, r%d, %d, %d", i.MDS.Rc ? -7 : -8, "rldcr", - i.MDS.Rc ? "." : "", i.MDS.RA, i.MDS.RT, i.MDS.RB, - (i.MDS.MB5 << 5) | i.MDS.MB); + str->AppendFormat("%*s%s r%d, r%d, %d, %d", i.MDS.Rc ? -7 : -8, "rldcr", + i.MDS.Rc ? "." : "", i.MDS.RA, i.MDS.RT, i.MDS.RB, + (i.MDS.MB5 << 5) | i.MDS.MB); } else if (i.MD.idx == 3) { // XEDISASMR(rldimix, 0x7800000C, MD ) - str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldimi", - i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH, - (i.MD.MB5 << 5) | i.MD.MB); + str->AppendFormat("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldimi", + i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, + (i.MD.SH5 << 5) | i.MD.SH, (i.MD.MB5 << 5) | i.MD.MB); } else { assert_always(); } } void Disasm_rlwim(InstrData& i, StringBuffer* str) { - str->Append("%*s%s r%d, r%d, %d, %d, %d", i.M.Rc ? -7 : -8, i.type->name, - i.M.Rc ? "." : "", i.M.RA, i.M.RT, i.M.SH, i.M.MB, i.M.ME); + str->AppendFormat("%*s%s r%d, r%d, %d, %d, %d", i.M.Rc ? -7 : -8, + i.type->name, i.M.Rc ? "." : "", i.M.RA, i.M.RT, i.M.SH, + i.M.MB, i.M.ME); } void Disasm_rlwnmx(InstrData& i, StringBuffer* str) { - str->Append("%*s%s r%d, r%d, r%d, %d, %d", i.M.Rc ? -7 : -8, i.type->name, - i.M.Rc ? "." : "", i.M.RA, i.M.RT, i.M.SH, i.M.MB, i.M.ME); + str->AppendFormat("%*s%s r%d, r%d, r%d, %d, %d", i.M.Rc ? -7 : -8, + i.type->name, i.M.Rc ? "." : "", i.M.RA, i.M.RT, i.M.SH, + i.M.MB, i.M.ME); } void Disasm_srawix(InstrData& i, StringBuffer* str) { - str->Append("%*s%s r%d, r%d, %d", i.X.Rc ? -7 : -8, i.type->name, - i.X.Rc ? "." : "", i.X.RA, i.X.RT, i.X.RB); + str->AppendFormat("%*s%s r%d, r%d, %d", i.X.Rc ? -7 : -8, i.type->name, + i.X.Rc ? "." : "", i.X.RA, i.X.RT, i.X.RB); } void Disasm_sradix(InstrData& i, StringBuffer* str) { - str->Append("%*s%s r%d, r%d, %d", i.XS.Rc ? -7 : -8, i.type->name, - i.XS.Rc ? "." : "", i.XS.RA, i.XS.RT, (i.XS.SH5 << 5) | i.XS.SH); + str->AppendFormat("%*s%s r%d, r%d, %d", i.XS.Rc ? -7 : -8, i.type->name, + i.XS.Rc ? "." : "", i.XS.RA, i.XS.RT, + (i.XS.SH5 << 5) | i.XS.SH); } void Disasm_vpermwi128(InstrData& i, StringBuffer* str) { const uint32_t vd = i.VX128_P.VD128l | (i.VX128_P.VD128h << 5); const uint32_t vb = i.VX128_P.VB128l | (i.VX128_P.VB128h << 5); - str->Append("%-8s v%d, v%d, %.2X", i.type->name, vd, vb, - i.VX128_P.PERMl | (i.VX128_P.PERMh << 5)); + str->AppendFormat("%-8s v%d, v%d, %.2X", i.type->name, vd, vb, + i.VX128_P.PERMl | (i.VX128_P.PERMh << 5)); } void Disasm_vrfin128(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_3_VD128; const uint32_t vb = VX128_3_VB128; - str->Append("%-8s v%d, v%d", i.type->name, vd, vb); + str->AppendFormat("%-8s v%d, v%d", i.type->name, vd, vb); } void Disasm_vrlimi128(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_4_VD128; const uint32_t vb = VX128_4_VB128; - str->Append("%-8s v%d, v%d, %.2X, %.2X", i.type->name, vd, vb, i.VX128_4.IMM, - i.VX128_4.z); + str->AppendFormat("%-8s v%d, v%d, %.2X, %.2X", i.type->name, vd, vb, + i.VX128_4.IMM, i.VX128_4.z); } void Disasm_vsldoi128(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_5_VD128; const uint32_t va = VX128_5_VA128; const uint32_t vb = VX128_5_VB128; const uint32_t sh = i.VX128_5.SH; - str->Append("%-8s v%d, v%d, v%d, %.2X", i.type->name, vd, va, vb, sh); + str->AppendFormat("%-8s v%d, v%d, v%d, %.2X", i.type->name, vd, va, vb, sh); } void Disasm_vspltb(InstrData& i, StringBuffer* str) { - str->Append("%-8s v%d, v%d, %.2X", i.type->name, i.VX.VD, i.VX.VB, - i.VX.VA & 0xF); + str->AppendFormat("%-8s v%d, v%d, %.2X", i.type->name, i.VX.VD, i.VX.VB, + i.VX.VA & 0xF); } void Disasm_vsplth(InstrData& i, StringBuffer* str) { - str->Append("%-8s v%d, v%d, %.2X", i.type->name, i.VX.VD, i.VX.VB, - i.VX.VA & 0x7); + str->AppendFormat("%-8s v%d, v%d, %.2X", i.type->name, i.VX.VD, i.VX.VB, + i.VX.VA & 0x7); } void Disasm_vspltw(InstrData& i, StringBuffer* str) { - str->Append("%-8s v%d, v%d, %.2X", i.type->name, i.VX.VD, i.VX.VB, i.VX.VA); + str->AppendFormat("%-8s v%d, v%d, %.2X", i.type->name, i.VX.VD, i.VX.VB, + i.VX.VA); } void Disasm_vspltisb(InstrData& i, StringBuffer* str) { // 5bit -> 8bit sign extend int8_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xF0) : i.VX.VA; - str->Append("%-8s v%d, %.2X", i.type->name, i.VX.VD, simm); + str->AppendFormat("%-8s v%d, %.2X", i.type->name, i.VX.VD, simm); } void Disasm_vspltish(InstrData& i, StringBuffer* str) { // 5bit -> 16bit sign extend int16_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFF0) : i.VX.VA; - str->Append("%-8s v%d, %.4X", i.type->name, i.VX.VD, simm); + str->AppendFormat("%-8s v%d, %.4X", i.type->name, i.VX.VD, simm); } void Disasm_vspltisw(InstrData& i, StringBuffer* str) { // 5bit -> 32bit sign extend int32_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFFFFFF0) : i.VX.VA; - str->Append("%-8s v%d, %.8X", i.type->name, i.VX.VD, simm); + str->AppendFormat("%-8s v%d, %.8X", i.type->name, i.VX.VD, simm); } int DisasmPPC(InstrData& i, StringBuffer* str) { diff --git a/src/xenia/cpu/frontend/ppc_instr.cc b/src/xenia/cpu/frontend/ppc_instr.cc index 4216784b8..eed9aae55 100644 --- a/src/xenia/cpu/frontend/ppc_instr.cc +++ b/src/xenia/cpu/frontend/ppc_instr.cc @@ -28,7 +28,8 @@ void DumpAllInstrCounts() { sb.Append("Instruction translation counts:\n"); for (auto instr_type : all_instrs_) { if (instr_type->translation_count) { - sb.Append("%8d : %s\n", instr_type->translation_count, instr_type->name); + sb.AppendFormat("%8d : %s\n", instr_type->translation_count, + instr_type->name); } } fprintf(stdout, sb.GetString()); diff --git a/src/xenia/cpu/frontend/ppc_translator.cc b/src/xenia/cpu/frontend/ppc_translator.cc index dde980294..bd3f37fa2 100644 --- a/src/xenia/cpu/frontend/ppc_translator.cc +++ b/src/xenia/cpu/frontend/ppc_translator.cc @@ -195,10 +195,10 @@ void PPCTranslator::DumpSource(FunctionInfo* symbol_info, StringBuffer* string_buffer) { Memory* memory = frontend_->memory(); - string_buffer->Append("%s fn %.8X-%.8X %s\n", - symbol_info->module()->name().c_str(), - symbol_info->address(), symbol_info->end_address(), - symbol_info->name().c_str()); + 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()); auto blocks = scanner_->FindBlocks(symbol_info); @@ -215,13 +215,14 @@ void PPCTranslator::DumpSource(FunctionInfo* symbol_info, // Check labels. if (block_it != blocks.end() && block_it->start_address == address) { - string_buffer->Append("%.8X loc_%.8X:\n", address, address); + string_buffer->AppendFormat("%.8X loc_%.8X:\n", address, + address); ++block_it; } - string_buffer->Append("%.8X %.8X ", address, i.code); + string_buffer->AppendFormat("%.8X %.8X ", address, i.code); DisasmPPC(i, string_buffer); - string_buffer->Append("\n"); + string_buffer->Append('\n'); } } diff --git a/src/xenia/cpu/hir/hir_builder.cc b/src/xenia/cpu/hir/hir_builder.cc index e0aed4879..828accca0 100644 --- a/src/xenia/cpu/hir/hir_builder.cc +++ b/src/xenia/cpu/hir/hir_builder.cc @@ -40,7 +40,7 @@ assert_true((value->type) != FLOAT32_TYPE && (value->type) != FLOAT64_TYPE) #define ASSERT_TYPES_EQUAL(value1, value2) \ assert_true((value1->type) == (value2->type)) - HIRBuilder::HIRBuilder() { +HIRBuilder::HIRBuilder() { arena_ = new Arena(); Reset(); } @@ -103,27 +103,27 @@ void HIRBuilder::DumpValue(StringBuffer* str, Value* value) { if (value->IsConstant()) { switch (value->type) { case INT8_TYPE: - str->Append("%X", value->constant.i8); + str->AppendFormat("%X", value->constant.i8); break; case INT16_TYPE: - str->Append("%X", value->constant.i16); + str->AppendFormat("%X", value->constant.i16); break; case INT32_TYPE: - str->Append("%X", value->constant.i32); + str->AppendFormat("%X", value->constant.i32); break; case INT64_TYPE: - str->Append("%llX", value->constant.i64); + str->AppendFormat("%llX", value->constant.i64); break; case FLOAT32_TYPE: - str->Append("%F", value->constant.f32); + str->AppendFormat("%F", value->constant.f32); break; case FLOAT64_TYPE: - str->Append("%F", value->constant.f64); + str->AppendFormat("%F", value->constant.f64); break; case VEC128_TYPE: - str->Append("(%F,%F,%F,%F)", value->constant.v128.x, - value->constant.v128.y, value->constant.v128.z, - value->constant.v128.w); + str->AppendFormat("(%F,%F,%F,%F)", value->constant.v128.x, + value->constant.v128.y, value->constant.v128.z, + value->constant.v128.w); break; default: assert_always(); @@ -133,10 +133,10 @@ void HIRBuilder::DumpValue(StringBuffer* str, Value* value) { static const char* type_names[] = { "i8", "i16", "i32", "i64", "f32", "f64", "v128", }; - str->Append("v%d.%s", value->ordinal, type_names[value->type]); + str->AppendFormat("v%d.%s", value->ordinal, type_names[value->type]); } if (value->reg.index != -1) { - str->Append("<%s%d>", value->reg.set->name, value->reg.index); + str->AppendFormat("<%s%d>", value->reg.set->name, value->reg.index); } } @@ -149,11 +149,11 @@ void HIRBuilder::DumpOp(StringBuffer* str, OpcodeSignatureType sig_type, if (op->label->name) { str->Append(op->label->name); } else { - str->Append("label%d", op->label->id); + str->AppendFormat("label%d", op->label->id); } break; case OPCODE_SIG_TYPE_O: - str->Append("+%lld", op->offset); + str->AppendFormat("+%lld", op->offset); break; case OPCODE_SIG_TYPE_S: if (true) { @@ -169,14 +169,14 @@ void HIRBuilder::DumpOp(StringBuffer* str, OpcodeSignatureType sig_type, void HIRBuilder::Dump(StringBuffer* str) { if (attributes_) { - str->Append("; attributes = %.8X\n", attributes_); + str->AppendFormat("; attributes = %.8X\n", attributes_); } for (auto it = locals_.begin(); it != locals_.end(); ++it) { auto local = *it; str->Append(" ; local "); DumpValue(str, local); - str->Append("\n"); + str->Append('\n'); } uint32_t block_ordinal = 0; @@ -185,16 +185,16 @@ void HIRBuilder::Dump(StringBuffer* str) { if (block == block_head_) { str->Append(":\n"); } else if (!block->label_head) { - str->Append(":\n", block_ordinal); + str->AppendFormat(":\n", block_ordinal); } block_ordinal++; Label* label = block->label_head; while (label) { if (label->name) { - str->Append("%s:\n", label->name); + str->AppendFormat("%s:\n", label->name); } else { - str->Append("label%d:\n", label->id); + str->AppendFormat("label%d:\n", label->id); } label = label->next; } @@ -203,30 +203,30 @@ void HIRBuilder::Dump(StringBuffer* str) { while (incoming_edge) { auto src_label = incoming_edge->src->label_head; if (src_label && src_label->name) { - str->Append(" ; in: %s", src_label->name); + str->AppendFormat(" ; in: %s", src_label->name); } else if (src_label) { - str->Append(" ; in: label%d", src_label->id); + str->AppendFormat(" ; in: label%d", src_label->id); } else { - str->Append(" ; in: ", incoming_edge->src->ordinal); + str->AppendFormat(" ; in: ", incoming_edge->src->ordinal); } - str->Append(", dom:%d, uncond:%d\n", - (incoming_edge->flags & Edge::DOMINATES) ? 1 : 0, - (incoming_edge->flags & Edge::UNCONDITIONAL) ? 1 : 0); + str->AppendFormat(", dom:%d, uncond:%d\n", + (incoming_edge->flags & Edge::DOMINATES) ? 1 : 0, + (incoming_edge->flags & Edge::UNCONDITIONAL) ? 1 : 0); incoming_edge = incoming_edge->incoming_next; } Edge* outgoing_edge = block->outgoing_edge_head; while (outgoing_edge) { auto dest_label = outgoing_edge->dest->label_head; if (dest_label && dest_label->name) { - str->Append(" ; out: %s", dest_label->name); + str->AppendFormat(" ; out: %s", dest_label->name); } else if (dest_label) { - str->Append(" ; out: label%d", dest_label->id); + str->AppendFormat(" ; out: label%d", dest_label->id); } else { - str->Append(" ; out: ", outgoing_edge->dest->ordinal); + str->AppendFormat(" ; out: ", outgoing_edge->dest->ordinal); } - str->Append(", dom:%d, uncond:%d\n", - (outgoing_edge->flags & Edge::DOMINATES) ? 1 : 0, - (outgoing_edge->flags & Edge::UNCONDITIONAL) ? 1 : 0); + str->AppendFormat(", dom:%d, uncond:%d\n", + (outgoing_edge->flags & Edge::DOMINATES) ? 1 : 0, + (outgoing_edge->flags & Edge::UNCONDITIONAL) ? 1 : 0); outgoing_edge = outgoing_edge->outgoing_next; } @@ -237,7 +237,7 @@ void HIRBuilder::Dump(StringBuffer* str) { continue; } if (i->opcode == &OPCODE_COMMENT_info) { - str->Append(" ; %s\n", (char*)i->src1.offset); + str->AppendFormat(" ; %s\n", (char*)i->src1.offset); i = i->next; continue; } @@ -253,12 +253,12 @@ void HIRBuilder::Dump(StringBuffer* str) { str->Append(" = "); } if (i->flags) { - str->Append("%s.%d", info->name, i->flags); + str->AppendFormat("%s.%d", info->name, i->flags); } else { - str->Append("%s", info->name); + str->Append(info->name); } if (src1_type) { - str->Append(" "); + str->Append(' '); DumpOp(str, src1_type, &i->src1); } if (src2_type) { @@ -269,7 +269,7 @@ void HIRBuilder::Dump(StringBuffer* str) { str->Append(", "); DumpOp(str, src3_type, &i->src3); } - str->Append("\n"); + str->Append('\n'); i = i->next; } diff --git a/src/xenia/gpu/ucode_disassembler.cc b/src/xenia/gpu/ucode_disassembler.cc index d66524e2b..24bd83d0f 100644 --- a/src/xenia/gpu/ucode_disassembler.cc +++ b/src/xenia/gpu/ucode_disassembler.cc @@ -38,6 +38,7 @@ #include #include "xenia/base/assert.h" +#include "xenia/base/string_buffer.h" namespace xe { namespace gpu { @@ -45,28 +46,10 @@ namespace gpu { using namespace xe::gpu::ucode; using namespace xe::gpu::xenos; -const int OUTPUT_CAPACITY = 256 * 1024; -struct Output { - char buffer[OUTPUT_CAPACITY]; - size_t capacity; - size_t offset; - Output() : capacity(OUTPUT_CAPACITY), offset(0) { buffer[0] = 0; } - void append(const char* format, ...) { - va_list args; - va_start(args, format); - int len = vsnprintf(buffer + offset, capacity - offset, format, args); - va_end(args); - assert_true(offset + len < capacity); - offset += len; - buffer[offset] = 0; - } -}; - static const char* levels[] = { - "", "\t", "\t\t", "\t\t\t", - "\t\t\t\t", "\t\t\t\t\t", "\t\t\t\t\t\t", "\t\t\t\t\t\t\t", - "\t\t\t\t\t\t\t\t", "\t\t\t\t\t\t\t\t\t", "x", "x", - "x", "x", "x", "x", + "", "\t", "\t\t", "\t\t\t", "\t\t\t\t", "\t\t\t\t\t", "\t\t\t\t\t\t", + "\t\t\t\t\t\t\t", "\t\t\t\t\t\t\t\t", "\t\t\t\t\t\t\t\t\t", "x", "x", "x", + "x", "x", "x", }; /* @@ -79,52 +62,52 @@ static const char chan_names[] = { '0', '1', '?', '_', }; -void print_srcreg(Output* output, uint32_t num, uint32_t type, uint32_t swiz, - uint32_t negate, uint32_t abs_constants, +void print_srcreg(StringBuffer* output, uint32_t num, uint32_t type, + uint32_t swiz, uint32_t negate, uint32_t abs_constants, ShaderType shader_type) { if (negate) { - output->append("-"); + output->Append('-'); } if (type) { if (num & 0x80) { - output->append("abs("); + output->Append("abs("); } - output->append("R%u", num & 0x7F); + output->AppendFormat("R%u", num & 0x7F); if (num & 0x80) { - output->append(")"); + output->Append(')'); } } else { if (abs_constants) { - output->append("|"); + output->Append('|'); } num += shader_type == ShaderType::kPixel ? 256 : 0; - output->append("C%u", num); + output->AppendFormat("C%u", num); if (abs_constants) { - output->append("|"); + output->Append('|'); } } if (swiz) { - output->append("."); + output->Append('.'); for (int i = 0; i < 4; i++) { - output->append("%c", chan_names[(swiz + i) & 0x3]); + output->Append(chan_names[(swiz + i) & 0x3]); swiz >>= 2; } } } -void print_dstreg(Output* output, uint32_t num, uint32_t mask, +void print_dstreg(StringBuffer* output, uint32_t num, uint32_t mask, uint32_t dst_exp) { - output->append("%s%u", dst_exp ? "export" : "R", num); + output->AppendFormat("%s%u", dst_exp ? "export" : "R", num); if (mask != 0xf) { - output->append("."); + output->Append('.'); for (int i = 0; i < 4; i++) { - output->append("%c", (mask & 0x1) ? chan_names[i] : '_'); + output->Append((mask & 0x1) ? chan_names[i] : '_'); mask >>= 1; } } } -void print_export_comment(Output* output, uint32_t num, ShaderType type) { +void print_export_comment(StringBuffer* output, uint32_t num, ShaderType type) { const char* name = NULL; switch (type) { case ShaderType::kVertex: @@ -149,46 +132,47 @@ void print_export_comment(Output* output, uint32_t num, ShaderType type) { * up the name of the varying.. */ if (name) { - output->append("\t; %s", name); + output->AppendFormat("\t; %s", name); } } struct { uint32_t num_srcs; const char* name; -} vector_instructions[0x20] = { +} vector_instructions[0x20] = + { #define INSTR(opc, num_srcs) \ { num_srcs, #opc } - INSTR(ADDv, 2), // 0 - INSTR(MULv, 2), // 1 - INSTR(MAXv, 2), // 2 - INSTR(MINv, 2), // 3 - INSTR(SETEv, 2), // 4 - INSTR(SETGTv, 2), // 5 - INSTR(SETGTEv, 2), // 6 - INSTR(SETNEv, 2), // 7 - INSTR(FRACv, 1), // 8 - INSTR(TRUNCv, 1), // 9 - INSTR(FLOORv, 1), // 10 - INSTR(MULADDv, 3), // 111 - INSTR(CNDEv, 3), // 12 - INSTR(CNDGTEv, 3), // 13 - INSTR(CNDGTv, 3), // 14 - INSTR(DOT4v, 2), // 15 - INSTR(DOT3v, 2), // 16 - INSTR(DOT2ADDv, 3), // 17 -- ??? - INSTR(CUBEv, 2), // 18 - INSTR(MAX4v, 1), // 19 - INSTR(PRED_SETE_PUSHv, 2), // 20 - INSTR(PRED_SETNE_PUSHv, 2), // 21 - INSTR(PRED_SETGT_PUSHv, 2), // 22 - INSTR(PRED_SETGTE_PUSHv, 2), // 23 - INSTR(KILLEv, 2), // 24 - INSTR(KILLGTv, 2), // 25 - INSTR(KILLGTEv, 2), // 26 - INSTR(KILLNEv, 2), // 27 - INSTR(DSTv, 2), // 28 - INSTR(MOVAv, 1), // 29 + INSTR(ADDv, 2), // 0 + INSTR(MULv, 2), // 1 + INSTR(MAXv, 2), // 2 + INSTR(MINv, 2), // 3 + INSTR(SETEv, 2), // 4 + INSTR(SETGTv, 2), // 5 + INSTR(SETGTEv, 2), // 6 + INSTR(SETNEv, 2), // 7 + INSTR(FRACv, 1), // 8 + INSTR(TRUNCv, 1), // 9 + INSTR(FLOORv, 1), // 10 + INSTR(MULADDv, 3), // 111 + INSTR(CNDEv, 3), // 12 + INSTR(CNDGTEv, 3), // 13 + INSTR(CNDGTv, 3), // 14 + INSTR(DOT4v, 2), // 15 + INSTR(DOT3v, 2), // 16 + INSTR(DOT2ADDv, 3), // 17 -- ??? + INSTR(CUBEv, 2), // 18 + INSTR(MAX4v, 1), // 19 + INSTR(PRED_SETE_PUSHv, 2), // 20 + INSTR(PRED_SETNE_PUSHv, 2), // 21 + INSTR(PRED_SETGT_PUSHv, 2), // 22 + INSTR(PRED_SETGTE_PUSHv, 2), // 23 + INSTR(KILLEv, 2), // 24 + INSTR(KILLGTv, 2), // 25 + INSTR(KILLGTEv, 2), // 26 + INSTR(KILLNEv, 2), // 27 + INSTR(DSTv, 2), // 28 + INSTR(MOVAv, 1), // 29 }, scalar_instructions[0x40] = { INSTR(ADDs, 1), // 0 @@ -245,77 +229,77 @@ struct { #undef INSTR }; -int disasm_alu(Output* output, const uint32_t* dwords, uint32_t alu_off, +int disasm_alu(StringBuffer* output, const uint32_t* dwords, uint32_t alu_off, int level, int sync, ShaderType type) { const instr_alu_t* alu = (const instr_alu_t*)dwords; - output->append("%s", levels[level]); - output->append("%02x: %08x %08x %08x\t", alu_off, dwords[0], dwords[1], - dwords[2]); + output->Append(levels[level]); + output->AppendFormat("%02x: %08x %08x %08x\t", alu_off, dwords[0], dwords[1], + dwords[2]); - output->append(" %sALU:\t", sync ? "(S)" : " "); + output->AppendFormat(" %sALU:\t", sync ? "(S)" : " "); if (!alu->scalar_write_mask && !alu->vector_write_mask) { - output->append(" \n"); + output->Append(" \n"); } if (alu->vector_write_mask) { - output->append("%s", vector_instructions[alu->vector_opc].name); + output->Append(vector_instructions[alu->vector_opc].name); if (alu->pred_select & 0x2) { // seems to work similar to conditional execution in ARM instruction // set, so let's use a similar syntax for now: - output->append((alu->pred_select & 0x1) ? "EQ" : "NE"); + output->Append((alu->pred_select & 0x1) ? "EQ" : "NE"); } - output->append("\t"); + output->Append("\t"); print_dstreg(output, alu->vector_dest, alu->vector_write_mask, alu->export_data); - output->append(" = "); + output->Append(" = "); if (vector_instructions[alu->vector_opc].num_srcs == 3) { print_srcreg(output, alu->src3_reg, alu->src3_sel, alu->src3_swiz, alu->src3_reg_negate, alu->abs_constants, type); - output->append(", "); + output->Append(", "); } print_srcreg(output, alu->src1_reg, alu->src1_sel, alu->src1_swiz, alu->src1_reg_negate, alu->abs_constants, type); if (vector_instructions[alu->vector_opc].num_srcs > 1) { - output->append(", "); + output->Append(", "); print_srcreg(output, alu->src2_reg, alu->src2_sel, alu->src2_swiz, alu->src2_reg_negate, alu->abs_constants, type); } if (alu->vector_clamp) { - output->append(" CLAMP"); + output->Append(" CLAMP"); } if (alu->pred_select) { - output->append(" COND(%d)", alu->pred_condition); + output->AppendFormat(" COND(%d)", alu->pred_condition); } if (alu->export_data) { print_export_comment(output, alu->vector_dest, type); } - output->append("\n"); + output->Append('\n'); } if (alu->scalar_write_mask || !alu->vector_write_mask) { // 2nd optional scalar op: if (alu->vector_write_mask) { - output->append("%s", levels[level]); - output->append(" \t\t\t\t\t\t \t"); + output->Append(levels[level]); + output->AppendFormat(" \t\t\t\t\t\t \t"); } if (scalar_instructions[alu->scalar_opc].name) { - output->append("%s\t", scalar_instructions[alu->scalar_opc].name); + output->AppendFormat("%s\t", scalar_instructions[alu->scalar_opc].name); } else { - output->append("OP(%u)\t", alu->scalar_opc); + output->AppendFormat("OP(%u)\t", alu->scalar_opc); } print_dstreg(output, alu->scalar_dest, alu->scalar_write_mask, alu->export_data); - output->append(" = "); + output->Append(" = "); if (scalar_instructions[alu->scalar_opc].num_srcs == 2) { // MUL/ADD/etc // Clever, CONST_0 and CONST_1 are just an extra storage bit. @@ -325,24 +309,24 @@ int disasm_alu(Output* output, const uint32_t* dwords, uint32_t alu_off, uint32_t swiz_b = (src3_swiz & 0x3); print_srcreg(output, alu->src3_reg, 0, 0, alu->src3_reg_negate, alu->abs_constants, type); - output->append(".%c", chan_names[swiz_a]); - output->append(", "); + output->AppendFormat(".%c", chan_names[swiz_a]); + output->Append(", "); uint32_t reg2 = (alu->scalar_opc & 1) | (alu->src3_swiz & 0x3C) | (alu->src3_sel << 1); print_srcreg(output, reg2, 1, 0, alu->src3_reg_negate, alu->abs_constants, type); - output->append(".%c", chan_names[swiz_b]); + output->AppendFormat(".%c", chan_names[swiz_b]); } else { print_srcreg(output, alu->src3_reg, alu->src3_sel, alu->src3_swiz, alu->src3_reg_negate, alu->abs_constants, type); } if (alu->scalar_clamp) { - output->append(" CLAMP"); + output->Append(" CLAMP"); } if (alu->export_data) { print_export_comment(output, alu->scalar_dest, type); } - output->append("\n"); + output->Append('\n'); } return 0; @@ -353,115 +337,117 @@ struct { } fetch_types[0xff] = { #define TYPE(id) \ { #id } - TYPE(FMT_1_REVERSE), // 0 - {0}, - TYPE(FMT_8), // 2 - {0}, - {0}, - {0}, - TYPE(FMT_8_8_8_8), // 6 - TYPE(FMT_2_10_10_10), // 7 - {0}, - {0}, - TYPE(FMT_8_8), // 10 - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - TYPE(FMT_16), // 24 - TYPE(FMT_16_16), // 25 - TYPE(FMT_16_16_16_16), // 26 - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - TYPE(FMT_32), // 33 - TYPE(FMT_32_32), // 34 - TYPE(FMT_32_32_32_32), // 35 - TYPE(FMT_32_FLOAT), // 36 - TYPE(FMT_32_32_FLOAT), // 37 - TYPE(FMT_32_32_32_32_FLOAT), // 38 - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - TYPE(FMT_32_32_32_FLOAT), // 57 + TYPE(FMT_1_REVERSE), // 0 + {0}, + TYPE(FMT_8), // 2 + {0}, + {0}, + {0}, + TYPE(FMT_8_8_8_8), // 6 + TYPE(FMT_2_10_10_10), // 7 + {0}, + {0}, + TYPE(FMT_8_8), // 10 + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + TYPE(FMT_16), // 24 + TYPE(FMT_16_16), // 25 + TYPE(FMT_16_16_16_16), // 26 + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + TYPE(FMT_32), // 33 + TYPE(FMT_32_32), // 34 + TYPE(FMT_32_32_32_32), // 35 + TYPE(FMT_32_FLOAT), // 36 + TYPE(FMT_32_32_FLOAT), // 37 + TYPE(FMT_32_32_32_32_FLOAT), // 38 + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + TYPE(FMT_32_32_32_FLOAT), // 57 #undef TYPE }; -void print_fetch_dst(Output* output, uint32_t dst_reg, uint32_t dst_swiz) { - output->append("\tR%u.", dst_reg); +void print_fetch_dst(StringBuffer* output, uint32_t dst_reg, + uint32_t dst_swiz) { + output->AppendFormat("\tR%u.", dst_reg); for (int i = 0; i < 4; i++) { - output->append("%c", chan_names[dst_swiz & 0x7]); + output->Append(chan_names[dst_swiz & 0x7]); dst_swiz >>= 3; } } -void print_fetch_vtx(Output* output, const instr_fetch_t* fetch) { +void print_fetch_vtx(StringBuffer* output, const instr_fetch_t* fetch) { const instr_fetch_vtx_t* vtx = &fetch->vtx; if (vtx->pred_select) { // seems to work similar to conditional execution in ARM instruction // set, so let's use a similar syntax for now: - output->append(vtx->pred_condition ? "EQ" : "NE"); + output->Append(vtx->pred_condition ? "EQ" : "NE"); } print_fetch_dst(output, vtx->dst_reg, vtx->dst_swiz); - output->append(" = R%u.", vtx->src_reg); - output->append("%c", chan_names[vtx->src_swiz & 0x3]); + output->AppendFormat(" = R%u.", vtx->src_reg); + output->Append(chan_names[vtx->src_swiz & 0x3]); if (fetch_types[vtx->format].name) { - output->append(" %s", fetch_types[vtx->format].name); + output->AppendFormat(" %s", fetch_types[vtx->format].name); } else { - output->append(" TYPE(0x%x)", vtx->format); + output->AppendFormat(" TYPE(0x%x)", vtx->format); } - output->append(" %s", vtx->format_comp_all ? "SIGNED" : "UNSIGNED"); + output->AppendFormat(" %s", vtx->format_comp_all ? "SIGNED" : "UNSIGNED"); if (!vtx->num_format_all) { - output->append(" NORMALIZED"); + output->Append(" NORMALIZED"); } - output->append(" STRIDE(%u)", vtx->stride); + output->AppendFormat(" STRIDE(%u)", vtx->stride); if (vtx->offset) { - output->append(" OFFSET(%u)", vtx->offset); + output->AppendFormat(" OFFSET(%u)", vtx->offset); } - output->append(" CONST(%u, %u)", vtx->const_index, vtx->const_index_sel); + output->AppendFormat(" CONST(%u, %u)", vtx->const_index, + vtx->const_index_sel); if (vtx->pred_select) { - output->append(" COND(%d)", vtx->pred_condition); + output->AppendFormat(" COND(%d)", vtx->pred_condition); } if (1) { // XXX - output->append(" src_reg_am=%u", vtx->src_reg_am); - output->append(" dst_reg_am=%u", vtx->dst_reg_am); - output->append(" num_format_all=%u", vtx->num_format_all); - output->append(" signed_rf_mode_all=%u", vtx->signed_rf_mode_all); - output->append(" exp_adjust_all=%u", vtx->exp_adjust_all); + output->AppendFormat(" src_reg_am=%u", vtx->src_reg_am); + output->AppendFormat(" dst_reg_am=%u", vtx->dst_reg_am); + output->AppendFormat(" num_format_all=%u", vtx->num_format_all); + output->AppendFormat(" signed_rf_mode_all=%u", vtx->signed_rf_mode_all); + output->AppendFormat(" exp_adjust_all=%u", vtx->exp_adjust_all); } } -void print_fetch_tex(Output* output, const instr_fetch_t* fetch) { +void print_fetch_tex(StringBuffer* output, const instr_fetch_t* fetch) { static const char* filter[] = { "POINT", // TEX_FILTER_POINT "LINEAR", // TEX_FILTER_LINEAR @@ -493,219 +479,215 @@ void print_fetch_tex(Output* output, const instr_fetch_t* fetch) { if (tex->pred_select) { // seems to work similar to conditional execution in ARM instruction // set, so let's use a similar syntax for now: - output->append(tex->pred_condition ? "EQ" : "NE"); + output->Append(tex->pred_condition ? "EQ" : "NE"); } print_fetch_dst(output, tex->dst_reg, tex->dst_swiz); - output->append(" = R%u.", tex->src_reg); + output->AppendFormat(" = R%u.", tex->src_reg); for (int i = 0; i < 3; i++) { - output->append("%c", chan_names[src_swiz & 0x3]); + output->Append(chan_names[src_swiz & 0x3]); src_swiz >>= 2; } - output->append(" CONST(%u)", tex->const_idx); + output->AppendFormat(" CONST(%u)", tex->const_idx); if (tex->fetch_valid_only) { - output->append(" VALID_ONLY"); + output->Append(" VALID_ONLY"); } if (tex->tx_coord_denorm) { - output->append(" DENORM"); + output->Append(" DENORM"); } if (tex->mag_filter != TEX_FILTER_USE_FETCH_CONST) { - output->append(" MAG(%s)", filter[tex->mag_filter]); + output->AppendFormat(" MAG(%s)", filter[tex->mag_filter]); } if (tex->min_filter != TEX_FILTER_USE_FETCH_CONST) { - output->append(" MIN(%s)", filter[tex->min_filter]); + output->AppendFormat(" MIN(%s)", filter[tex->min_filter]); } if (tex->mip_filter != TEX_FILTER_USE_FETCH_CONST) { - output->append(" MIP(%s)", filter[tex->mip_filter]); + output->AppendFormat(" MIP(%s)", filter[tex->mip_filter]); } if (tex->aniso_filter != ANISO_FILTER_USE_FETCH_CONST) { - output->append(" ANISO(%s)", aniso_filter[tex->aniso_filter]); + output->AppendFormat(" ANISO(%s)", aniso_filter[tex->aniso_filter]); } if (tex->arbitrary_filter != ARBITRARY_FILTER_USE_FETCH_CONST) { - output->append(" ARBITRARY(%s)", arbitrary_filter[tex->arbitrary_filter]); + output->AppendFormat(" ARBITRARY(%s)", + arbitrary_filter[tex->arbitrary_filter]); } if (tex->vol_mag_filter != TEX_FILTER_USE_FETCH_CONST) { - output->append(" VOL_MAG(%s)", filter[tex->vol_mag_filter]); + output->AppendFormat(" VOL_MAG(%s)", filter[tex->vol_mag_filter]); } if (tex->vol_min_filter != TEX_FILTER_USE_FETCH_CONST) { - output->append(" VOL_MIN(%s)", filter[tex->vol_min_filter]); + output->AppendFormat(" VOL_MIN(%s)", filter[tex->vol_min_filter]); } if (!tex->use_comp_lod) { - output->append(" LOD(%u)", tex->use_comp_lod); - output->append(" LOD_BIAS(%u)", tex->lod_bias); + output->AppendFormat(" LOD(%u)", tex->use_comp_lod); + output->AppendFormat(" LOD_BIAS(%u)", tex->lod_bias); } if (tex->use_reg_lod) { - output->append(" REG_LOD(%u)", tex->use_reg_lod); + output->AppendFormat(" REG_LOD(%u)", tex->use_reg_lod); } if (tex->use_reg_gradients) { - output->append(" USE_REG_GRADIENTS"); + output->Append(" USE_REG_GRADIENTS"); } - output->append(" LOCATION(%s)", sample_loc[tex->sample_location]); + output->AppendFormat(" LOCATION(%s)", sample_loc[tex->sample_location]); if (tex->offset_x || tex->offset_y || tex->offset_z) { - output->append(" OFFSET(%u,%u,%u)", tex->offset_x, tex->offset_y, - tex->offset_z); + output->AppendFormat(" OFFSET(%u,%u,%u)", tex->offset_x, tex->offset_y, + tex->offset_z); } if (tex->pred_select) { - output->append(" COND(%d)", tex->pred_condition); + output->AppendFormat(" COND(%d)", tex->pred_condition); } } struct { const char* name; - void (*fxn)(Output* output, const instr_fetch_t* cf); + void (*fxn)(StringBuffer* output, const instr_fetch_t* cf); } fetch_instructions[] = { #define INSTR(opc, name, fxn) \ { name, fxn } - INSTR(VTX_FETCH, "VERTEX", print_fetch_vtx), // 0 - INSTR(TEX_FETCH, "SAMPLE", print_fetch_tex), // 1 - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - INSTR(TEX_GET_BORDER_COLOR_FRAC, "?", print_fetch_tex), // 16 - INSTR(TEX_GET_COMP_TEX_LOD, "?", print_fetch_tex), // 17 - INSTR(TEX_GET_GRADIENTS, "?", print_fetch_tex), // 18 - INSTR(TEX_GET_WEIGHTS, "?", print_fetch_tex), // 19 - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - INSTR(TEX_SET_TEX_LOD, "SET_TEX_LOD", print_fetch_tex), // 24 - INSTR(TEX_SET_GRADIENTS_H, "?", print_fetch_tex), // 25 - INSTR(TEX_SET_GRADIENTS_V, "?", print_fetch_tex), // 26 - INSTR(TEX_RESERVED_4, "?", print_fetch_tex), // 27 + INSTR(VTX_FETCH, "VERTEX", print_fetch_vtx), // 0 + INSTR(TEX_FETCH, "SAMPLE", print_fetch_tex), // 1 + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + INSTR(TEX_GET_BORDER_COLOR_FRAC, "?", print_fetch_tex), // 16 + INSTR(TEX_GET_COMP_TEX_LOD, "?", print_fetch_tex), // 17 + INSTR(TEX_GET_GRADIENTS, "?", print_fetch_tex), // 18 + INSTR(TEX_GET_WEIGHTS, "?", print_fetch_tex), // 19 + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + INSTR(TEX_SET_TEX_LOD, "SET_TEX_LOD", print_fetch_tex), // 24 + INSTR(TEX_SET_GRADIENTS_H, "?", print_fetch_tex), // 25 + INSTR(TEX_SET_GRADIENTS_V, "?", print_fetch_tex), // 26 + INSTR(TEX_RESERVED_4, "?", print_fetch_tex), // 27 #undef INSTR }; -int disasm_fetch(Output* output, const uint32_t* dwords, uint32_t alu_off, +int disasm_fetch(StringBuffer* output, const uint32_t* dwords, uint32_t alu_off, int level, int sync) { const instr_fetch_t* fetch = (const instr_fetch_t*)dwords; - output->append("%s", levels[level]); - output->append("%02x: %08x %08x %08x\t", alu_off, dwords[0], dwords[1], - dwords[2]); + output->Append(levels[level]); + output->AppendFormat("%02x: %08x %08x %08x\t", alu_off, dwords[0], dwords[1], + dwords[2]); - output->append(" %sFETCH:\t", sync ? "(S)" : " "); + output->AppendFormat(" %sFETCH:\t", sync ? "(S)" : " "); if (fetch_instructions[fetch->opc].fxn) { - output->append("%s", fetch_instructions[fetch->opc].name); + output->Append(fetch_instructions[fetch->opc].name); fetch_instructions[fetch->opc].fxn(output, fetch); } else { - output->append("???"); + output->Append("???"); } - output->append("\n"); + output->Append('\n'); return 0; } -void print_cf_nop(Output* output, const instr_cf_t* cf) {} +void print_cf_nop(StringBuffer* output, const instr_cf_t* cf) {} -void print_cf_exec(Output* output, const instr_cf_t* cf) { - output->append(" ADDR(0x%x) CNT(0x%x)", cf->exec.address, cf->exec.count); +void print_cf_exec(StringBuffer* output, const instr_cf_t* cf) { + output->AppendFormat(" ADDR(0x%x) CNT(0x%x)", cf->exec.address, + cf->exec.count); if (cf->exec.yeild) { - output->append(" YIELD"); + output->Append(" YIELD"); } uint8_t vc = cf->exec.vc_hi | (cf->exec.vc_lo << 2); if (vc) { - output->append(" VC(0x%x)", vc); + output->AppendFormat(" VC(0x%x)", vc); } if (cf->exec.bool_addr) { - output->append(" BOOL_ADDR(0x%x)", cf->exec.bool_addr); + output->AppendFormat(" BOOL_ADDR(0x%x)", cf->exec.bool_addr); } if (cf->exec.address_mode == ABSOLUTE_ADDR) { - output->append(" ABSOLUTE_ADDR"); + output->Append(" ABSOLUTE_ADDR"); } if (cf->is_cond_exec()) { - output->append(" COND(%d)", cf->exec.pred_condition); + output->AppendFormat(" COND(%d)", cf->exec.pred_condition); } } -void print_cf_loop(Output* output, const instr_cf_t* cf) { - output->append(" ADDR(0x%x) LOOP_ID(%d)", cf->loop.address, cf->loop.loop_id); +void print_cf_loop(StringBuffer* output, const instr_cf_t* cf) { + output->AppendFormat(" ADDR(0x%x) LOOP_ID(%d)", cf->loop.address, + cf->loop.loop_id); if (cf->loop.address_mode == ABSOLUTE_ADDR) { - output->append(" ABSOLUTE_ADDR"); + output->Append(" ABSOLUTE_ADDR"); } } -void print_cf_jmp_call(Output* output, const instr_cf_t* cf) { - output->append(" ADDR(0x%x) DIR(%d)", cf->jmp_call.address, - cf->jmp_call.direction); +void print_cf_jmp_call(StringBuffer* output, const instr_cf_t* cf) { + output->AppendFormat(" ADDR(0x%x) DIR(%d)", cf->jmp_call.address, + cf->jmp_call.direction); if (cf->jmp_call.force_call) { - output->append(" FORCE_CALL"); + output->Append(" FORCE_CALL"); } if (cf->jmp_call.predicated_jmp) { - output->append(" COND(%d)", cf->jmp_call.condition); + output->AppendFormat(" COND(%d)", cf->jmp_call.condition); } if (cf->jmp_call.bool_addr) { - output->append(" BOOL_ADDR(0x%x)", cf->jmp_call.bool_addr); + output->AppendFormat(" BOOL_ADDR(0x%x)", cf->jmp_call.bool_addr); } if (cf->jmp_call.address_mode == ABSOLUTE_ADDR) { - output->append(" ABSOLUTE_ADDR"); + output->Append(" ABSOLUTE_ADDR"); } } -void print_cf_alloc(Output* output, const instr_cf_t* cf) { +void print_cf_alloc(StringBuffer* output, const instr_cf_t* cf) { static const char* bufname[] = { "NO ALLOC", // SQ_NO_ALLOC "POSITION", // SQ_POSITION "PARAM/PIXEL", // SQ_PARAMETER_PIXEL "MEMORY", // SQ_MEMORY }; - output->append(" %s SIZE(0x%x)", bufname[cf->alloc.buffer_select], - cf->alloc.size); + output->AppendFormat(" %s SIZE(0x%x)", bufname[cf->alloc.buffer_select], + cf->alloc.size); if (cf->alloc.no_serial) { - output->append(" NO_SERIAL"); + output->Append(" NO_SERIAL"); } if (cf->alloc.alloc_mode) { // ??? - output->append(" ALLOC_MODE"); + output->Append(" ALLOC_MODE"); } } struct { const char* name; - void (*fxn)(Output* output, const instr_cf_t* cf); + void (*fxn)(StringBuffer* output, const instr_cf_t* cf); } cf_instructions[] = { #define INSTR(opc, fxn) \ { #opc, fxn } - INSTR(NOP, print_cf_nop), - INSTR(EXEC, print_cf_exec), - INSTR(EXEC_END, print_cf_exec), - INSTR(COND_EXEC, print_cf_exec), - INSTR(COND_EXEC_END, print_cf_exec), - INSTR(COND_PRED_EXEC, print_cf_exec), - INSTR(COND_PRED_EXEC_END, print_cf_exec), - INSTR(LOOP_START, print_cf_loop), - INSTR(LOOP_END, print_cf_loop), - INSTR(COND_CALL, print_cf_jmp_call), - INSTR(RETURN, print_cf_jmp_call), - INSTR(COND_JMP, print_cf_jmp_call), - INSTR(ALLOC, print_cf_alloc), - INSTR(COND_EXEC_PRED_CLEAN, print_cf_exec), - INSTR(COND_EXEC_PRED_CLEAN_END, print_cf_exec), - INSTR(MARK_VS_FETCH_DONE, print_cf_nop), // ?? + INSTR(NOP, print_cf_nop), INSTR(EXEC, print_cf_exec), + INSTR(EXEC_END, print_cf_exec), INSTR(COND_EXEC, print_cf_exec), + INSTR(COND_EXEC_END, print_cf_exec), INSTR(COND_PRED_EXEC, print_cf_exec), + INSTR(COND_PRED_EXEC_END, print_cf_exec), INSTR(LOOP_START, print_cf_loop), + INSTR(LOOP_END, print_cf_loop), INSTR(COND_CALL, print_cf_jmp_call), + INSTR(RETURN, print_cf_jmp_call), INSTR(COND_JMP, print_cf_jmp_call), + INSTR(ALLOC, print_cf_alloc), INSTR(COND_EXEC_PRED_CLEAN, print_cf_exec), + INSTR(COND_EXEC_PRED_CLEAN_END, print_cf_exec), + INSTR(MARK_VS_FETCH_DONE, print_cf_nop), // ?? #undef INSTR }; -static void print_cf(Output* output, const instr_cf_t* cf, int level) { - output->append("%s", levels[level]); +static void print_cf(StringBuffer* output, const instr_cf_t* cf, int level) { + output->Append(levels[level]); const uint16_t* words = (uint16_t*)cf; - output->append(" %04x %04x %04x \t", words[0], words[1], - words[2]); + output->AppendFormat(" %04x %04x %04x \t", words[0], words[1], + words[2]); - output->append("%s", cf_instructions[cf->opc].name); + output->AppendFormat(cf_instructions[cf->opc].name); cf_instructions[cf->opc].fxn(output, cf); - output->append("\n"); + output->Append('\n'); } /* @@ -714,8 +696,9 @@ static void print_cf(Output* output, const instr_cf_t* cf, int level) { * which refers to ALU/FETCH instructions that follow it by address. * 2) ALU and FETCH instructions */ -void disasm_exec(Output* output, const uint32_t* dwords, size_t dword_count, - int level, ShaderType type, const instr_cf_t* cf) { +void disasm_exec(StringBuffer* output, const uint32_t* dwords, + size_t dword_count, int level, ShaderType type, + const instr_cf_t* cf) { uint32_t sequence = cf->exec.serialize; for (uint32_t i = 0; i < cf->exec.count; i++) { uint32_t alu_off = (cf->exec.address + i); @@ -732,7 +715,7 @@ void disasm_exec(Output* output, const uint32_t* dwords, size_t dword_count, std::string DisassembleShader(ShaderType type, const uint32_t* dwords, size_t dword_count) { - Output* output = new Output(); + StringBuffer string_buffer(256 * 1024); instr_cf_t cfa; instr_cf_t cfb; @@ -744,22 +727,20 @@ std::string DisassembleShader(ShaderType type, const uint32_t* dwords, cfa.dword_1 = dword_1 & 0xFFFF; cfb.dword_0 = (dword_1 >> 16) | (dword_2 << 16); cfb.dword_1 = dword_2 >> 16; - print_cf(output, &cfa, 0); + print_cf(&string_buffer, &cfa, 0); if (cfa.is_exec()) { - disasm_exec(output, dwords, dword_count, 0, type, &cfa); + disasm_exec(&string_buffer, dwords, dword_count, 0, type, &cfa); } - print_cf(output, &cfb, 0); + print_cf(&string_buffer, &cfb, 0); if (cfb.is_exec()) { - disasm_exec(output, dwords, dword_count, 0, type, &cfb); + disasm_exec(&string_buffer, dwords, dword_count, 0, type, &cfb); } if (cfa.opc == EXEC_END || cfb.opc == EXEC_END) { break; } } - auto result = std::string(output->buffer); - delete output; - return result; + return string_buffer.to_string(); } } // namespace gpu