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