void disassembleCF(fmt::MemoryWriter &out, const ControlFlowInst &inst) { auto id = inst.word1.CF_INST(); auto name = getInstructionName(id); out << name; switch (id) { case SQ_CF_INST_TEX: disassembleCfTEX(out, inst); break; case SQ_CF_INST_VTX: case SQ_CF_INST_VTX_TC: disassembleCfVTX(out, inst); break; 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: disassembleLoop(out, inst); break; 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: disassembleJump(out, inst); break; case SQ_CF_INST_EMIT_VERTEX: case SQ_CF_INST_EMIT_CUT_VERTEX: case SQ_CF_INST_CUT_VERTEX: if (!inst.word1.BARRIER()) { out << " NO_BARRIER"; } break; case SQ_CF_INST_PUSH: case SQ_CF_INST_PUSH_ELSE: case SQ_CF_INST_KILL: disassembleCondition(out, inst); // switch case pass through case SQ_CF_INST_POP: case SQ_CF_INST_POP_PUSH: case SQ_CF_INST_POP_PUSH_ELSE: if (inst.word1.POP_COUNT()) { out << " POP_COUNT(" << inst.word1.POP_COUNT() << ")"; } if (inst.word1.VALID_PIXEL_MODE()) { out << " VALID_PIX"; } break; case SQ_CF_INST_END_PROGRAM: case SQ_CF_INST_NOP: 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: out << " UNK_FORMAT"; break; } }
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; }