xref: /aosp_15_r20/external/mesa3d/src/nouveau/codegen/nv50_ir_print.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2011 Christoph Bumiller
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "nv50_ir.h"
24 #include "nv50_ir_target.h"
25 #include "nv50_ir_driver.h"
26 
27 #include <inttypes.h>
28 
29 namespace nv50_ir {
30 
31 enum TextStyle
32 {
33    TXT_DEFAULT,
34    TXT_GPR,
35    TXT_REGISTER,
36    TXT_FLAGS,
37    TXT_MEM,
38    TXT_IMMD,
39    TXT_BRA,
40    TXT_INSN
41 };
42 
43 static const char *_colour[8] =
44 {
45    "\x1b[00m",
46    "\x1b[34m",
47    "\x1b[35m",
48    "\x1b[35m",
49    "\x1b[36m",
50    "\x1b[33m",
51    "\x1b[37m",
52    "\x1b[32m"
53 };
54 
55 static const char *_nocolour[8] =
56 {
57       "", "", "", "", "", "", "", ""
58 };
59 
60 static const char **colour;
61 
init_colours()62 static void init_colours()
63 {
64    if (getenv("NV50_PROG_DEBUG_NO_COLORS") != NULL)
65       colour = _nocolour;
66    else
67       colour = _colour;
68 }
69 
70 const char *operationStr[OP_LAST + 1] =
71 {
72    "nop",
73    "phi",
74    "union",
75    "split",
76    "merge",
77    "mov",
78    "ld",
79    "st",
80    "add",
81    "sub",
82    "mul",
83    "div",
84    "mod",
85    "mad",
86    "fma",
87    "sad",
88    "shladd",
89    "xmad",
90    "abs",
91    "neg",
92    "not",
93    "and",
94    "or",
95    "xor",
96    "lop3 lut",
97    "shl",
98    "shr",
99    "shf",
100    "max",
101    "min",
102    "sat",
103    "ceil",
104    "floor",
105    "trunc",
106    "cvt",
107    "set and",
108    "set or",
109    "set xor",
110    "set",
111    "selp",
112    "slct",
113    "rcp",
114    "rsq",
115    "lg2",
116    "sin",
117    "cos",
118    "ex2",
119    "presin",
120    "preex2",
121    "sqrt",
122    "bra",
123    "call",
124    "ret",
125    "cont",
126    "break",
127    "preret",
128    "precont",
129    "prebreak",
130    "brkpt",
131    "joinat",
132    "join",
133    "discard",
134    "exit",
135    "membar",
136    "vfetch",
137    "pfetch",
138    "afetch",
139    "export",
140    "linterp",
141    "pinterp",
142    "emit",
143    "restart",
144    "final",
145    "tex",
146    "texbias",
147    "texlod",
148    "texfetch",
149    "texquery",
150    "texgrad",
151    "texgather",
152    "texquerylod",
153    "texcsaa",
154    "texprep",
155    "suldb",
156    "suldp",
157    "sustb",
158    "sustp",
159    "suredb",
160    "suredp",
161    "sulea",
162    "subfm",
163    "suclamp",
164    "sueau",
165    "suq",
166    "madsp",
167    "texbar",
168    "dfdx",
169    "dfdy",
170    "rdsv",
171    "pixld",
172    "quadop",
173    "quadon",
174    "quadpop",
175    "popcnt",
176    "insbf",
177    "extbf",
178    "bfind",
179    "brev",
180    "bmsk",
181    "permt",
182    "sgxt",
183    "atom",
184    "bar",
185    "vadd",
186    "vavg",
187    "vmin",
188    "vmax",
189    "vsad",
190    "vset",
191    "vshr",
192    "vshl",
193    "vsel",
194    "cctl",
195    "shfl",
196    "vote",
197    "bufq",
198    "warpsync",
199    "(invalid)"
200 };
201 
202 static const char *atomSubOpStr[] =
203 {
204    "add", "min", "max", "inc", "dec", "and", "or", "xor", "cas", "exch"
205 };
206 
207 static const char *ldstSubOpStr[] =
208 {
209    "", "lock", "unlock"
210 };
211 
212 static const char *subfmOpStr[] =
213 {
214    "", "3d"
215 };
216 
217 static const char *shflOpStr[] =
218 {
219   "idx", "up", "down", "bfly"
220 };
221 
222 static const char *pixldOpStr[] =
223 {
224    "count", "covmask", "covered", "offset", "cent_offset", "sampleid"
225 };
226 
227 static const char *rcprsqOpStr[] =
228 {
229    "", "64h"
230 };
231 
232 static const char *emitOpStr[] =
233 {
234    "", "restart"
235 };
236 
237 static const char *cctlOpStr[] =
238 {
239    "", "", "", "", "", "iv", "ivall"
240 };
241 
242 static const char *barOpStr[] =
243 {
244    "sync", "arrive", "red and", "red or", "red popc"
245 };
246 
247 static const char *xmadOpCModeStr[] =
248 {
249    "clo", "chi", "csfu", "cbcc"
250 };
251 
252 static const char *DataTypeStr[] =
253 {
254    "-",
255    "u8", "s8",
256    "u16", "s16",
257    "u32", "s32",
258    "u64", "s64",
259    "f16", "f32", "f64",
260    "b96", "b128"
261 };
262 
263 static const char *RoundModeStr[] =
264 {
265    "", "rm", "rz", "rp", "rni", "rmi", "rzi", "rpi"
266 };
267 
268 static const char *CondCodeStr[] =
269 {
270    "never",
271    "lt",
272    "eq",
273    "le",
274    "gt",
275    "ne",
276    "ge",
277    "",
278    "(invalid)",
279    "ltu",
280    "equ",
281    "leu",
282    "gtu",
283    "neu",
284    "geu",
285    "",
286    "no",
287    "nc",
288    "ns",
289    "na",
290    "a",
291    "s",
292    "c",
293    "o"
294 };
295 
296 static const char *SemanticStr[] =
297 {
298    "POSITION",
299    "VERTEX_ID",
300    "INSTANCE_ID",
301    "INVOCATION_ID",
302    "PRIMITIVE_ID",
303    "VERTEX_COUNT",
304    "LAYER",
305    "VIEWPORT_INDEX",
306    "VIEWPORT_MASK",
307    "Y_DIR",
308    "FACE",
309    "POINT_SIZE",
310    "POINT_COORD",
311    "CLIP_DISTANCE",
312    "SAMPLE_INDEX",
313    "SAMPLE_POS",
314    "SAMPLE_MASK",
315    "TESS_OUTER",
316    "TESS_INNER",
317    "TESS_COORD",
318    "TID",
319    "COMBINED_TID",
320    "CTAID",
321    "NTID",
322    "GRIDID",
323    "NCTAID",
324    "LANEID",
325    "PHYSID",
326    "NPHYSID",
327    "CLOCK",
328    "LBASE",
329    "SBASE",
330    "VERTEX_STRIDE",
331    "INVOCATION_INFO",
332    "THREAD_KILL",
333    "BASEVERTEX",
334    "BASEINSTANCE",
335    "DRAWID",
336    "WORK_DIM",
337    "LANEMASK_EQ",
338    "LANEMASK_LT",
339    "LANEMASK_LE",
340    "LANEMASK_GT",
341    "LANEMASK_GE",
342    "?",
343    "(INVALID)"
344 };
345 
346 static const char *TSStr[17] =
347 {
348    "THREAD_STATE_ENUM0",
349    "THREAD_STATE_ENUM1",
350    "THREAD_STATE_ENUM2",
351    "THREAD_STATE_ENUM3",
352    "THREAD_STATE_ENUM4",
353    "TRAP_RETURN_PC_LO",
354    "TRAP_RETURN_PC_HI",
355    "TRAP_RETURN_MASK",
356    "MEXITED",
357    "MKILL",
358    "MACTIVE",
359    "MATEXIT",
360    "OPT_STACK",
361    "API_CALL_DEPTH",
362    "ATEXIT_PC_LO",
363    "ATEXIT_PC_HI",
364    "PQUAD_MACTIVE",
365 };
366 
367 static const char *interpStr[16] =
368 {
369    "pass",
370    "mul",
371    "flat",
372    "sc",
373    "cent pass",
374    "cent mul",
375    "cent flat",
376    "cent sc",
377    "off pass",
378    "off mul",
379    "off flat",
380    "off sc",
381    "samp pass",
382    "samp mul",
383    "samp flat",
384    "samp sc"
385 };
386 
387 static const char *texMaskStr[16] =
388 {
389    "____",
390    "r___",
391    "_g__",
392    "rg__",
393    "__b_",
394    "r_b_",
395    "_gb_",
396    "rgb_",
397    "___a",
398    "r__a",
399    "_g_a",
400    "rg_a",
401    "__ba",
402    "r_ba",
403    "_gba",
404    "rgba",
405 };
406 
407 static const char *gatherCompStr[4] =
408 {
409    "r", "g", "b", "a",
410 };
411 
412 #define PRINT(args...)                                \
413    do {                                               \
414       pos += snprintf(&buf[pos], size - pos, args);   \
415    } while(0)
416 
417 #define SPACE_PRINT(cond, args...)                      \
418    do {                                                 \
419       if (cond)                                         \
420          buf[pos++] = ' ';                              \
421       pos += snprintf(&buf[pos], size - pos, args);     \
422    } while(0)
423 
424 #define SPACE()                                    \
425    do {                                            \
426       if (pos < size)                              \
427          buf[pos++] = ' ';                         \
428    } while(0)
429 
print(char * buf,size_t size) const430 int Modifier::print(char *buf, size_t size) const
431 {
432    size_t pos = 0;
433 
434    if (bits)
435       PRINT("%s", colour[TXT_INSN]);
436 
437    size_t base = pos;
438 
439    if (bits & NV50_IR_MOD_NOT)
440       PRINT("not");
441    if (bits & NV50_IR_MOD_SAT)
442       SPACE_PRINT(pos > base && pos < size, "sat");
443    if (bits & NV50_IR_MOD_NEG)
444       SPACE_PRINT(pos > base && pos < size, "neg");
445    if (bits & NV50_IR_MOD_ABS)
446       SPACE_PRINT(pos > base && pos < size, "abs");
447 
448    return pos;
449 }
450 
print(char * buf,size_t size,DataType ty) const451 int LValue::print(char *buf, size_t size, DataType ty) const
452 {
453    const char *postFix = "";
454    size_t pos = 0;
455    int idx = join->reg.data.id >= 0 ? join->reg.data.id : id;
456    char p = join->reg.data.id >= 0 ? '$' : '%';
457    char r;
458    int col = TXT_DEFAULT;
459 
460    switch (reg.file) {
461    case FILE_GPR:
462       r = 'r'; col = TXT_GPR;
463       if (reg.size == 2) {
464          if (p == '$') {
465             postFix = (idx & 1) ? "h" : "l";
466             idx /= 2;
467          } else {
468             postFix = "s";
469          }
470       } else
471       if (reg.size == 8) {
472          postFix = "d";
473       } else
474       if (reg.size == 16) {
475          postFix = "q";
476       } else
477       if (reg.size == 12) {
478          postFix = "t";
479       }
480       break;
481    case FILE_PREDICATE:
482       r = 'p'; col = TXT_REGISTER;
483       if (reg.size == 2)
484          postFix = "d";
485       else
486       if (reg.size == 4)
487          postFix = "q";
488       break;
489    case FILE_FLAGS:
490       r = 'c'; col = TXT_FLAGS;
491       break;
492    case FILE_ADDRESS:
493       r = 'a'; col = TXT_REGISTER;
494       break;
495    case FILE_BARRIER:
496       r = 'b'; col = TXT_REGISTER;
497       break;
498    default:
499       assert(!"invalid file for lvalue");
500       r = '?';
501       break;
502    }
503 
504    PRINT("%s%c%c%i%s", colour[col], p, r, idx, postFix);
505 
506    return pos;
507 }
508 
print(char * buf,size_t size,DataType ty) const509 int ImmediateValue::print(char *buf, size_t size, DataType ty) const
510 {
511    size_t pos = 0;
512 
513    PRINT("%s", colour[TXT_IMMD]);
514 
515    switch (ty) {
516    case TYPE_F32: PRINT("%f", reg.data.f32); break;
517    case TYPE_F64: PRINT("%f", reg.data.f64); break;
518    case TYPE_U8:  PRINT("0x%02x", reg.data.u8); break;
519    case TYPE_S8:  PRINT("%i", reg.data.s8); break;
520    case TYPE_U16: PRINT("0x%04x", reg.data.u16); break;
521    case TYPE_S16: PRINT("%i", reg.data.s16); break;
522    case TYPE_U32: PRINT("0x%08x", reg.data.u32); break;
523    case TYPE_S32: PRINT("%i", reg.data.s32); break;
524    case TYPE_U64:
525    case TYPE_S64:
526    default:
527       PRINT("0x%016" PRIx64, reg.data.u64);
528       break;
529    }
530    return pos;
531 }
532 
print(char * buf,size_t size,DataType ty) const533 int Symbol::print(char *buf, size_t size, DataType ty) const
534 {
535    return print(buf, size, NULL, NULL, ty);
536 }
537 
print(char * buf,size_t size,Value * rel,Value * dimRel,DataType ty) const538 int Symbol::print(char *buf, size_t size,
539                   Value *rel, Value *dimRel, DataType ty) const
540 {
541    STATIC_ASSERT(ARRAY_SIZE(SemanticStr) == SV_LAST + 1);
542 
543    size_t pos = 0;
544    char c;
545 
546    if (ty == TYPE_NONE)
547       ty = typeOfSize(reg.size);
548 
549    if (reg.file == FILE_SYSTEM_VALUE) {
550       PRINT("%ssv[%s%s:%i%s", colour[TXT_MEM],
551             colour[TXT_REGISTER],
552             SemanticStr[reg.data.sv.sv], reg.data.sv.index, colour[TXT_MEM]);
553       if (rel) {
554          PRINT("%s+", colour[TXT_DEFAULT]);
555          pos += rel->print(&buf[pos], size - pos);
556       }
557       PRINT("%s]", colour[TXT_MEM]);
558       return pos;
559    } else if (reg.file == FILE_THREAD_STATE) {
560       PRINT("%sts[%s%s%s]", colour[TXT_MEM], colour[TXT_REGISTER],
561             TSStr[reg.data.ts], colour[TXT_MEM]);
562       return pos;
563    }
564 
565    switch (reg.file) {
566    case FILE_MEMORY_CONST:  c = 'c'; break;
567    case FILE_SHADER_INPUT:  c = 'a'; break;
568    case FILE_SHADER_OUTPUT: c = 'o'; break;
569    case FILE_MEMORY_BUFFER: c = 'b'; break; // Only used before lowering
570    case FILE_MEMORY_GLOBAL: c = 'g'; break;
571    case FILE_MEMORY_SHARED: c = 's'; break;
572    case FILE_MEMORY_LOCAL:  c = 'l'; break;
573    case FILE_BARRIER:       c = 'b'; break;
574    default:
575       assert(!"invalid file");
576       c = '?';
577       break;
578    }
579 
580    if (c == 'c')
581       PRINT("%s%c%i[", colour[TXT_MEM], c, reg.fileIndex);
582    else
583       PRINT("%s%c[", colour[TXT_MEM], c);
584 
585    if (dimRel) {
586       pos += dimRel->print(&buf[pos], size - pos, TYPE_S32);
587       PRINT("%s][", colour[TXT_MEM]);
588    }
589 
590    if (rel) {
591       pos += rel->print(&buf[pos], size - pos);
592       PRINT("%s%c", colour[TXT_DEFAULT], (reg.data.offset < 0) ? '-' : '+');
593    } else {
594       assert(reg.data.offset >= 0);
595    }
596    PRINT("%s0x%x%s]", colour[TXT_IMMD], abs(reg.data.offset), colour[TXT_MEM]);
597 
598    return pos;
599 }
600 
print() const601 void Instruction::print() const
602 {
603    #define BUFSZ 512
604 
605    const size_t size = BUFSZ;
606 
607    char buf[BUFSZ];
608    int s, d;
609    size_t pos = 0;
610 
611    PRINT("%s", colour[TXT_INSN]);
612 
613    if (join)
614       PRINT("join ");
615 
616    if (predSrc >= 0) {
617       const size_t pre = pos;
618       if (getSrc(predSrc)->reg.file == FILE_PREDICATE) {
619          if (cc == CC_NOT_P)
620             PRINT("not");
621       } else {
622          PRINT("%s", CondCodeStr[cc]);
623       }
624       if (pos > pre)
625          SPACE();
626       pos += getSrc(predSrc)->print(&buf[pos], BUFSZ - pos);
627       PRINT(" %s", colour[TXT_INSN]);
628    }
629 
630    if (saturate)
631       PRINT("sat ");
632 
633    if (asFlow()) {
634       PRINT("%s", operationStr[op]);
635       if (asFlow()->indirect)
636          PRINT(" ind");
637       if (asFlow()->absolute)
638          PRINT(" abs");
639       if (op == OP_CALL && asFlow()->builtin) {
640          PRINT(" %sBUILTIN:%i", colour[TXT_BRA], asFlow()->target.builtin);
641       } else
642       if (op == OP_CALL && asFlow()->target.fn) {
643          PRINT(" %s%s:%i", colour[TXT_BRA],
644                asFlow()->target.fn->getName(),
645                asFlow()->target.fn->getLabel());
646       } else
647       if (asFlow()->target.bb)
648          PRINT(" %sBB:%i", colour[TXT_BRA], asFlow()->target.bb->getId());
649    } else {
650       if (asTex())
651          PRINT("%s%s ", operationStr[op], asTex()->tex.scalar ? "s" : "");
652       else
653          PRINT("%s ", operationStr[op]);
654       if (op == OP_LINTERP || op == OP_PINTERP)
655          PRINT("%s ", interpStr[ipa]);
656       switch (op) {
657       case OP_SUREDP:
658       case OP_SUREDB:
659       case OP_ATOM:
660          if (subOp < ARRAY_SIZE(atomSubOpStr))
661             PRINT("%s ", atomSubOpStr[subOp]);
662          break;
663       case OP_LOAD:
664       case OP_STORE:
665          if (subOp < ARRAY_SIZE(ldstSubOpStr))
666             PRINT("%s ", ldstSubOpStr[subOp]);
667          break;
668       case OP_SUBFM:
669          if (subOp < ARRAY_SIZE(subfmOpStr))
670             PRINT("%s ", subfmOpStr[subOp]);
671          break;
672       case OP_SHFL:
673          if (subOp < ARRAY_SIZE(shflOpStr))
674             PRINT("%s ", shflOpStr[subOp]);
675          break;
676       case OP_PIXLD:
677          if (subOp < ARRAY_SIZE(pixldOpStr))
678             PRINT("%s ", pixldOpStr[subOp]);
679          break;
680       case OP_RCP:
681       case OP_RSQ:
682          if (subOp < ARRAY_SIZE(rcprsqOpStr))
683             PRINT("%s ", rcprsqOpStr[subOp]);
684          break;
685       case OP_EMIT:
686          if (subOp < ARRAY_SIZE(emitOpStr))
687             PRINT("%s ", emitOpStr[subOp]);
688          break;
689       case OP_CCTL:
690          if (subOp < ARRAY_SIZE(cctlOpStr))
691             PRINT("%s ", cctlOpStr[subOp]);
692          break;
693       case OP_BAR:
694          if (subOp < ARRAY_SIZE(barOpStr))
695             PRINT("%s ", barOpStr[subOp]);
696          break;
697       case OP_XMAD: {
698          if (subOp & NV50_IR_SUBOP_XMAD_PSL)
699             PRINT("psl ");
700          if (subOp & NV50_IR_SUBOP_XMAD_MRG)
701             PRINT("mrg ");
702          unsigned cmode = (subOp & NV50_IR_SUBOP_XMAD_CMODE_MASK);
703          cmode >>= NV50_IR_SUBOP_XMAD_CMODE_SHIFT;
704          if (cmode && cmode <= ARRAY_SIZE(xmadOpCModeStr))
705             PRINT("%s ", xmadOpCModeStr[cmode - 1]);
706          for (int i = 0; i < 2; i++)
707             PRINT("h%d ", (subOp & NV50_IR_SUBOP_XMAD_H1(i)) ? 1 : 0);
708          break;
709       }
710       default:
711          if (subOp)
712             PRINT("(SUBOP:%u) ", subOp);
713          break;
714       }
715       if (perPatch)
716          PRINT("patch ");
717       if (asTex()) {
718          PRINT("%s %s$r%u $s%u ", asTex()->tex.target.getName(),
719                colour[TXT_MEM], asTex()->tex.r, asTex()->tex.s);
720          if (op == OP_TXG)
721             PRINT("%s ", gatherCompStr[asTex()->tex.gatherComp]);
722          PRINT("%s %s", texMaskStr[asTex()->tex.mask], colour[TXT_INSN]);
723       }
724 
725       if (postFactor)
726          PRINT("x2^%i ", postFactor);
727       PRINT("%s%s", dnz ? "dnz " : (ftz ? "ftz " : ""),  DataTypeStr[dType]);
728    }
729 
730    if (rnd != ROUND_N)
731       PRINT(" %s", RoundModeStr[rnd]);
732 
733    if (defExists(1))
734       PRINT(" {");
735    for (d = 0; defExists(d); ++d) {
736       SPACE();
737       pos += getDef(d)->print(&buf[pos], size - pos);
738    }
739    if (d > 1)
740       PRINT(" %s}", colour[TXT_INSN]);
741    else
742    if (!d && !asFlow())
743       PRINT(" %s#", colour[TXT_INSN]);
744 
745    if (asCmp())
746       PRINT(" %s%s", colour[TXT_INSN], CondCodeStr[asCmp()->setCond]);
747 
748    if (sType != dType)
749       PRINT(" %s%s", colour[TXT_INSN], DataTypeStr[sType]);
750 
751    for (s = 0; srcExists(s); ++s) {
752       if (s == predSrc || src(s).usedAsPtr)
753          continue;
754       const size_t pre = pos;
755       SPACE();
756       pos += src(s).mod.print(&buf[pos], BUFSZ - pos);
757       if (pos > pre + 1)
758          SPACE();
759       if (src(s).isIndirect(0) || src(s).isIndirect(1))
760          pos += getSrc(s)->asSym()->print(&buf[pos], BUFSZ - pos,
761                                           getIndirect(s, 0),
762                                           getIndirect(s, 1));
763       else
764          pos += getSrc(s)->print(&buf[pos], BUFSZ - pos, sType);
765    }
766    if (exit)
767       PRINT("%s exit", colour[TXT_INSN]);
768 
769    PRINT("%s", colour[TXT_DEFAULT]);
770 
771    buf[MIN2(pos, BUFSZ - 1)] = 0;
772 
773    INFO("%s (%u)\n", buf, encSize);
774 }
775 
776 class PrintPass : public Pass
777 {
778 public:
PrintPass(bool omitLineNum)779    PrintPass(bool omitLineNum) : serial(0), omit_serial(omitLineNum) { }
780 
781    virtual bool visit(Function *);
782    virtual bool visit(BasicBlock *);
783    virtual bool visit(Instruction *);
784 
785 private:
786    int serial;
787    bool omit_serial;
788 };
789 
790 bool
visit(Function * fn)791 PrintPass::visit(Function *fn)
792 {
793    char str[16];
794 
795    INFO("\n%s:%i (", fn->getName(), fn->getLabel());
796 
797    if (!fn->outs.empty())
798       INFO("out");
799    for (std::deque<ValueRef>::iterator it = fn->outs.begin();
800         it != fn->outs.end();
801         ++it) {
802       it->get()->print(str, sizeof(str), typeOfSize(it->get()->reg.size));
803       INFO(" %s", str);
804    }
805 
806    if (!fn->ins.empty())
807       INFO("%s%sin", colour[TXT_DEFAULT], fn->outs.empty() ? "" : ", ");
808    for (std::deque<ValueDef>::iterator it = fn->ins.begin();
809         it != fn->ins.end();
810         ++it) {
811       it->get()->print(str, sizeof(str), typeOfSize(it->get()->reg.size));
812       INFO(" %s", str);
813    }
814    INFO("%s)\n", colour[TXT_DEFAULT]);
815 
816    return true;
817 }
818 
819 bool
visit(BasicBlock * bb)820 PrintPass::visit(BasicBlock *bb)
821 {
822 #if 0
823    INFO("---\n");
824    for (Graph::EdgeIterator ei = bb->cfg.incident(); !ei.end(); ei.next())
825       INFO(" <- BB:%i (%s)\n",
826            BasicBlock::get(ei.getNode())->getId(),
827            ei.getEdge()->typeStr());
828 #endif
829    INFO("BB:%i (%u instructions) - ", bb->getId(), bb->getInsnCount());
830 
831    if (bb->idom())
832       INFO("idom = BB:%i, ", bb->idom()->getId());
833 
834    INFO("df = { ");
835    for (DLList::Iterator df = bb->getDF().iterator(); !df.end(); df.next())
836       INFO("BB:%i ", BasicBlock::get(df)->getId());
837 
838    INFO("}\n");
839 
840    for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next())
841       INFO(" -> BB:%i (%s)\n",
842            BasicBlock::get(ei.getNode())->getId(),
843            ei.getEdge()->typeStr());
844 
845    return true;
846 }
847 
848 bool
visit(Instruction * insn)849 PrintPass::visit(Instruction *insn)
850 {
851    if (omit_serial)
852       INFO("     ");
853    else
854       INFO("%3i: ", serial);
855    serial++;
856    insn->print();
857    return true;
858 }
859 
860 void
print()861 Function::print()
862 {
863    PrintPass pass(prog->driver->omitLineNum);
864    pass.run(this, true, false);
865 }
866 
867 void
print()868 Program::print()
869 {
870    PrintPass pass(driver->omitLineNum);
871    init_colours();
872    pass.run(this, true, false);
873 }
874 
875 void
printLiveIntervals() const876 Function::printLiveIntervals() const
877 {
878    INFO("printing live intervals ...\n");
879 
880    for (ArrayList::Iterator it = allLValues.iterator(); !it.end(); it.next()) {
881       const Value *lval = Value::get(it)->asLValue();
882       if (lval && !lval->livei.isEmpty()) {
883          INFO("livei(%%%i): ", lval->id);
884          lval->livei.print();
885       }
886    }
887 }
888 
889 } // namespace nv50_ir
890 
891 extern void
nv50_ir_prog_info_out_print(struct nv50_ir_prog_info_out * info_out)892 nv50_ir_prog_info_out_print(struct nv50_ir_prog_info_out *info_out)
893 {
894    int i;
895 
896    INFO("{\n");
897    INFO("   \"target\":\"%d\",\n", info_out->target);
898    INFO("   \"type\":\"%d\",\n", info_out->type);
899 
900    // Bin
901    INFO("   \"bin\":{\n");
902    INFO("      \"maxGPR\":\"%d\",\n", info_out->bin.maxGPR);
903    INFO("      \"tlsSpace\":\"%d\",\n", info_out->bin.tlsSpace);
904    INFO("      \"smemSize\":\"%d\",\n", info_out->bin.smemSize);
905    INFO("      \"codeSize\":\"%d\",\n", info_out->bin.codeSize);
906    INFO("      \"instructions\":\"%d\",\n", info_out->bin.instructions);
907 
908    // RelocInfo
909    INFO("      \"RelocInfo\":");
910    if (!info_out->bin.relocData) {
911       INFO("\"NULL\",\n");
912    } else {
913       nv50_ir::RelocInfo *reloc = (nv50_ir::RelocInfo *)info_out->bin.relocData;
914       INFO("{\n");
915       INFO("         \"codePos\":\"%d\",\n", reloc->codePos);
916       INFO("         \"libPos\":\"%d\",\n", reloc->libPos);
917       INFO("         \"dataPos\":\"%d\",\n", reloc->dataPos);
918       INFO("         \"count\":\"%d\",\n", reloc->count);
919       INFO("         \"RelocEntry\":[\n");
920       for (unsigned int i = 0; i < reloc->count; i++) {
921          INFO("            {\"data\":\"%d\",\t\"mask\":\"%d\",\t\"offset\":\"%d\",\t\"bitPos\":\"%d\",\t\"type\":\"%d\"}",
922                    reloc->entry[i].data, reloc->entry[i].mask, reloc->entry[i].offset, reloc->entry[i].bitPos, reloc->entry[i].type
923                    );
924       }
925       INFO("\n");
926       INFO("         ]\n");
927       INFO("      },\n");
928    }
929 
930    // FixupInfo
931    INFO("      \"FixupInfo\":");
932    if (!info_out->bin.fixupData) {
933       INFO("\"NULL\"\n");
934    } else {
935       nv50_ir::FixupInfo *fixup = (nv50_ir::FixupInfo *)info_out->bin.fixupData;
936       INFO("{\n");
937       INFO("         \"count\":\"%d\"\n", fixup->count);
938       INFO("         \"FixupEntry\":[\n");
939       for (unsigned int i = 0; i < fixup->count; i++) {
940          INFO("            {\"apply\":\"%p\",\t\"ipa\":\"%d\",\t\"reg\":\"%d\",\t\"loc\":\"%d\"}\n",
941                    fixup->entry[i].apply, fixup->entry[i].ipa, fixup->entry[i].reg, fixup->entry[i].loc);
942       }
943       INFO("\n");
944       INFO("         ]\n");
945       INFO("      }\n");
946 
947       INFO("   },\n");
948    }
949 
950    if (info_out->numSysVals) {
951       INFO("   \"sv\":[\n");
952       for (i = 0; i < info_out->numSysVals; i++) {
953             INFO("      {\"sn\":\"%d\"}\n",
954                  info_out->sv[i].sn);
955       }
956       INFO("\n   ],\n");
957    }
958    if (info_out->numInputs) {
959       INFO("   \"in\":[\n");
960       for (i = 0; i < info_out->numInputs; i++) {
961          INFO("      {\"id\":\"%d\",\t\"sn\":\"%d\",\t\"si\":\"%d\"}\n",
962               info_out->in[i].id, info_out->in[i].sn, info_out->in[i].si);
963       }
964       INFO("\n   ],\n");
965    }
966    if (info_out->numOutputs) {
967       INFO("   \"out\":[\n");
968       for (i = 0; i < info_out->numOutputs; i++) {
969          INFO("      {\"id\":\"%d\",\t\"sn\":\"%d\",\t\"si\":\"%d\"}\n",
970               info_out->out[i].id, info_out->out[i].sn, info_out->out[i].si);
971       }
972       INFO("\n   ],\n");
973    }
974 
975    INFO("   \"numInputs\":\"%d\",\n", info_out->numInputs);
976    INFO("   \"numOutputs\":\"%d\",\n", info_out->numOutputs);
977    INFO("   \"numPatchConstants\":\"%d\",\n", info_out->numPatchConstants);
978    INFO("   \"numSysVals\":\"%d\",\n", info_out->numSysVals);
979 
980    INFO("   \"prop\":{\n");
981    switch (info_out->type) {
982       case PIPE_SHADER_VERTEX:
983          INFO("      \"vp\": {\"usesDrawParameters\":\"%s\"}\n",
984                info_out->prop.vp.usesDrawParameters ? "true" : "false");
985          break;
986       case PIPE_SHADER_TESS_CTRL:
987       case PIPE_SHADER_TESS_EVAL:
988          INFO("      \"tp\":{\n");
989          INFO("         \"outputPatchSize\":\"%d\"\n", info_out->prop.tp.outputPatchSize);
990          INFO("         \"partitioning\":\"%d\"\n", info_out->prop.tp.partitioning);
991          INFO("         \"winding\":\"%d\"\n", info_out->prop.tp.winding);
992          INFO("         \"domain\":\"%d\"\n", info_out->prop.tp.domain);
993          INFO("         \"outputPrim\":\"%d\"\n", info_out->prop.tp.outputPrim);
994          break;
995       case PIPE_SHADER_GEOMETRY:
996          INFO("      \"gp\":{\n");
997          INFO("         \"outputPrim\":\"%d\"\n", info_out->prop.gp.outputPrim);
998          INFO("         \"instancesCount\":\"%d\"\n", info_out->prop.gp.instanceCount);
999          INFO("         \"maxVertices\":\"%d\"\n", info_out->prop.gp.maxVertices);
1000          break;
1001       case PIPE_SHADER_FRAGMENT:
1002          INFO("      \"fp\":{\n");
1003          INFO("         \"numColourResults\":\"%d\"\n", info_out->prop.fp.numColourResults);
1004          INFO("         \"writesDepth\":\"%s\"\n", info_out->prop.fp.writesDepth ? "true" : "false");
1005          INFO("         \"earlyFragTests\":\"%s\"\n", info_out->prop.fp.earlyFragTests ? "true" : "false");
1006          INFO("         \"postDepthCoverage\":\"%s\"\n", info_out->prop.fp.postDepthCoverage ? "true" : "false");
1007          INFO("         \"usesDiscard\":\"%s\"\n", info_out->prop.fp.usesDiscard ? "true" : "false");
1008          INFO("         \"usesSampleMaskIn\":\"%s\"\n", info_out->prop.fp.usesSampleMaskIn ? "true" : "false");
1009          INFO("         \"readsFramebuffer\":\"%s\"\n", info_out->prop.fp.readsFramebuffer ? "true" : "false");
1010          INFO("         \"readsSampleLocations\":\"%s\"\n", info_out->prop.fp.readsSampleLocations ? "true" : "false");
1011          INFO("         \"separateFragData\":\"%s\"\n", info_out->prop.fp.separateFragData ? "true" : "false");
1012          break;
1013       default:
1014          assert("!unhandled pipe shader type\n");
1015    }
1016    INFO("      }\n");
1017    INFO("   }\n");
1018 
1019    INFO("   \"io\":{\n");
1020    INFO("      \"clipDistances\":\"%d\"\n", info_out->io.clipDistances);
1021    INFO("      \"cullDistances\":\"%d\"\n", info_out->io.cullDistances);
1022    INFO("      \"genUserClip\":\"%d\"\n", info_out->io.genUserClip);
1023    INFO("      \"instanceId\":\"%d\"\n", info_out->io.instanceId);
1024    INFO("      \"vertexId\":\"%d\"\n", info_out->io.vertexId);
1025    INFO("      \"edgeFlagIn\":\"%d\"\n", info_out->io.edgeFlagIn);
1026    INFO("      \"edgeFlagOut\":\"%d\"\n", info_out->io.edgeFlagOut);
1027    INFO("      \"fragDepth\":\"%d\"\n", info_out->io.fragDepth);
1028    INFO("      \"sampleMask\":\"%d\"\n", info_out->io.sampleMask);
1029    INFO("      \"globalAccess\":\"%d\"\n", info_out->io.globalAccess);
1030    INFO("      \"fp64\":\"%s\"\n", info_out->io.fp64 ? "true" : "false");
1031    INFO("      \"layer_viewport_relative\":\"%s\"\n", info_out->io.layer_viewport_relative ? "true" : "false");
1032    INFO("   \"}\n");
1033    INFO("   \"numBarriers\":\"%d\"\n", info_out->numBarriers);
1034    INFO("   \"driverPriv\":\"%p\"\n", info_out->driverPriv);
1035 
1036    INFO("}\n");
1037 }
1038