xref: /aosp_15_r20/external/mesa3d/src/imagination/vulkan/pds/pvr_pds_printer.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2022 Imagination Technologies Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #include <stdbool.h>
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 
29 #include "pvr_rogue_pds_defs.h"
30 #include "pvr_rogue_pds_disasm.h"
31 #include "pvr_rogue_pds_encode.h"
32 #include "util/log.h"
33 
34 #define X(lop, str) #str,
35 static const char *const LOP[] = { PVR_PDS_LOP };
36 #undef X
37 
pvr_pds_disassemble_operand(struct pvr_operand * op,char * instr_str,size_t instr_len)38 static void pvr_pds_disassemble_operand(struct pvr_operand *op,
39                                         char *instr_str,
40                                         size_t instr_len)
41 {
42 #define X(enum, str, size) { #str, #size },
43    static const char *const regs[][2] = { PVR_PDS_OPERAND_TYPES };
44 #undef X
45 
46    if (op->type == LITERAL_NUM) {
47       snprintf(instr_str,
48                instr_len,
49                "%s (%llu)",
50                regs[op->type][0],
51                (unsigned long long)op->literal);
52    } else if (op->type == UNRESOLVED) {
53       snprintf(instr_str, instr_len, "UNRESOLVED");
54    } else {
55       snprintf(instr_str,
56                instr_len,
57                "%s[%u].%s",
58                regs[op->type][0],
59                op->absolute_address,
60                regs[op->type][1]);
61    }
62 }
63 
pvr_pds_disassemble_instruction_add64(struct pvr_add * add,char * instr_str,size_t instr_len)64 static void pvr_pds_disassemble_instruction_add64(struct pvr_add *add,
65                                                   char *instr_str,
66                                                   size_t instr_len)
67 {
68    char dst[32];
69    char src0[32];
70    char src1[32];
71 
72    pvr_pds_disassemble_operand(add->src0, src0, sizeof(src0));
73    pvr_pds_disassemble_operand(add->src1, src1, sizeof(src1));
74    pvr_pds_disassemble_operand(add->dst, dst, sizeof(dst));
75 
76    snprintf(instr_str,
77             instr_len,
78             "%-16s%s%s = %s %s %s %s",
79             "ADD64",
80             add->cc ? "? " : "",
81             dst,
82             src0,
83             add->sna ? "-" : "+",
84             src1,
85             add->alum ? "[signed]" : "");
86 }
87 
pvr_pds_disassemble_instruction_add32(struct pvr_add * add,char * instr_str,size_t instr_len)88 static void pvr_pds_disassemble_instruction_add32(struct pvr_add *add,
89                                                   char *instr_str,
90                                                   size_t instr_len)
91 {
92    char dst[32];
93    char src0[32];
94    char src1[32];
95 
96    pvr_pds_disassemble_operand(add->src0, src0, sizeof(src0));
97    pvr_pds_disassemble_operand(add->src1, src1, sizeof(src1));
98    pvr_pds_disassemble_operand(add->dst, dst, sizeof(dst));
99 
100    snprintf(instr_str,
101             instr_len,
102             "%-16s%s%s = %s %s %s %s",
103             "ADD32",
104             add->cc ? "? " : "",
105             dst,
106             src0,
107             add->sna ? "-" : "+",
108             src1,
109             add->alum ? "[signed]" : "");
110 }
111 
112 static void
pvr_pds_disassemble_instruction_sftlp32(struct pvr_sftlp * instruction,char * instr_str,size_t instr_len)113 pvr_pds_disassemble_instruction_sftlp32(struct pvr_sftlp *instruction,
114                                         char *instr_str,
115                                         size_t instr_len)
116 {
117    char dst[32];
118    char src0[32];
119    char src1[32];
120    char src2[32];
121 
122    pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
123    pvr_pds_disassemble_operand(instruction->src1, src1, sizeof(src1));
124    pvr_pds_disassemble_operand(instruction->dst, dst, sizeof(dst));
125 
126    if (instruction->IM)
127       snprintf(src2, sizeof(src2), "%u", (uint32_t)instruction->src2->literal);
128    else
129       pvr_pds_disassemble_operand(instruction->src2, src2, sizeof(src2));
130 
131    if (instruction->lop == LOP_NONE) {
132       snprintf(instr_str,
133                instr_len,
134                "%-16s%s%s = %s %s %s",
135                "SFTLP32",
136                instruction->cc ? "? " : "",
137                dst,
138                src0,
139                instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
140                src2);
141    } else if (instruction->lop == LOP_NOT) {
142       snprintf(instr_str,
143                instr_len,
144                "%-16s%s%s = (~%s) %s %s",
145                "SFTLP32",
146                instruction->cc ? "? " : "",
147                dst,
148                src0,
149                instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
150                src2);
151    } else {
152       snprintf(instr_str,
153                instr_len,
154                "%-16s%s%s = (%s %s %s) %s %s",
155                "SFTLP32",
156                instruction->cc ? "? " : "",
157                dst,
158                src0,
159                LOP[instruction->lop],
160                src1,
161                instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
162                src2);
163    }
164 }
165 
pvr_pds_disassemble_instruction_stm(struct pvr_stm * instruction,char * instr_str,size_t instr_len)166 static void pvr_pds_disassemble_instruction_stm(struct pvr_stm *instruction,
167                                                 char *instr_str,
168                                                 size_t instr_len)
169 {
170    char src0[32];
171    char src1[32];
172    char src2[32];
173    char src3[32];
174 
175    char stm_pred[64];
176 
177    pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
178    pvr_pds_disassemble_operand(instruction->src1, src1, sizeof(src1));
179    pvr_pds_disassemble_operand(instruction->src2, src2, sizeof(src2));
180    pvr_pds_disassemble_operand(instruction->src3, src3, sizeof(src3));
181 
182    if (instruction->ccs_global)
183       snprintf(stm_pred, sizeof(stm_pred), "overflow_any");
184    else if (instruction->ccs_so)
185       snprintf(stm_pred, sizeof(stm_pred), "overflow_current");
186    else
187       stm_pred[0] = 0;
188 
189    snprintf(instr_str,
190             instr_len,
191             "%-16s%s%s%s stm%u = %s, %s, %s, %s",
192             "STM",
193             instruction->cc ? "? " : "",
194             stm_pred,
195             instruction->tst ? " (TST only)" : "",
196             instruction->stream_out,
197             src0,
198             src1,
199             src2,
200             src3);
201 }
202 
pds_disassemble_instruction_stmc(struct pvr_stmc * instruction,char * instr_str,size_t instr_len)203 static void pds_disassemble_instruction_stmc(struct pvr_stmc *instruction,
204                                              char *instr_str,
205                                              size_t instr_len)
206 {
207    char src0[32];
208 
209    pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
210 
211    snprintf(instr_str,
212             instr_len,
213             "%-16s%s %s",
214             "STMC",
215             instruction->cc ? "? " : "",
216             src0);
217 }
218 
219 static void
pvr_pds_disassemble_instruction_sftlp64(struct pvr_sftlp * instruction,char * instr_str,size_t instr_len)220 pvr_pds_disassemble_instruction_sftlp64(struct pvr_sftlp *instruction,
221                                         char *instr_str,
222                                         size_t instr_len)
223 {
224    char dst[32];
225    char src0[32];
226    char src1[32];
227    char src2[32];
228 
229    pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
230    pvr_pds_disassemble_operand(instruction->src1, src1, sizeof(src1));
231    pvr_pds_disassemble_operand(instruction->dst, dst, sizeof(dst));
232 
233    if (instruction->IM)
234       snprintf(src2, sizeof(src2), "%u", (uint32_t)instruction->src2->literal);
235    else
236       pvr_pds_disassemble_operand(instruction->src2, src2, sizeof(src2));
237 
238    if (instruction->lop == LOP_NONE) {
239       snprintf(instr_str,
240                instr_len,
241                "%-16s%s%s = %s %s %s",
242                "SFTLP64",
243                instruction->cc ? "? " : "",
244                dst,
245                src0,
246                instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
247                src2);
248    } else if (instruction->lop == LOP_NOT) {
249       snprintf(instr_str,
250                instr_len,
251                "%-16s%s%s = (~%s) %s %s",
252                "SFTLP64",
253                instruction->cc ? "? " : "",
254                dst,
255                src0,
256                instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
257                src2);
258    } else {
259       snprintf(instr_str,
260                instr_len,
261                "%-16s%s%s = (%s %s %s) %s %s",
262                "SFTLP64",
263                instruction->cc ? "? " : "",
264                dst,
265                src0,
266                LOP[instruction->lop],
267                src1,
268                instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
269                src2);
270    }
271 }
272 
pvr_pds_disassemble_instruction_cmp(struct pvr_cmp * cmp,char * instr_str,size_t instr_len)273 static void pvr_pds_disassemble_instruction_cmp(struct pvr_cmp *cmp,
274                                                 char *instr_str,
275                                                 size_t instr_len)
276 {
277    char src0[32];
278    char src1[32];
279    static const char *const COP[] = { "=", ">", "<", "!=" };
280 
281    pvr_pds_disassemble_operand(cmp->src0, src0, sizeof(src0));
282 
283    if (cmp->IM) {
284       snprintf(src1,
285                sizeof(src1),
286                "%#04llx",
287                (unsigned long long)cmp->src1->literal);
288    } else {
289       pvr_pds_disassemble_operand(cmp->src1, src1, sizeof(src1));
290    }
291 
292    snprintf(instr_str,
293             instr_len,
294             "%-16s%sP0 = (%s %s %s)",
295             "CMP",
296             cmp->cc ? "? " : "",
297             src0,
298             COP[cmp->cop],
299             src1);
300 }
301 
pvr_pds_disassemble_instruction_ldst(struct pvr_ldst * ins,char * instr_str,size_t instr_len)302 static void pvr_pds_disassemble_instruction_ldst(struct pvr_ldst *ins,
303                                                  char *instr_str,
304                                                  size_t instr_len)
305 {
306    char src0[PVR_PDS_MAX_INST_STR_LEN];
307 
308    pvr_pds_disassemble_operand(ins->src0, src0, sizeof(src0));
309 
310    if (ins->st) {
311       snprintf(instr_str,
312                instr_len,
313                "%-16s%s%s: mem(%s) <= src(%s)",
314                "ST",
315                ins->cc ? "? " : "",
316                src0,
317                "?",
318                "?");
319    } else {
320       snprintf(instr_str,
321                instr_len,
322                "%-16s%s%s: dst(%s) <= mem(%s)",
323                "ld",
324                ins->cc ? "? " : "",
325                src0,
326                "?",
327                "?");
328    }
329 }
330 
pvr_pds_disassemble_simple(struct pvr_simple * simple,const char * type,char * instr_str,size_t instr_len)331 static void pvr_pds_disassemble_simple(struct pvr_simple *simple,
332                                        const char *type,
333                                        char *instr_str,
334                                        size_t instr_len)
335 {
336    snprintf(instr_str, instr_len, "%-16s%s", type, simple->cc ? "? " : "");
337 }
338 
pvr_pds_disassemble_instruction_limm(struct pvr_limm * limm,char * instr_str,size_t instr_len)339 static void pvr_pds_disassemble_instruction_limm(struct pvr_limm *limm,
340                                                  char *instr_str,
341                                                  size_t instr_len)
342 {
343    int32_t imm = (uint32_t)limm->src0->literal;
344    char dst[PVR_PDS_MAX_INST_STR_LEN];
345 
346    pvr_pds_disassemble_operand(limm->dst, dst, sizeof(dst));
347 
348    if (limm->GR) {
349       char *pchGReg;
350 
351       switch (imm) {
352       case 0:
353          pchGReg = "cluster";
354          break;
355       case 1:
356          pchGReg = "instance";
357          break;
358       default:
359          pchGReg = "unknown";
360       }
361 
362       snprintf(instr_str,
363                instr_len,
364                "%-16s%s%s = G%d (%s)",
365                "LIMM",
366                limm->cc ? "? " : "",
367                dst,
368                imm,
369                pchGReg);
370    } else {
371       snprintf(instr_str,
372                instr_len,
373                "%-16s%s%s = %#04x",
374                "LIMM",
375                limm->cc ? "? " : "",
376                dst,
377                imm);
378    }
379 }
380 
pvr_pds_disassemble_instruction_ddmad(struct pvr_ddmad * ddmad,char * instr_str,size_t instr_len)381 static void pvr_pds_disassemble_instruction_ddmad(struct pvr_ddmad *ddmad,
382                                                   char *instr_str,
383                                                   size_t instr_len)
384 {
385    char src0[PVR_PDS_MAX_INST_STR_LEN];
386    char src1[PVR_PDS_MAX_INST_STR_LEN];
387    char src2[PVR_PDS_MAX_INST_STR_LEN];
388    char src3[PVR_PDS_MAX_INST_STR_LEN];
389 
390    pvr_pds_disassemble_operand(ddmad->src0, src0, sizeof(src0));
391    pvr_pds_disassemble_operand(ddmad->src1, src1, sizeof(src1));
392    pvr_pds_disassemble_operand(ddmad->src2, src2, sizeof(src2));
393    pvr_pds_disassemble_operand(ddmad->src3, src3, sizeof(src3));
394 
395    snprintf(instr_str,
396             instr_len,
397             "%-16s%sdoutd = (%s * %s) + %s, %s%s",
398             "DDMAD",
399             ddmad->cc ? "? " : "",
400             src0,
401             src1,
402             src2,
403             src3,
404             ddmad->END ? "; HALT" : "");
405 }
406 
pvr_pds_disassemble_predicate(uint32_t predicate,char * buffer,size_t buffer_length)407 static void pvr_pds_disassemble_predicate(uint32_t predicate,
408                                           char *buffer,
409                                           size_t buffer_length)
410 {
411    switch (predicate) {
412    case PVR_ROGUE_PDSINST_PREDICATE_P0:
413       snprintf(buffer, buffer_length, "%s", "p0");
414       break;
415    case PVR_ROGUE_PDSINST_PREDICATE_IF0:
416       snprintf(buffer, buffer_length, "%s", "if0");
417       break;
418    case PVR_ROGUE_PDSINST_PREDICATE_IF1:
419       snprintf(buffer, buffer_length, "%s", "if1");
420       break;
421    case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_0:
422       snprintf(buffer, buffer_length, "%s", "so_overflow_0");
423       break;
424    case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_1:
425       snprintf(buffer, buffer_length, "%s", "so_overflow_1");
426       break;
427    case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_2:
428       snprintf(buffer, buffer_length, "%s", "so_overflow_2");
429       break;
430    case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_3:
431       snprintf(buffer, buffer_length, "%s", "so_overflow_3");
432       break;
433    case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_GLOBAL:
434       snprintf(buffer, buffer_length, "%s", "so_overflow_any");
435       break;
436    case PVR_ROGUE_PDSINST_PREDICATE_KEEP:
437       snprintf(buffer, buffer_length, "%s", "keep");
438       break;
439    case PVR_ROGUE_PDSINST_PREDICATE_OOB:
440       snprintf(buffer, buffer_length, "%s", "oob");
441       break;
442    default:
443       snprintf(buffer, buffer_length, "%s", "<ERROR>");
444       break;
445    }
446 }
447 
pvr_pds_disassemble_instruction_bra(struct pvr_bra * bra,char * instr_str,size_t instr_len)448 static void pvr_pds_disassemble_instruction_bra(struct pvr_bra *bra,
449                                                 char *instr_str,
450                                                 size_t instr_len)
451 {
452    char setc_pred[32];
453    char srcc_pred[32];
454 
455    pvr_pds_disassemble_predicate(bra->srcc->predicate,
456                                  srcc_pred,
457                                  sizeof(srcc_pred));
458    pvr_pds_disassemble_predicate(bra->setc->predicate,
459                                  setc_pred,
460                                  sizeof(setc_pred));
461 
462    if (bra->setc->predicate != PVR_ROGUE_PDSINST_PREDICATE_KEEP) {
463       snprintf(instr_str,
464                instr_len,
465                "%-16sif %s%s %d ( setc = %s )",
466                "BRA",
467                bra->srcc->negate ? "! " : "",
468                srcc_pred,
469                bra->address,
470                setc_pred);
471    } else {
472       snprintf(instr_str,
473                instr_len,
474                "%-16sif %s%s %d",
475                "BRA",
476                bra->srcc->negate ? "! " : "",
477                srcc_pred,
478                bra->address);
479    }
480 }
481 
pvr_pds_disassemble_instruction_mad(struct pvr_mad * mad,char * instr_str,size_t instr_len)482 static void pvr_pds_disassemble_instruction_mad(struct pvr_mad *mad,
483                                                 char *instr_str,
484                                                 size_t instr_len)
485 {
486    char src0[PVR_PDS_MAX_INST_STR_LEN];
487    char src1[PVR_PDS_MAX_INST_STR_LEN];
488    char src2[PVR_PDS_MAX_INST_STR_LEN];
489    char dst[PVR_PDS_MAX_INST_STR_LEN];
490 
491    pvr_pds_disassemble_operand(mad->src0, src0, sizeof(src0));
492    pvr_pds_disassemble_operand(mad->src1, src1, sizeof(src1));
493    pvr_pds_disassemble_operand(mad->src2, src2, sizeof(src2));
494    pvr_pds_disassemble_operand(mad->dst, dst, sizeof(dst));
495 
496    snprintf(instr_str,
497             instr_len,
498             "%-16s%s%s = (%s * %s) %s %s%s",
499             "MAD",
500             mad->cc ? "? " : "",
501             dst,
502             src0,
503             src1,
504             mad->sna ? "-" : "+",
505             src2,
506             mad->alum ? " [signed]" : "");
507 }
508 
pvr_pds_disassemble_instruction_dout(struct pvr_dout * dout,char * instr_str,size_t instr_len)509 static void pvr_pds_disassemble_instruction_dout(struct pvr_dout *dout,
510                                                  char *instr_str,
511                                                  size_t instr_len)
512 {
513    char src0[PVR_PDS_MAX_INST_STR_LEN];
514    char src1[PVR_PDS_MAX_INST_STR_LEN];
515 
516 #define X(dout_dst, str) #str,
517    static const char *const dst[] = { PVR_PDS_DOUT_DSTS };
518 #undef X
519 
520    pvr_pds_disassemble_operand(dout->src0, src0, sizeof(src0));
521    pvr_pds_disassemble_operand(dout->src1, src1, sizeof(src1));
522 
523    {
524       snprintf(instr_str,
525                instr_len,
526                "%-16s%s%s = %s, %s%s",
527                "DOUT",
528                dout->cc ? "? " : "",
529                dst[dout->dst],
530                src0,
531                src1,
532                dout->END ? "; HALT" : "");
533    }
534 }
535 
pvr_pds_disassemble_instruction(char * instr_str,size_t instr_len,struct pvr_instruction * instruction)536 void pvr_pds_disassemble_instruction(char *instr_str,
537                                      size_t instr_len,
538                                      struct pvr_instruction *instruction)
539 {
540    if (!instruction) {
541       snprintf(instr_str,
542                instr_len,
543                "Instruction was not disassembled properly\n");
544       return;
545    }
546 
547    switch (instruction->type) {
548    case INS_LIMM:
549       pvr_pds_disassemble_instruction_limm((struct pvr_limm *)instruction,
550                                            instr_str,
551                                            instr_len);
552       break;
553    case INS_ADD64:
554       pvr_pds_disassemble_instruction_add64((struct pvr_add *)instruction,
555                                             instr_str,
556                                             instr_len);
557       break;
558    case INS_ADD32:
559       pvr_pds_disassemble_instruction_add32((struct pvr_add *)instruction,
560                                             instr_str,
561                                             instr_len);
562       break;
563    case INS_CMP:
564       pvr_pds_disassemble_instruction_cmp((struct pvr_cmp *)instruction,
565                                           instr_str,
566                                           instr_len);
567       break;
568    case INS_MAD:
569       pvr_pds_disassemble_instruction_mad((struct pvr_mad *)instruction,
570                                           instr_str,
571                                           instr_len);
572       break;
573    case INS_BRA:
574       pvr_pds_disassemble_instruction_bra((struct pvr_bra *)instruction,
575                                           instr_str,
576                                           instr_len);
577       break;
578    case INS_DDMAD:
579       pvr_pds_disassemble_instruction_ddmad((struct pvr_ddmad *)instruction,
580                                             instr_str,
581                                             instr_len);
582       break;
583    case INS_DOUT:
584       pvr_pds_disassemble_instruction_dout((struct pvr_dout *)instruction,
585                                            instr_str,
586                                            instr_len);
587       break;
588    case INS_LD:
589    case INS_ST:
590       pvr_pds_disassemble_instruction_ldst((struct pvr_ldst *)instruction,
591                                            instr_str,
592                                            instr_len);
593       break;
594    case INS_WDF:
595       pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
596                                  "WDF",
597                                  instr_str,
598                                  instr_len);
599       break;
600    case INS_LOCK:
601       pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
602                                  "LOCK",
603                                  instr_str,
604                                  instr_len);
605       break;
606    case INS_RELEASE:
607       pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
608                                  "RELEASE",
609                                  instr_str,
610                                  instr_len);
611       break;
612    case INS_HALT:
613       pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
614                                  "HALT",
615                                  instr_str,
616                                  instr_len);
617       break;
618    case INS_NOP:
619       pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
620                                  "NOP",
621                                  instr_str,
622                                  instr_len);
623       break;
624    case INS_SFTLP32:
625       pvr_pds_disassemble_instruction_sftlp32((struct pvr_sftlp *)instruction,
626                                               instr_str,
627                                               instr_len);
628       break;
629    case INS_SFTLP64:
630       pvr_pds_disassemble_instruction_sftlp64((struct pvr_sftlp *)instruction,
631                                               instr_str,
632                                               instr_len);
633       break;
634    case INS_STM:
635       pvr_pds_disassemble_instruction_stm((struct pvr_stm *)instruction,
636                                           instr_str,
637                                           instr_len);
638       break;
639    case INS_STMC:
640       pds_disassemble_instruction_stmc((struct pvr_stmc *)instruction,
641                                        instr_str,
642                                        instr_len);
643       break;
644    default:
645       snprintf(instr_str, instr_len, "Printing not implemented\n");
646       break;
647    }
648 }
649 
650 #if defined(DUMP_PDS)
pvr_pds_print_instruction(uint32_t instr)651 void pvr_pds_print_instruction(uint32_t instr)
652 {
653    char instruction_str[1024];
654    struct pvr_instruction *decoded =
655       pvr_pds_disassemble_instruction2(0, 0, instr);
656 
657    if (!decoded) {
658       mesa_logd("%X\n", instr);
659    } else {
660       pvr_pds_disassemble_instruction(instruction_str,
661                                       sizeof(instruction_str),
662                                       decoded);
663       mesa_logd("\t0x%08x, /* %s */\n", instr, instruction_str);
664    }
665 }
666 #endif
667