+static void
+parse_op(struct dump_info *di,
+ const uint **token,
+ struct dump_op *op,
+ uint num_dst,
+ uint num_src)
+{
+ uint i;
+
+ assert(num_dst <= 1);
+ assert(num_src <= DUMP_MAX_OP_SRC);
+
+ op->op = *(struct sh_op *)*token;
+ *token += sizeof(struct sh_op) / sizeof(uint);
+
+ if (num_dst >= 1) {
+ op->dst = *(struct sh_dstreg *)*token;
+ *token += sizeof(struct sh_dstreg) / sizeof(uint);
+ if (op->dst.relative &&
+ (!di->is_ps && di->version >= SVGA3D_VS_30)) {
+ op->dstind = *(struct sh_srcreg *)*token;
+ *token += sizeof(struct sh_srcreg) / sizeof(uint);
+ }
+ }
+
+ if (op->op.predicated) {
+ op->p0 = *(struct sh_srcreg *)*token;
+ *token += sizeof(struct sh_srcreg) / sizeof(uint);
+ }
+
+ for (i = 0; i < num_src; ++i) {
+ op->src[i] = *(struct sh_srcreg *)*token;
+ *token += sizeof(struct sh_srcreg) / sizeof(uint);
+ if (op->src[i].relative &&
+ ((!di->is_ps && di->version >= SVGA3D_VS_20) ||
+ (di->is_ps && di->version >= SVGA3D_PS_30))) {
+ op->srcind[i] = *(struct sh_srcreg *)*token;
+ *token += sizeof(struct sh_srcreg) / sizeof(uint);
+ }
+ }
+}
+
+static void
+dump_inst(struct dump_info *di,
+ const unsigned **assem,
+ struct sh_op op,
+ const struct sh_opcode_info *info)
+{
+ struct dump_op dop;
+ boolean not_first_arg = FALSE;
+ uint i;
+
+ assert(info->num_dst <= 1);
+
+ di->indent -= info->pre_dedent;
+ dump_indent(di->indent);
+ di->indent += info->post_indent;
+
+ dump_op(op, info->mnemonic);
+
+ parse_op(di, assem, &dop, info->num_dst, info->num_src);
+ if (info->num_dst > 0) {
+ dump_dstreg(dop.dst, &dop.dstind, di);
+ not_first_arg = TRUE;
+ }
+
+ for (i = 0; i < info->num_src; i++) {
+ if (not_first_arg) {
+ _debug_printf(", ");
+ } else {
+ _debug_printf(" ");
+ }
+ dump_srcreg(dop.src[i], &dop.srcind[i], di);
+ not_first_arg = TRUE;
+ }
+
+ _debug_printf("\n");
+}
+