bool disassembleNormal(DisassembleState &state, latte::cf::inst id, latte::cf::Instruction &cf) { auto name = latte::cf::name[id]; switch (id) { case latte::cf::TEX: return disassembleTEX(state, id, cf); case latte::cf::LOOP_START: case latte::cf::LOOP_START_DX10: case latte::cf::LOOP_START_NO_AL: state.out << name << " FAIL_JUMP_ADDR(" << cf.word0.addr << ")"; endLine(state); increaseIndent(state); break; case latte::cf::LOOP_END: state.out << name << " PASS_JUMP_ADDR(" << cf.word0.addr << ")"; endLine(state); decreaseIndent(state); break; case latte::cf::ELSE: case latte::cf::JUMP: state.out << name << " POP_CNT(" << cf.word1.popCount << ")" << " ADDR(" << cf.word0.addr << ")"; endLine(state); break; case latte::cf::NOP: case latte::cf::CALL_FS: case latte::cf::END_PROGRAM: state.out << name; endLine(state); break; case latte::cf::VTX: case latte::cf::VTX_TC: case latte::cf::LOOP_CONTINUE: case latte::cf::LOOP_BREAK: case latte::cf::POP_JUMP: case latte::cf::CALL: case latte::cf::RETURN: case latte::cf::EMIT_VERTEX: case latte::cf::EMIT_CUT_VERTEX: case latte::cf::CUT_VERTEX: case latte::cf::KILL: case latte::cf::PUSH: case latte::cf::PUSH_ELSE: case latte::cf::POP: case latte::cf::POP_PUSH: case latte::cf::POP_PUSH_ELSE: case latte::cf::WAIT_ACK: case latte::cf::TEX_ACK: case latte::cf::VTX_ACK: case latte::cf::VTX_TC_ACK: default: assert(false); break; } return true; }
bool disassembleControlFlow(State &state, shadir::CfInstruction *inst) { state.out.write("{}{:02} {}", state.indent, inst->cfPC, inst->name); switch (inst->id) { case SQ_CF_INST_TEX: return disassembleTEX(state, inst); case SQ_CF_INST_VTX: case SQ_CF_INST_VTX_TC: return disassembleVTX(state, inst); case SQ_CF_INST_LOOP_START: case SQ_CF_INST_LOOP_START_DX10: case SQ_CF_INST_LOOP_START_NO_AL: case SQ_CF_INST_LOOP_END: case SQ_CF_INST_LOOP_CONTINUE: case SQ_CF_INST_LOOP_BREAK: return disassembleLoop(state, inst); case SQ_CF_INST_JUMP: case SQ_CF_INST_ELSE: case SQ_CF_INST_CALL: case SQ_CF_INST_CALL_FS: case SQ_CF_INST_RETURN: case SQ_CF_INST_POP_JUMP: return disassembleJump(state, inst); case SQ_CF_INST_EMIT_VERTEX: case SQ_CF_INST_EMIT_CUT_VERTEX: case SQ_CF_INST_CUT_VERTEX: if (!inst->barrier) { state.out << " NO_BARRIER"; } state.out << '\n'; break; case SQ_CF_INST_PUSH: case SQ_CF_INST_PUSH_ELSE: case SQ_CF_INST_KILL: disassembleCondition(state, inst); // pass through case SQ_CF_INST_POP: case SQ_CF_INST_POP_PUSH: case SQ_CF_INST_POP_PUSH_ELSE: if (inst->popCount) { state.out << " POP_COUNT(" << inst->popCount << ")"; } if (inst->validPixelMode) { state.out << " VALID_PIX"; } state.out << '\n'; break; case SQ_CF_INST_END_PROGRAM: case SQ_CF_INST_NOP: state.out << '\n'; break; case SQ_CF_INST_WAIT_ACK: case SQ_CF_INST_TEX_ACK: case SQ_CF_INST_VTX_ACK: case SQ_CF_INST_VTX_TC_ACK: default: state.out << " UNK_FORMAT\n"; break; } return false; }