StringBuffer cleanup.

This commit is contained in:
Ben Vanik 2015-05-31 14:35:30 -07:00
parent da6edbe1d7
commit d816d80190
8 changed files with 460 additions and 456 deletions

View File

@ -32,11 +32,19 @@ void StringBuffer::Grow(size_t additional_length) {
buffer_.reserve(new_capacity);
}
void StringBuffer::Append(char c) {
AppendBytes(reinterpret_cast<const uint8_t*>(&c), 1);
}
void StringBuffer::Append(const char* value) {
AppendBytes(reinterpret_cast<const uint8_t*>(value), std::strlen(value));
}
void StringBuffer::Append(const std::string& value) {
AppendBytes(reinterpret_cast<const uint8_t*>(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);

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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());

View File

@ -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');
}
}

View File

@ -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("<entry>:\n");
} else if (!block->label_head) {
str->Append("<block%d>:\n", block_ordinal);
str->AppendFormat("<block%d>:\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: <block%d>", incoming_edge->src->ordinal);
str->AppendFormat(" ; in: <block%d>", 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: <block%d>", outgoing_edge->dest->ordinal);
str->AppendFormat(" ; out: <block%d>", 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;
}

View File

@ -38,6 +38,7 @@
#include <string.h>
#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(" <nop>\n");
output->Append(" <nop>\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