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