1 /**********************************************************
2  * Copyright 2008-2009 VMware, Inc.  All rights reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  **********************************************************/
25 
26 /**
27  * @file
28  * SVGA Shader Dump Facilities
29  *
30  * @author Michal Krol <michal@vmware.com>
31  */
32 
33 #include <assert.h>
34 #include <string.h>
35 
36 #include "svga_shader.h"
37 #include "svga_shader_dump.h"
38 #include "svga_shader_op.h"
39 #include "util/u_debug.h"
40 
41 #include "../svga_hw_reg.h"
42 #include "svga3d_shaderdefs.h"
43 
44 struct dump_info
45 {
46    uint32 version;
47    boolean is_ps;
48    int indent;
49 };
50 
51 #define DUMP_MAX_OP_SRC 4
52 
53 struct dump_op
54 {
55    struct sh_op op;
56    struct sh_dstreg dst;
57    struct sh_srcreg dstind;
58    struct sh_srcreg src[DUMP_MAX_OP_SRC];
59    struct sh_srcreg srcind[DUMP_MAX_OP_SRC];
60    struct sh_srcreg p0;
61 };
62 
63 static void
dump_indent(int indent)64 dump_indent(int indent)
65 {
66    int i;
67 
68    for (i = 0; i < indent; ++i) {
69       _debug_printf("  ");
70    }
71 }
72 
dump_op(struct sh_op op,const char * mnemonic)73 static void dump_op( struct sh_op op, const char *mnemonic )
74 {
75    assert( op.is_reg == 0 );
76 
77    if (op.predicated) {
78       _debug_printf("(p0) ");
79    }
80    if (op.coissue)
81       _debug_printf( "+" );
82    _debug_printf( "%s", mnemonic );
83 
84    switch (op.opcode) {
85    case SVGA3DOP_TEX:
86       switch (op.control) {
87       case 0:
88          break;
89       case 1 /* PROJECT */:
90          _debug_printf("p");
91          break;
92       case 2 /* BIAS */:
93          _debug_printf("b");
94          break;
95       default:
96          assert(0);
97       }
98       break;
99 
100    case SVGA3DOP_IFC:
101    case SVGA3DOP_BREAKC:
102    case SVGA3DOP_SETP:
103       switch (op.control) {
104       case SVGA3DOPCOMP_GT:
105          _debug_printf("_gt");
106          break;
107       case SVGA3DOPCOMP_EQ:
108          _debug_printf("_eq");
109          break;
110       case SVGA3DOPCOMP_GE:
111          _debug_printf("_ge");
112          break;
113       case SVGA3DOPCOMP_LT:
114          _debug_printf("_lt");
115          break;
116       case SVGA3DOPCOMPC_NE:
117          _debug_printf("_ne");
118          break;
119       case SVGA3DOPCOMP_LE:
120          _debug_printf("_le");
121          break;
122       default:
123          assert(0);
124       }
125       break;
126 
127    default:
128       assert(op.control == 0);
129    }
130 }
131 
132 static void
format_reg(const char * name,const struct sh_reg reg,const struct sh_srcreg * indreg)133 format_reg(const char *name,
134            const struct sh_reg reg,
135            const struct sh_srcreg *indreg)
136 {
137    if (reg.relative) {
138       assert(indreg);
139 
140       if (sh_srcreg_type(*indreg) == SVGA3DREG_LOOP) {
141          _debug_printf("%s[aL+%u]", name, reg.number);
142       } else {
143          _debug_printf("%s[a%u.x+%u]", name, indreg->number, reg.number);
144       }
145    } else {
146       _debug_printf("%s%u", name, reg.number);
147    }
148 }
149 
dump_reg(struct sh_reg reg,struct sh_srcreg * indreg,const struct dump_info * di)150 static void dump_reg( struct sh_reg reg, struct sh_srcreg *indreg, const struct dump_info *di )
151 {
152    assert( reg.is_reg == 1 );
153 
154    switch (sh_reg_type( reg )) {
155    case SVGA3DREG_TEMP:
156       format_reg("r", reg, NULL);
157       break;
158 
159    case SVGA3DREG_INPUT:
160       format_reg("v", reg, indreg);
161       break;
162 
163    case SVGA3DREG_CONST:
164       format_reg("c", reg, indreg);
165       break;
166 
167    case SVGA3DREG_ADDR:    /* VS */
168    /* SVGA3DREG_TEXTURE */ /* PS */
169       assert(!reg.relative);
170       if (di->is_ps) {
171          format_reg("t", reg, NULL);
172       } else {
173          format_reg("a", reg, NULL);
174       }
175       break;
176 
177    case SVGA3DREG_RASTOUT:
178       assert(!reg.relative);
179       switch (reg.number) {
180       case 0 /*POSITION*/:
181          _debug_printf( "oPos" );
182          break;
183       case 1 /*FOG*/:
184          _debug_printf( "oFog" );
185          break;
186       case 2 /*POINT_SIZE*/:
187          _debug_printf( "oPts" );
188          break;
189       default:
190          assert( 0 );
191          _debug_printf( "???" );
192       }
193       break;
194 
195    case SVGA3DREG_ATTROUT:
196       assert( reg.number < 2 );
197       format_reg("oD", reg, NULL);
198       break;
199 
200    case SVGA3DREG_TEXCRDOUT:  /* VS */
201    /* SVGA3DREG_OUTPUT */     /* VS3.0+ */
202       if (!di->is_ps && di->version >= SVGA3D_VS_30) {
203          format_reg("o", reg, indreg);
204       } else {
205          format_reg("oT", reg, NULL);
206       }
207       break;
208 
209    case SVGA3DREG_COLOROUT:
210       format_reg("oC", reg, NULL);
211       break;
212 
213    case SVGA3DREG_DEPTHOUT:
214       assert(!reg.relative);
215       assert(reg.number == 0);
216       _debug_printf("oDepth");
217       break;
218 
219    case SVGA3DREG_SAMPLER:
220       format_reg("s", reg, NULL);
221       break;
222 
223    case SVGA3DREG_CONSTBOOL:
224       format_reg("b", reg, NULL);
225       break;
226 
227    case SVGA3DREG_CONSTINT:
228       format_reg("i", reg, NULL);
229       break;
230 
231    case SVGA3DREG_LOOP:
232       assert(!reg.relative);
233       assert( reg.number == 0 );
234       _debug_printf( "aL" );
235       break;
236 
237    case SVGA3DREG_MISCTYPE:
238       assert(!reg.relative);
239       switch (reg.number) {
240       case SVGA3DMISCREG_POSITION:
241          _debug_printf("vPos");
242          break;
243       case SVGA3DMISCREG_FACE:
244          _debug_printf("vFace");
245          break;
246       default:
247          assert(0);
248          _debug_printf("???");
249       }
250       break;
251 
252    case SVGA3DREG_LABEL:
253       format_reg("l", reg, NULL);
254       break;
255 
256    case SVGA3DREG_PREDICATE:
257       format_reg("p", reg, NULL);
258       break;
259 
260    default:
261       assert( 0 );
262       _debug_printf( "???" );
263    }
264 }
265 
dump_cdata(struct sh_cdata cdata)266 static void dump_cdata( struct sh_cdata cdata )
267 {
268    _debug_printf( "%f, %f, %f, %f", cdata.xyzw[0], cdata.xyzw[1], cdata.xyzw[2], cdata.xyzw[3] );
269 }
270 
dump_idata(struct sh_idata idata)271 static void dump_idata( struct sh_idata idata )
272 {
273    _debug_printf( "%d, %d, %d, %d", idata.xyzw[0], idata.xyzw[1], idata.xyzw[2], idata.xyzw[3] );
274 }
275 
dump_bdata(boolean bdata)276 static void dump_bdata( boolean bdata )
277 {
278    _debug_printf( bdata ? "TRUE" : "FALSE" );
279 }
280 
281 static void
dump_sampleinfo(struct sh_sampleinfo sampleinfo)282 dump_sampleinfo(struct sh_sampleinfo sampleinfo)
283 {
284    assert( sampleinfo.is_reg == 1 );
285 
286    switch (sampleinfo.texture_type) {
287    case SVGA3DSAMP_2D:
288       _debug_printf( "_2d" );
289       break;
290    case SVGA3DSAMP_2D_SHADOW:
291       _debug_printf( "_2dshadow" );
292       break;
293    case SVGA3DSAMP_CUBE:
294       _debug_printf( "_cube" );
295       break;
296    case SVGA3DSAMP_VOLUME:
297       _debug_printf( "_volume" );
298       break;
299    default:
300       assert( 0 );
301    }
302 }
303 
304 static void
dump_semantic(uint usage,uint usage_index)305 dump_semantic(uint usage,
306               uint usage_index)
307 {
308    switch (usage) {
309    case SVGA3D_DECLUSAGE_POSITION:
310       _debug_printf("_position");
311       break;
312    case SVGA3D_DECLUSAGE_BLENDWEIGHT:
313       _debug_printf("_blendweight");
314       break;
315    case SVGA3D_DECLUSAGE_BLENDINDICES:
316       _debug_printf("_blendindices");
317       break;
318    case SVGA3D_DECLUSAGE_NORMAL:
319       _debug_printf("_normal");
320       break;
321    case SVGA3D_DECLUSAGE_PSIZE:
322       _debug_printf("_psize");
323       break;
324    case SVGA3D_DECLUSAGE_TEXCOORD:
325       _debug_printf("_texcoord");
326       break;
327    case SVGA3D_DECLUSAGE_TANGENT:
328       _debug_printf("_tangent");
329       break;
330    case SVGA3D_DECLUSAGE_BINORMAL:
331       _debug_printf("_binormal");
332       break;
333    case SVGA3D_DECLUSAGE_TESSFACTOR:
334       _debug_printf("_tessfactor");
335       break;
336    case SVGA3D_DECLUSAGE_POSITIONT:
337       _debug_printf("_positiont");
338       break;
339    case SVGA3D_DECLUSAGE_COLOR:
340       _debug_printf("_color");
341       break;
342    case SVGA3D_DECLUSAGE_FOG:
343       _debug_printf("_fog");
344       break;
345    case SVGA3D_DECLUSAGE_DEPTH:
346       _debug_printf("_depth");
347       break;
348    case SVGA3D_DECLUSAGE_SAMPLE:
349       _debug_printf("_sample");
350       break;
351    default:
352       assert(!"Unknown usage");
353       _debug_printf("_???");
354    }
355 
356    if (usage_index) {
357       _debug_printf("%u", usage_index);
358    }
359 }
360 
361 static void
dump_dstreg(struct sh_dstreg dstreg,struct sh_srcreg * indreg,const struct dump_info * di)362 dump_dstreg(struct sh_dstreg dstreg,
363             struct sh_srcreg *indreg,
364             const struct dump_info *di)
365 {
366    union {
367       struct sh_reg reg;
368       struct sh_dstreg dstreg;
369    } u;
370 
371    memset(&u, 0, sizeof(u));
372 
373    assert( (dstreg.modifier & (SVGA3DDSTMOD_SATURATE | SVGA3DDSTMOD_PARTIALPRECISION)) == dstreg.modifier );
374 
375    if (dstreg.modifier & SVGA3DDSTMOD_SATURATE)
376       _debug_printf( "_sat" );
377    if (dstreg.modifier & SVGA3DDSTMOD_PARTIALPRECISION)
378       _debug_printf( "_pp" );
379    switch (dstreg.shift_scale) {
380    case 0:
381       break;
382    case 1:
383       _debug_printf( "_x2" );
384       break;
385    case 2:
386       _debug_printf( "_x4" );
387       break;
388    case 3:
389       _debug_printf( "_x8" );
390       break;
391    case 13:
392       _debug_printf( "_d8" );
393       break;
394    case 14:
395       _debug_printf( "_d4" );
396       break;
397    case 15:
398       _debug_printf( "_d2" );
399       break;
400    default:
401       assert( 0 );
402    }
403    _debug_printf( " " );
404 
405    u.dstreg = dstreg;
406    dump_reg( u.reg, indreg, di);
407    if (dstreg.write_mask != SVGA3DWRITEMASK_ALL) {
408       _debug_printf( "." );
409       if (dstreg.write_mask & SVGA3DWRITEMASK_0)
410          _debug_printf( "x" );
411       if (dstreg.write_mask & SVGA3DWRITEMASK_1)
412          _debug_printf( "y" );
413       if (dstreg.write_mask & SVGA3DWRITEMASK_2)
414          _debug_printf( "z" );
415       if (dstreg.write_mask & SVGA3DWRITEMASK_3)
416          _debug_printf( "w" );
417    }
418 }
419 
dump_srcreg(struct sh_srcreg srcreg,struct sh_srcreg * indreg,const struct dump_info * di)420 static void dump_srcreg( struct sh_srcreg srcreg, struct sh_srcreg *indreg, const struct dump_info *di )
421 {
422    struct sh_reg srcreg_sh = {0};
423    /* bit-fields carefully aligned, ensure they stay that way. */
424    STATIC_ASSERT(sizeof(struct sh_reg) == sizeof(struct sh_srcreg));
425    memcpy(&srcreg_sh, &srcreg, sizeof(srcreg_sh));
426 
427    switch (srcreg.modifier) {
428    case SVGA3DSRCMOD_NEG:
429    case SVGA3DSRCMOD_BIASNEG:
430    case SVGA3DSRCMOD_SIGNNEG:
431    case SVGA3DSRCMOD_X2NEG:
432    case SVGA3DSRCMOD_ABSNEG:
433       _debug_printf( "-" );
434       break;
435    case SVGA3DSRCMOD_COMP:
436       _debug_printf( "1-" );
437       break;
438    case SVGA3DSRCMOD_NOT:
439       _debug_printf( "!" );
440    }
441    dump_reg(srcreg_sh, indreg, di );
442    switch (srcreg.modifier) {
443    case SVGA3DSRCMOD_NONE:
444    case SVGA3DSRCMOD_NEG:
445    case SVGA3DSRCMOD_COMP:
446    case SVGA3DSRCMOD_NOT:
447       break;
448    case SVGA3DSRCMOD_BIAS:
449    case SVGA3DSRCMOD_BIASNEG:
450       _debug_printf( "_bias" );
451       break;
452    case SVGA3DSRCMOD_SIGN:
453    case SVGA3DSRCMOD_SIGNNEG:
454       _debug_printf( "_bx2" );
455       break;
456    case SVGA3DSRCMOD_X2:
457    case SVGA3DSRCMOD_X2NEG:
458       _debug_printf( "_x2" );
459       break;
460    case SVGA3DSRCMOD_DZ:
461       _debug_printf( "_dz" );
462       break;
463    case SVGA3DSRCMOD_DW:
464       _debug_printf( "_dw" );
465       break;
466    case SVGA3DSRCMOD_ABS:
467    case SVGA3DSRCMOD_ABSNEG:
468       _debug_printf("_abs");
469       break;
470    default:
471       assert( 0 );
472    }
473    if (srcreg.swizzle_x != 0 || srcreg.swizzle_y != 1 || srcreg.swizzle_z != 2 || srcreg.swizzle_w != 3) {
474       _debug_printf( "." );
475       if (srcreg.swizzle_x == srcreg.swizzle_y && srcreg.swizzle_y == srcreg.swizzle_z && srcreg.swizzle_z == srcreg.swizzle_w) {
476          _debug_printf( "%c", "xyzw"[srcreg.swizzle_x] );
477       }
478       else {
479          _debug_printf( "%c", "xyzw"[srcreg.swizzle_x] );
480          _debug_printf( "%c", "xyzw"[srcreg.swizzle_y] );
481          _debug_printf( "%c", "xyzw"[srcreg.swizzle_z] );
482          _debug_printf( "%c", "xyzw"[srcreg.swizzle_w] );
483       }
484    }
485 }
486 
487 static void
parse_op(struct dump_info * di,const uint ** token,struct dump_op * op,uint num_dst,uint num_src)488 parse_op(struct dump_info *di,
489          const uint **token,
490          struct dump_op *op,
491          uint num_dst,
492          uint num_src)
493 {
494    uint i;
495 
496    assert(num_dst <= 1);
497    assert(num_src <= DUMP_MAX_OP_SRC);
498 
499    op->op = *(struct sh_op *)*token;
500    *token += sizeof(struct sh_op) / sizeof(uint);
501 
502    if (num_dst >= 1) {
503       op->dst = *(struct sh_dstreg *)*token;
504       *token += sizeof(struct sh_dstreg) / sizeof(uint);
505       if (op->dst.relative &&
506           (!di->is_ps && di->version >= SVGA3D_VS_30)) {
507          op->dstind = *(struct sh_srcreg *)*token;
508          *token += sizeof(struct sh_srcreg) / sizeof(uint);
509       }
510    }
511 
512    if (op->op.predicated) {
513       op->p0 = *(struct sh_srcreg *)*token;
514       *token += sizeof(struct sh_srcreg) / sizeof(uint);
515    }
516 
517    for (i = 0; i < num_src; ++i) {
518       op->src[i] = *(struct sh_srcreg *)*token;
519       *token += sizeof(struct sh_srcreg) / sizeof(uint);
520       if (op->src[i].relative &&
521           ((!di->is_ps && di->version >= SVGA3D_VS_20) ||
522           (di->is_ps && di->version >= SVGA3D_PS_30))) {
523          op->srcind[i] = *(struct sh_srcreg *)*token;
524          *token += sizeof(struct sh_srcreg) / sizeof(uint);
525       }
526    }
527 }
528 
529 static void
dump_inst(struct dump_info * di,const unsigned ** assem,struct sh_op op,const struct sh_opcode_info * info)530 dump_inst(struct dump_info *di,
531           const unsigned **assem,
532           struct sh_op op,
533           const struct sh_opcode_info *info)
534 {
535    struct dump_op dop;
536    boolean not_first_arg = FALSE;
537    uint i;
538 
539    assert(info->num_dst <= 1);
540 
541    di->indent -= info->pre_dedent;
542    dump_indent(di->indent);
543    di->indent += info->post_indent;
544 
545    dump_op(op, info->mnemonic);
546 
547    parse_op(di, assem, &dop, info->num_dst, info->num_src);
548    if (info->num_dst > 0) {
549       dump_dstreg(dop.dst, &dop.dstind, di);
550       not_first_arg = TRUE;
551    }
552 
553    for (i = 0; i < info->num_src; i++) {
554       if (not_first_arg) {
555          _debug_printf(", ");
556       } else {
557          _debug_printf(" ");
558       }
559       dump_srcreg(dop.src[i], &dop.srcind[i], di);
560       not_first_arg = TRUE;
561    }
562 
563    _debug_printf("\n");
564 }
565 
566 void
svga_shader_dump(const unsigned * assem,unsigned dwords,unsigned do_binary)567 svga_shader_dump(
568    const unsigned *assem,
569    unsigned dwords,
570    unsigned do_binary )
571 {
572    boolean finished = FALSE;
573    struct dump_info di;
574 
575    di.version = *assem++;
576    di.is_ps = (di.version & 0xFFFF0000) == 0xFFFF0000;
577    di.indent = 0;
578 
579    _debug_printf(
580       "%s_%u_%u\n",
581       di.is_ps ? "ps" : "vs",
582       (di.version >> 8) & 0xff,
583       di.version & 0xff );
584 
585    while (!finished) {
586       struct sh_op op = *(struct sh_op *) assem;
587 
588       switch (op.opcode) {
589       case SVGA3DOP_DCL:
590          {
591             struct sh_dcl dcl = *(struct sh_dcl *) assem;
592 
593             _debug_printf( "dcl" );
594             switch (sh_dstreg_type(dcl.reg)) {
595             case SVGA3DREG_INPUT:
596                if ((di.is_ps && di.version >= SVGA3D_PS_30) ||
597                    (!di.is_ps && di.version >= SVGA3D_VS_30)) {
598                   dump_semantic(dcl.u.semantic.usage,
599                                 dcl.u.semantic.usage_index);
600                }
601                break;
602             case SVGA3DREG_TEXCRDOUT:
603                if (!di.is_ps && di.version >= SVGA3D_VS_30) {
604                   dump_semantic(dcl.u.semantic.usage,
605                                 dcl.u.semantic.usage_index);
606                }
607                break;
608             case SVGA3DREG_SAMPLER:
609                dump_sampleinfo( dcl.u.sampleinfo );
610                break;
611             }
612             dump_dstreg(dcl.reg, NULL, &di);
613             _debug_printf( "\n" );
614             assem += sizeof( struct sh_dcl ) / sizeof( unsigned );
615          }
616          break;
617 
618       case SVGA3DOP_DEFB:
619          {
620             struct sh_defb defb = *(struct sh_defb *) assem;
621 
622             _debug_printf( "defb " );
623             dump_reg( defb.reg, NULL, &di );
624             _debug_printf( ", " );
625             dump_bdata( defb.data );
626             _debug_printf( "\n" );
627             assem += sizeof( struct sh_defb ) / sizeof( unsigned );
628          }
629          break;
630 
631       case SVGA3DOP_DEFI:
632          {
633             struct sh_defi defi = *(struct sh_defi *) assem;
634 
635             _debug_printf( "defi " );
636             dump_reg( defi.reg, NULL, &di );
637             _debug_printf( ", " );
638             dump_idata( defi.idata );
639             _debug_printf( "\n" );
640             assem += sizeof( struct sh_defi ) / sizeof( unsigned );
641          }
642          break;
643 
644       case SVGA3DOP_TEXCOORD:
645          {
646             struct sh_opcode_info info = *svga_opcode_info(op.opcode);
647 
648             assert(di.is_ps);
649             if (di.version > SVGA3D_PS_13) {
650                assert(info.num_src == 0);
651 
652                info.num_src = 1;
653             }
654 
655             dump_inst(&di, &assem, op, &info);
656          }
657          break;
658 
659       case SVGA3DOP_TEX:
660          {
661             struct sh_opcode_info info = *svga_opcode_info(op.opcode);
662 
663             assert(di.is_ps);
664             if (di.version > SVGA3D_PS_13) {
665                assert(info.num_src == 0);
666 
667                if (di.version > SVGA3D_PS_14) {
668                   info.num_src = 2;
669                   info.mnemonic = "texld";
670                } else {
671                   info.num_src = 1;
672                }
673             }
674 
675             dump_inst(&di, &assem, op, &info);
676          }
677          break;
678 
679       case SVGA3DOP_DEF:
680          {
681             struct sh_def def = *(struct sh_def *) assem;
682 
683             _debug_printf( "def " );
684             dump_reg( def.reg, NULL, &di );
685             _debug_printf( ", " );
686             dump_cdata( def.cdata );
687             _debug_printf( "\n" );
688             assem += sizeof( struct sh_def ) / sizeof( unsigned );
689          }
690          break;
691 
692       case SVGA3DOP_SINCOS:
693          {
694             struct sh_opcode_info info = *svga_opcode_info(op.opcode);
695 
696             if ((di.is_ps && di.version >= SVGA3D_PS_30) ||
697                 (!di.is_ps && di.version >= SVGA3D_VS_30)) {
698                assert(info.num_src == 3);
699 
700                info.num_src = 1;
701             }
702 
703             dump_inst(&di, &assem, op, &info);
704          }
705          break;
706 
707       case SVGA3DOP_PHASE:
708          _debug_printf( "phase\n" );
709          assem += sizeof( struct sh_op ) / sizeof( unsigned );
710          break;
711 
712       case SVGA3DOP_COMMENT:
713          {
714             struct sh_comment comment = *(struct sh_comment *)assem;
715 
716             /* Ignore comment contents. */
717             assem += sizeof(struct sh_comment) / sizeof(unsigned) + comment.size;
718          }
719          break;
720 
721       case SVGA3DOP_END:
722          finished = TRUE;
723          break;
724 
725       default:
726          {
727             const struct sh_opcode_info *info = svga_opcode_info(op.opcode);
728 
729             dump_inst(&di, &assem, op, info);
730          }
731       }
732    }
733 }
734