xref: /aosp_15_r20/external/mesa3d/src/imagination/rogue/rogue_print.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 "compiler/shader_enums.h"
25 #include "rogue.h"
26 #include "util/bitscan.h"
27 #include "util/macros.h"
28 
29 #include <inttypes.h>
30 #include <stdbool.h>
31 
32 /**
33  * \file rogue_print.c
34  *
35  * \brief Contains functions to print Rogue IR types and structures.
36  */
37 
38 /* TODO NEXT: Go through and make types the same, i.e. decide on using ONLY
39  * unsigned, uint32/64_t, etc., and then use inttypes if so */
40 /* TODO NEXT: Make fp the last argument. */
41 
42 enum color_esc {
43    ESC_RESET = 0,
44    ESC_BLACK,
45    ESC_RED,
46    ESC_GREEN,
47    ESC_YELLOW,
48    ESC_BLUE,
49    ESC_PURPLE,
50    ESC_CYAN,
51    ESC_WHITE,
52 
53    ESC_COUNT,
54 };
55 
56 static
57 const char *color_esc[2][ESC_COUNT] = {
58    [0] = {
59       [ESC_RESET] = "",
60       [ESC_BLACK] = "",
61       [ESC_RED] = "",
62       [ESC_GREEN] = "",
63       [ESC_YELLOW] = "",
64       [ESC_BLUE] = "",
65       [ESC_PURPLE] = "",
66       [ESC_CYAN] = "",
67       [ESC_WHITE] = "",
68    },
69    [1] = {
70       [ESC_RESET] = "\033[0m",
71       [ESC_BLACK] = "\033[0;30m",
72       [ESC_RED] = "\033[0;31m",
73       [ESC_GREEN] = "\033[0;32m",
74       [ESC_YELLOW] = "\033[0;33m",
75       [ESC_BLUE] = "\033[0;34m",
76       [ESC_PURPLE] = "\033[0;35m",
77       [ESC_CYAN] = "\033[0;36m",
78       [ESC_WHITE] = "\033[0;37m",
79    },
80 };
81 
RESET(FILE * fp)82 static inline void RESET(FILE *fp)
83 {
84    fputs(color_esc[rogue_color][ESC_RESET], fp);
85 }
86 
BLACK(FILE * fp)87 static inline void BLACK(FILE *fp)
88 {
89    fputs(color_esc[rogue_color][ESC_BLACK], fp);
90 }
91 
RED(FILE * fp)92 static inline void RED(FILE *fp)
93 {
94    fputs(color_esc[rogue_color][ESC_RED], fp);
95 }
96 
GREEN(FILE * fp)97 static inline void GREEN(FILE *fp)
98 {
99    fputs(color_esc[rogue_color][ESC_GREEN], fp);
100 }
101 
YELLOW(FILE * fp)102 static inline void YELLOW(FILE *fp)
103 {
104    fputs(color_esc[rogue_color][ESC_YELLOW], fp);
105 }
106 
BLUE(FILE * fp)107 static inline void BLUE(FILE *fp)
108 {
109    fputs(color_esc[rogue_color][ESC_BLUE], fp);
110 }
111 
PURPLE(FILE * fp)112 static inline void PURPLE(FILE *fp)
113 {
114    fputs(color_esc[rogue_color][ESC_PURPLE], fp);
115 }
116 
CYAN(FILE * fp)117 static inline void CYAN(FILE *fp)
118 {
119    fputs(color_esc[rogue_color][ESC_CYAN], fp);
120 }
121 
WHITE(FILE * fp)122 static inline void WHITE(FILE *fp)
123 {
124    fputs(color_esc[rogue_color][ESC_WHITE], fp);
125 }
126 
rogue_print_val(FILE * fp,unsigned val)127 static inline void rogue_print_val(FILE *fp, unsigned val)
128 {
129    PURPLE(fp);
130    fprintf(fp, "%u", val);
131    RESET(fp);
132 }
133 
rogue_print_reg(FILE * fp,const rogue_reg * reg)134 static inline void rogue_print_reg(FILE *fp, const rogue_reg *reg)
135 {
136    const rogue_reg_info *info = &rogue_reg_infos[reg->class];
137    YELLOW(fp);
138    fprintf(fp, "%s%" PRIu32, info->str, reg->index);
139    RESET(fp);
140 }
141 
rogue_print_regarray(FILE * fp,const rogue_regarray * regarray)142 static inline void rogue_print_regarray(FILE *fp,
143                                         const rogue_regarray *regarray)
144 {
145    const rogue_reg *reg = regarray->regs[0];
146    const rogue_reg_info *info = &rogue_reg_infos[reg->class];
147    YELLOW(fp);
148    fprintf(fp, "%s[%" PRIu32, info->str, reg->index);
149    if (regarray->size > 1) {
150       RESET(fp);
151       fputs("..", fp);
152       YELLOW(fp);
153       fprintf(fp, "%" PRIu32, regarray->size + reg->index - 1);
154    }
155    fputs("]", fp);
156    RESET(fp);
157 }
158 
rogue_print_imm(FILE * fp,const rogue_imm * imm)159 static inline void rogue_print_imm(FILE *fp, const rogue_imm *imm)
160 {
161    PURPLE(fp);
162    fprintf(fp, "0x%" PRIx32, imm->imm.u32);
163    RESET(fp);
164 }
165 
rogue_print_io(FILE * fp,enum rogue_io io)166 static inline void rogue_print_io(FILE *fp, enum rogue_io io)
167 {
168    const rogue_io_info *info = &rogue_io_infos[io];
169    BLUE(fp);
170    fprintf(fp, "%s", info->str);
171    RESET(fp);
172 }
173 
rogue_print_drc(FILE * fp,const rogue_drc * drc)174 static inline void rogue_print_drc(FILE *fp, const rogue_drc *drc)
175 {
176    RED(fp);
177    fprintf(fp, "drc%u", drc->index);
178    RESET(fp);
179 }
180 
rogue_print_ref(FILE * fp,const rogue_ref * ref)181 static inline void rogue_print_ref(FILE *fp, const rogue_ref *ref)
182 {
183    switch (ref->type) {
184    case ROGUE_REF_TYPE_VAL:
185       rogue_print_val(fp, ref->val);
186       break;
187 
188    case ROGUE_REF_TYPE_REG:
189       rogue_print_reg(fp, ref->reg);
190       break;
191 
192    case ROGUE_REF_TYPE_REGARRAY:
193       rogue_print_regarray(fp, ref->regarray);
194       break;
195 
196    case ROGUE_REF_TYPE_IMM:
197       rogue_print_imm(fp, &ref->imm);
198       break;
199 
200    case ROGUE_REF_TYPE_IO:
201       rogue_print_io(fp, ref->io);
202       break;
203 
204    case ROGUE_REF_TYPE_DRC:
205       rogue_print_drc(fp, &ref->drc);
206       break;
207 
208    default:
209       unreachable("Unsupported ref type.");
210    }
211 }
212 
rogue_print_alu_dst(FILE * fp,const rogue_instr_dst * dst)213 static inline void rogue_print_alu_dst(FILE *fp, const rogue_instr_dst *dst)
214 {
215    rogue_print_ref(fp, &dst->ref);
216 
217    uint64_t mod = dst->mod;
218    while (mod) {
219       enum rogue_alu_dst_mod dst_mod = u_bit_scan64(&mod);
220       assert(dst_mod < ROGUE_ALU_DST_MOD_COUNT);
221       fprintf(fp, ".%s", rogue_alu_dst_mod_infos[dst_mod].str);
222    }
223 }
224 
rogue_print_alu_src(FILE * fp,const rogue_instr_src * src)225 static inline void rogue_print_alu_src(FILE *fp, const rogue_instr_src *src)
226 {
227    rogue_print_ref(fp, &src->ref);
228 
229    uint64_t mod = src->mod;
230    while (mod) {
231       enum rogue_alu_src_mod src_mod = u_bit_scan64(&mod);
232       assert(src_mod < ROGUE_ALU_SRC_MOD_COUNT);
233       fprintf(fp, ".%s", rogue_alu_src_mod_infos[src_mod].str);
234    }
235 }
236 
rogue_print_alu_mods(FILE * fp,const rogue_alu_instr * alu)237 static inline void rogue_print_alu_mods(FILE *fp, const rogue_alu_instr *alu)
238 {
239    uint64_t mod = alu->mod;
240    while (mod) {
241       enum rogue_alu_op_mod op_mod = u_bit_scan64(&mod);
242       assert(op_mod < ROGUE_ALU_OP_MOD_COUNT);
243       fprintf(fp, ".%s", rogue_alu_op_mod_infos[op_mod].str);
244    }
245 }
246 
rogue_print_alu_instr(FILE * fp,const rogue_alu_instr * alu)247 static inline void rogue_print_alu_instr(FILE *fp, const rogue_alu_instr *alu)
248 {
249    const rogue_alu_op_info *info = &rogue_alu_op_infos[alu->op];
250 
251    /* TODO: Print conditional info once supported. */
252 
253    fprintf(fp, "%s", info->str);
254 
255    rogue_print_alu_mods(fp, alu);
256 
257    for (unsigned i = 0; i < info->num_dsts; ++i) {
258       if (i > 0)
259          fputs(",", fp);
260 
261       fputs(" ", fp);
262 
263       rogue_print_alu_dst(fp, &alu->dst[i]);
264    }
265 
266    for (unsigned i = 0; i < info->num_srcs; ++i) {
267       if (i == 0 && !info->num_dsts)
268          fputs(" ", fp);
269       else
270          fputs(", ", fp);
271 
272       rogue_print_alu_src(fp, &alu->src[i]);
273    }
274 }
275 
rogue_print_block_label(FILE * fp,const rogue_block * block)276 static inline void rogue_print_block_label(FILE *fp, const rogue_block *block)
277 {
278    /* For debug purposes. */
279    if (block->label)
280       fprintf(fp, "%s", block->label);
281    else
282       fprintf(fp, "block%u", block->index);
283 }
284 
rogue_print_backend_dst(FILE * fp,const rogue_instr_dst * dst)285 static inline void rogue_print_backend_dst(FILE *fp, const rogue_instr_dst *dst)
286 {
287    rogue_print_ref(fp, &dst->ref);
288 }
289 
rogue_print_backend_src(FILE * fp,const rogue_instr_src * src)290 static inline void rogue_print_backend_src(FILE *fp, const rogue_instr_src *src)
291 {
292    rogue_print_ref(fp, &src->ref);
293 }
294 
rogue_print_backend_mods(FILE * fp,const rogue_backend_instr * backend)295 static inline void rogue_print_backend_mods(FILE *fp,
296                                             const rogue_backend_instr *backend)
297 {
298    uint64_t mod = backend->mod;
299    while (mod) {
300       enum rogue_backend_op_mod op_mod = u_bit_scan64(&mod);
301       assert(op_mod < ROGUE_BACKEND_OP_MOD_COUNT);
302       fprintf(fp, ".%s", rogue_backend_op_mod_infos[op_mod].str);
303    }
304 }
305 
rogue_print_backend_instr(FILE * fp,const rogue_backend_instr * backend)306 static inline void rogue_print_backend_instr(FILE *fp,
307                                              const rogue_backend_instr *backend)
308 {
309    const rogue_backend_op_info *info = &rogue_backend_op_infos[backend->op];
310 
311    fprintf(fp, "%s", info->str);
312 
313    rogue_print_backend_mods(fp, backend);
314 
315    for (unsigned i = 0; i < info->num_dsts; ++i) {
316       if (i > 0)
317          fputs(",", fp);
318 
319       fputs(" ", fp);
320 
321       rogue_print_backend_dst(fp, &backend->dst[i]);
322    }
323 
324    for (unsigned i = 0; i < info->num_srcs; ++i) {
325       if (i == 0 && !info->num_dsts)
326          fputs(" ", fp);
327       else
328          fputs(", ", fp);
329 
330       rogue_print_backend_src(fp, &backend->src[i]);
331    }
332 }
333 
rogue_print_ctrl_mods(FILE * fp,const rogue_ctrl_instr * ctrl)334 static inline void rogue_print_ctrl_mods(FILE *fp, const rogue_ctrl_instr *ctrl)
335 {
336    uint64_t mod = ctrl->mod;
337    while (mod) {
338       enum rogue_ctrl_op_mod op_mod = u_bit_scan64(&mod);
339       assert(op_mod < ROGUE_CTRL_OP_MOD_COUNT);
340       fprintf(fp, ".%s", rogue_ctrl_op_mod_infos[op_mod].str);
341    }
342 }
343 
rogue_print_ctrl_src(FILE * fp,const rogue_instr_src * src)344 static inline void rogue_print_ctrl_src(FILE *fp, const rogue_instr_src *src)
345 {
346    rogue_print_ref(fp, &src->ref);
347 }
348 
rogue_print_ctrl_instr(FILE * fp,const rogue_ctrl_instr * ctrl)349 static inline void rogue_print_ctrl_instr(FILE *fp,
350                                           const rogue_ctrl_instr *ctrl)
351 {
352    const rogue_ctrl_op_info *info = &rogue_ctrl_op_infos[ctrl->op];
353 
354    /* TODO: Print conditional info once supported. */
355 
356    fprintf(fp, "%s", info->str);
357 
358    rogue_print_ctrl_mods(fp, ctrl);
359 
360    if (ctrl->target_block) {
361       fputs(" ", fp);
362       rogue_print_block_label(fp, ctrl->target_block);
363    }
364 
365    /* TODO NEXT: Dests. */
366    /* TODO: Special case for the conditional ctrl instructions as they're
367     * printed as source 0, then dest, then rest of the sources. */
368 
369    for (unsigned i = 0; i < info->num_srcs; ++i) {
370       if (i == 0 && !info->num_dsts)
371          fputs(" ", fp);
372       else
373          fputs(", ", fp);
374 
375       rogue_print_ctrl_src(fp, &ctrl->src[i]);
376    }
377 }
378 
rogue_print_bitwise_dst(FILE * fp,const rogue_instr_dst * dst)379 static inline void rogue_print_bitwise_dst(FILE *fp, const rogue_instr_dst *dst)
380 {
381    rogue_print_ref(fp, &dst->ref);
382 }
383 
rogue_print_bitwise_src(FILE * fp,const rogue_instr_src * src)384 static inline void rogue_print_bitwise_src(FILE *fp, const rogue_instr_src *src)
385 {
386    rogue_print_ref(fp, &src->ref);
387 }
388 
rogue_print_bitwise_instr(FILE * fp,const rogue_bitwise_instr * bitwise)389 static inline void rogue_print_bitwise_instr(FILE *fp,
390                                              const rogue_bitwise_instr *bitwise)
391 {
392    const rogue_bitwise_op_info *info = &rogue_bitwise_op_infos[bitwise->op];
393 
394    fprintf(fp, "%s", info->str);
395 
396    /* rogue_print_bitwise_mods(fp, bitwise); */
397 
398    for (unsigned i = 0; i < info->num_dsts; ++i) {
399       if (i > 0)
400          fputs(",", fp);
401 
402       fputs(" ", fp);
403 
404       rogue_print_bitwise_dst(fp, &bitwise->dst[i]);
405    }
406 
407    for (unsigned i = 0; i < info->num_srcs; ++i) {
408       if (i == 0 && !info->num_dsts)
409          fputs(" ", fp);
410       else
411          fputs(", ", fp);
412 
413       rogue_print_bitwise_src(fp, &bitwise->src[i]);
414    }
415 }
416 
417 PUBLIC
rogue_print_instr(FILE * fp,const rogue_instr * instr)418 void rogue_print_instr(FILE *fp, const rogue_instr *instr)
419 {
420    if (instr->exec_cond > ROGUE_EXEC_COND_PE_TRUE)
421       fprintf(fp, "%s ", rogue_exec_cond_str[instr->exec_cond]);
422 
423    if (instr->repeat > 1)
424       fprintf(fp, "(rpt%u) ", instr->repeat);
425 
426    GREEN(fp);
427    switch (instr->type) {
428    case ROGUE_INSTR_TYPE_ALU:
429       rogue_print_alu_instr(fp, rogue_instr_as_alu(instr));
430       break;
431 
432    case ROGUE_INSTR_TYPE_BACKEND:
433       rogue_print_backend_instr(fp, rogue_instr_as_backend(instr));
434       break;
435 
436    case ROGUE_INSTR_TYPE_CTRL:
437       rogue_print_ctrl_instr(fp, rogue_instr_as_ctrl(instr));
438       break;
439 
440    case ROGUE_INSTR_TYPE_BITWISE:
441       rogue_print_bitwise_instr(fp, rogue_instr_as_bitwise(instr));
442       break;
443 
444    default:
445       unreachable("Unsupported instruction type.");
446    }
447    RESET(fp);
448 
449    if (instr->end)
450       fputs(" {end}", fp);
451 
452    /* For debug purposes. */
453    fputs(";", fp);
454 
455    if (instr->comment)
456       fprintf(fp, " /* %s */", instr->comment);
457 }
458 
459 /* TODO NEXT: Split this up into separate functions for printing lower srcs,
460  * upper srcs, etc. since we'd want to print them in-between instructions. */
461 /* TODO NEXT: Commonise with printing the ref io stuff. */
462 static inline void
rogue_print_instr_group_io_sel(FILE * fp,const rogue_instr_group_io_sel * io_sel)463 rogue_print_instr_group_io_sel(FILE *fp, const rogue_instr_group_io_sel *io_sel)
464 {
465    bool present = false;
466 
467    fputs(" ", fp);
468 
469    /* TODO NEXT: Commonise this code!! */
470    /* Print upper and lower sources. */
471    for (unsigned i = 0; i < ARRAY_SIZE(io_sel->srcs); ++i) {
472       if (rogue_ref_is_null(&io_sel->srcs[i]))
473          continue;
474 
475       if (present && i > 0)
476          fputs(", ", fp);
477 
478       present = true;
479 
480       rogue_print_io(fp, ROGUE_IO_S0 + i);
481       fputs("=", fp);
482 
483       if (rogue_ref_is_reg(&io_sel->srcs[i]))
484          rogue_print_reg(fp, io_sel->srcs[i].reg);
485       else if (rogue_ref_is_regarray(&io_sel->srcs[i]))
486          rogue_print_regarray(fp, io_sel->srcs[i].regarray);
487       else if (rogue_ref_is_io(&io_sel->srcs[i]))
488          rogue_print_io(fp, io_sel->srcs[i].io);
489       else
490          unreachable("Unsupported src map.");
491    }
492    if (present)
493       fputs(" ", fp);
494 
495    /* Print internal sources. */
496    present = false;
497    for (unsigned i = 0; i < ARRAY_SIZE(io_sel->iss); ++i) {
498       if (rogue_ref_is_null(&io_sel->iss[i]))
499          continue;
500 
501       if (present && i > 0)
502          fputs(", ", fp);
503 
504       present = true;
505 
506       rogue_print_io(fp, ROGUE_IO_IS0 + i);
507       fputs("=", fp);
508 
509       if (rogue_ref_is_reg(&io_sel->iss[i]))
510          rogue_print_reg(fp, io_sel->iss[i].reg);
511       else if (rogue_ref_is_regarray(&io_sel->iss[i]))
512          rogue_print_regarray(fp, io_sel->iss[i].regarray);
513       else if (rogue_ref_is_io(&io_sel->iss[i]))
514          rogue_print_io(fp, io_sel->iss[i].io);
515       else
516          unreachable("Unsupported iss map.");
517    }
518    if (present)
519       fputs(" ", fp);
520 
521    /* Print destinations. */
522    present = false;
523    for (unsigned i = 0; i < ARRAY_SIZE(io_sel->dsts); ++i) {
524       if (rogue_ref_is_null(&io_sel->dsts[i]))
525          continue;
526 
527       if (present && i > 0)
528          fputs(", ", fp);
529 
530       present = true;
531 
532       rogue_print_io(fp, ROGUE_IO_W0 + i);
533       fputs("=", fp);
534 
535       if (rogue_ref_is_reg(&io_sel->dsts[i]))
536          rogue_print_reg(fp, io_sel->dsts[i].reg);
537       else if (rogue_ref_is_regarray(&io_sel->dsts[i]))
538          rogue_print_regarray(fp, io_sel->dsts[i].regarray);
539       else if (rogue_ref_is_io(&io_sel->dsts[i]))
540          rogue_print_io(fp, io_sel->dsts[i].io);
541       else
542          unreachable("Unsupported dst map.");
543    }
544    if (present)
545       fputs(" ", fp);
546 }
547 
rogue_print_instr_phase(FILE * fp,enum rogue_alu alu,enum rogue_instr_phase phase)548 static inline void rogue_print_instr_phase(FILE *fp,
549                                            enum rogue_alu alu,
550                                            enum rogue_instr_phase phase)
551 {
552    const char *phase_str = rogue_instr_phase_str[alu][phase];
553    assert(phase_str);
554    fputs(phase_str, fp);
555 }
556 
557 static inline void
rogue_print_instr_group_header(FILE * fp,const rogue_instr_group * group)558 rogue_print_instr_group_header(FILE *fp, const rogue_instr_group *group)
559 {
560    /* ALU specific */
561    switch (group->header.alu) {
562    case ROGUE_ALU_MAIN:
563       break;
564 
565    case ROGUE_ALU_BITWISE:
566       break;
567 
568    case ROGUE_ALU_CONTROL:
569       break;
570 
571    default:
572       unreachable("Unsupported instruction group ALU.");
573    }
574 
575    if (group->header.end)
576       fputs(".end", fp);
577 }
578 
rogue_print_instr_group(FILE * fp,const rogue_instr_group * group)579 static inline void rogue_print_instr_group(FILE *fp,
580                                            const rogue_instr_group *group)
581 {
582    /* For debug purposes. */
583    fprintf(fp, "%u", group->index);
584    fputs(": ", fp);
585 
586    if (group->header.exec_cond > ROGUE_EXEC_COND_PE_TRUE)
587       fprintf(fp, "%s ", rogue_exec_cond_str[group->header.exec_cond]);
588 
589    if (group->header.repeat > 1)
590       fprintf(fp, "(rpt%u) ", group->header.repeat);
591 
592    fputs("{ ", fp);
593 
594    CYAN(fp);
595    fprintf(fp, "%s", rogue_alu_str[group->header.alu]);
596    RESET(fp);
597 
598    /* Print each instruction. */
599    rogue_foreach_phase_in_set (p, group->header.phases) {
600       const rogue_instr *instr = group->instrs[p];
601       assert(instr);
602 
603       fputs(" ", fp);
604       rogue_print_instr_phase(fp, group->header.alu, p);
605       fputs(": ", fp);
606       rogue_print_instr(fp, instr);
607    }
608 
609    /* Print source/dest mappings (if present). */
610    rogue_print_instr_group_io_sel(fp, &group->io_sel);
611 
612    fputs("}", fp);
613 
614    /* Print group header info. */
615    rogue_print_instr_group_header(fp, group);
616 }
617 
rogue_print_block(FILE * fp,const rogue_block * block)618 static inline void rogue_print_block(FILE *fp, const rogue_block *block)
619 {
620    rogue_print_block_label(fp, block);
621    fputs(":\n", fp);
622 
623    if (!block->shader->is_grouped) {
624       rogue_foreach_instr_in_block (instr, block) {
625          fputs("\t", fp);
626          fprintf(fp, "%u", instr->index);
627          fputs(": ", fp);
628          fprintf(fp, "%s: ", rogue_instr_type_str[instr->type]);
629          rogue_print_instr(fp, instr);
630          fputs("\n", fp);
631       }
632    } else {
633       rogue_foreach_instr_group_in_block (group, block) {
634          fputs("\t", fp);
635          rogue_print_instr_group(fp, group);
636          fputs("\n", fp);
637       }
638    }
639 }
640 
641 PUBLIC
rogue_print_shader(FILE * fp,const rogue_shader * shader)642 void rogue_print_shader(FILE *fp, const rogue_shader *shader)
643 {
644    fputs("/*", fp);
645 
646    if (shader->stage == MESA_SHADER_NONE)
647       fputs(" USC program", fp);
648    else
649       fprintf(fp, " %s shader", _mesa_shader_stage_to_string(shader->stage));
650 
651    if (shader->name)
652       fprintf(fp, " - %s", shader->name);
653 
654    fputs(" */\n", fp);
655 
656    rogue_foreach_block (block, shader)
657       rogue_print_block(fp, block);
658 }
659 
rogue_print_instr_ref(FILE * fp,const rogue_instr * instr,bool dst,unsigned index,bool is_grouped)660 static void rogue_print_instr_ref(FILE *fp,
661                                   const rogue_instr *instr,
662                                   bool dst,
663                                   unsigned index,
664                                   bool is_grouped)
665 {
666    if (is_grouped) {
667       fprintf(fp, "%u", instr->group->index);
668       fputs(": { ", fp);
669       rogue_print_instr_phase(fp, instr->group->header.alu, instr->index);
670    } else {
671       fprintf(fp, "%u", instr->index);
672       if (index != ~0)
673          fputs(": ", fp);
674    }
675 
676    if (index != ~0) {
677       BLUE(fp);
678       fprintf(fp, "[%s%u]", dst ? "dst" : "src", index);
679       RESET(fp);
680    }
681 
682    if (is_grouped)
683       fputs(" }", fp);
684 }
685 
686 PUBLIC
rogue_print_reg_writes(FILE * fp,const rogue_shader * shader)687 void rogue_print_reg_writes(FILE *fp, const rogue_shader *shader)
688 {
689    fputs("/* register writes */\n", fp);
690    for (enum rogue_reg_class class = 0; class < ROGUE_REG_CLASS_COUNT;
691         ++class) {
692       rogue_foreach_reg (reg, shader, class) {
693          bool unused = true;
694 
695          rogue_print_reg(fp, reg);
696          fputs(":", fp);
697 
698          rogue_foreach_reg_write (write, reg) {
699             assert(write->instr);
700             unused = false;
701 
702             fputs(" ", fp);
703             rogue_print_instr_ref(fp,
704                                   write->instr,
705                                   true,
706                                   write->dst_index,
707                                   shader->is_grouped);
708          }
709 
710          if (reg->regarray) {
711             rogue_foreach_regarray_write (write, reg->regarray) {
712                assert(write->instr);
713                unused = false;
714 
715                fputs(" ", fp);
716                rogue_print_instr_ref(fp,
717                                      write->instr,
718                                      false,
719                                      write->dst_index,
720                                      shader->is_grouped);
721             }
722 
723             rogue_foreach_subarray (subarray, reg->regarray) {
724                unsigned subarray_start = subarray->regs[0]->index;
725                unsigned subarray_end = subarray_start + subarray->size - 1;
726                if (reg->index < subarray_start || reg->index > subarray_end)
727                   continue;
728 
729                rogue_foreach_regarray_write (write, subarray) {
730                   assert(write->instr);
731                   unused = false;
732 
733                   fputs(" ", fp);
734                   rogue_print_instr_ref(fp,
735                                         write->instr,
736                                         false,
737                                         write->dst_index,
738                                         shader->is_grouped);
739                }
740             }
741          }
742 
743          if (unused) {
744             fputs(" <none>\n", fp);
745             continue;
746          }
747 
748          fputs("\n", fp);
749       }
750    }
751 }
752 
753 PUBLIC
rogue_print_reg_uses(FILE * fp,const rogue_shader * shader)754 void rogue_print_reg_uses(FILE *fp, const rogue_shader *shader)
755 {
756    fputs("/* register uses */\n", fp);
757    for (enum rogue_reg_class class = 0; class < ROGUE_REG_CLASS_COUNT;
758         ++class) {
759       rogue_foreach_reg (reg, shader, class) {
760          bool unused = true;
761 
762          rogue_print_reg(fp, reg);
763          fputs(":", fp);
764 
765          rogue_foreach_reg_use (use, reg) {
766             assert(use->instr);
767             unused = false;
768 
769             fputs(" ", fp);
770             rogue_print_instr_ref(fp,
771                                   use->instr,
772                                   false,
773                                   use->src_index,
774                                   shader->is_grouped);
775          }
776 
777          if (reg->regarray) {
778             rogue_foreach_regarray_use (use, reg->regarray) {
779                assert(use->instr);
780                unused = false;
781 
782                fputs(" ", fp);
783                rogue_print_instr_ref(fp,
784                                      use->instr,
785                                      false,
786                                      use->src_index,
787                                      shader->is_grouped);
788             }
789 
790             rogue_foreach_subarray (subarray, reg->regarray) {
791                unsigned subarray_start = subarray->regs[0]->index;
792                unsigned subarray_end = subarray_start + subarray->size - 1;
793                if (reg->index < subarray_start || reg->index > subarray_end)
794                   continue;
795 
796                rogue_foreach_regarray_use (use, subarray) {
797                   assert(use->instr);
798                   unused = false;
799 
800                   fputs(" ", fp);
801                   rogue_print_instr_ref(fp,
802                                         use->instr,
803                                         false,
804                                         use->src_index,
805                                         shader->is_grouped);
806                }
807             }
808          }
809 
810          if (unused) {
811             fputs(" <none>\n", fp);
812             continue;
813          }
814 
815          fputs("\n", fp);
816       }
817    }
818 }
819 
820 PUBLIC
rogue_print_block_uses(FILE * fp,const rogue_shader * shader)821 void rogue_print_block_uses(FILE *fp, const rogue_shader *shader)
822 {
823    fputs("/* block uses */\n", fp);
824    rogue_foreach_block (block, shader) {
825       rogue_print_block_label(fp, block);
826       fputs(":", fp);
827 
828       if (list_is_empty(&block->uses)) {
829          if (list_first_entry(&shader->blocks, rogue_block, link) == block)
830             fputs(" <entry>\n", fp);
831          else
832             fputs(" <none>\n", fp);
833 
834          continue;
835       }
836 
837       rogue_foreach_block_use (use, block) {
838          assert(use->instr);
839 
840          fputs(" ", fp);
841          rogue_print_instr_ref(fp, use->instr, false, ~0, shader->is_grouped);
842       }
843 
844       fputs("\n", fp);
845    }
846 }
847 
rogue_print_drc_trxn(FILE * fp,const rogue_shader * shader,const rogue_drc_trxn * drc_trxn,unsigned index)848 static void rogue_print_drc_trxn(FILE *fp,
849                                  const rogue_shader *shader,
850                                  const rogue_drc_trxn *drc_trxn,
851                                  unsigned index)
852 {
853    fprintf(fp, "drc%u: ack: ", index);
854 
855    rogue_print_instr_ref(fp, drc_trxn->acquire, false, ~0, shader->is_grouped);
856 
857    fputs(", rel: ", fp);
858 
859    if (drc_trxn->release) {
860       rogue_print_instr_ref(fp,
861                             drc_trxn->release,
862                             false,
863                             ~0,
864                             shader->is_grouped);
865    } else {
866       fputs("<none>", fp);
867    }
868 
869    fputs("\n", fp);
870 }
871 
872 PUBLIC
rogue_print_drc_trxns(FILE * fp,const rogue_shader * shader)873 void rogue_print_drc_trxns(FILE *fp, const rogue_shader *shader)
874 {
875    fputs("/* DRC transactions */\n", fp);
876 
877    rogue_foreach_drc_trxn (drc_trxn, shader, 0) {
878       rogue_print_drc_trxn(fp, shader, drc_trxn, 0);
879    }
880 
881    rogue_foreach_drc_trxn (drc_trxn, shader, 1) {
882       rogue_print_drc_trxn(fp, shader, drc_trxn, 1);
883    }
884 }
885