• 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 *TSStr[17] =
352 {
353    "THREAD_STATE_ENUM0",
354    "THREAD_STATE_ENUM1",
355    "THREAD_STATE_ENUM2",
356    "THREAD_STATE_ENUM3",
357    "THREAD_STATE_ENUM4",
358    "TRAP_RETURN_PC_LO",
359    "TRAP_RETURN_PC_HI",
360    "TRAP_RETURN_MASK",
361    "MEXITED",
362    "MKILL",
363    "MACTIVE",
364    "MATEXIT",
365    "OPT_STACK",
366    "API_CALL_DEPTH",
367    "ATEXIT_PC_LO",
368    "ATEXIT_PC_HI",
369    "PQUAD_MACTIVE",
370 };
371 
372 static const char *interpStr[16] =
373 {
374    "pass",
375    "mul",
376    "flat",
377    "sc",
378    "cent pass",
379    "cent mul",
380    "cent flat",
381    "cent sc",
382    "off pass",
383    "off mul",
384    "off flat",
385    "off sc",
386    "samp pass",
387    "samp mul",
388    "samp flat",
389    "samp sc"
390 };
391 
392 static const char *texMaskStr[16] =
393 {
394    "____",
395    "r___",
396    "_g__",
397    "rg__",
398    "__b_",
399    "r_b_",
400    "_gb_",
401    "rgb_",
402    "___a",
403    "r__a",
404    "_g_a",
405    "rg_a",
406    "__ba",
407    "r_ba",
408    "_gba",
409    "rgba",
410 };
411 
412 static const char *gatherCompStr[4] =
413 {
414    "r", "g", "b", "a",
415 };
416 
417 #define PRINT(args...)                                \
418    do {                                               \
419       pos += snprintf(&buf[pos], size - pos, args);   \
420    } while(0)
421 
422 #define SPACE_PRINT(cond, args...)                      \
423    do {                                                 \
424       if (cond)                                         \
425          buf[pos++] = ' ';                              \
426       pos += snprintf(&buf[pos], size - pos, args);     \
427    } while(0)
428 
429 #define SPACE()                                    \
430    do {                                            \
431       if (pos < size)                              \
432          buf[pos++] = ' ';                         \
433    } while(0)
434 
print(char * buf,size_t size) const435 int Modifier::print(char *buf, size_t size) const
436 {
437    size_t pos = 0;
438 
439    if (bits)
440       PRINT("%s", colour[TXT_INSN]);
441 
442    size_t base = pos;
443 
444    if (bits & NV50_IR_MOD_NOT)
445       PRINT("not");
446    if (bits & NV50_IR_MOD_SAT)
447       SPACE_PRINT(pos > base && pos < size, "sat");
448    if (bits & NV50_IR_MOD_NEG)
449       SPACE_PRINT(pos > base && pos < size, "neg");
450    if (bits & NV50_IR_MOD_ABS)
451       SPACE_PRINT(pos > base && pos < size, "abs");
452 
453    return pos;
454 }
455 
print(char * buf,size_t size,DataType ty) const456 int LValue::print(char *buf, size_t size, DataType ty) const
457 {
458    const char *postFix = "";
459    size_t pos = 0;
460    int idx = join->reg.data.id >= 0 ? join->reg.data.id : id;
461    char p = join->reg.data.id >= 0 ? '$' : '%';
462    char r;
463    int col = TXT_DEFAULT;
464 
465    switch (reg.file) {
466    case FILE_GPR:
467       r = 'r'; col = TXT_GPR;
468       if (reg.size == 2) {
469          if (p == '$') {
470             postFix = (idx & 1) ? "h" : "l";
471             idx /= 2;
472          } else {
473             postFix = "s";
474          }
475       } else
476       if (reg.size == 8) {
477          postFix = "d";
478       } else
479       if (reg.size == 16) {
480          postFix = "q";
481       } else
482       if (reg.size == 12) {
483          postFix = "t";
484       }
485       break;
486    case FILE_PREDICATE:
487       r = 'p'; col = TXT_REGISTER;
488       if (reg.size == 2)
489          postFix = "d";
490       else
491       if (reg.size == 4)
492          postFix = "q";
493       break;
494    case FILE_FLAGS:
495       r = 'c'; col = TXT_FLAGS;
496       break;
497    case FILE_ADDRESS:
498       r = 'a'; col = TXT_REGISTER;
499       break;
500    case FILE_BARRIER:
501       r = 'b'; col = TXT_REGISTER;
502       break;
503    default:
504       assert(!"invalid file for lvalue");
505       r = '?';
506       break;
507    }
508 
509    PRINT("%s%c%c%i%s", colour[col], p, r, idx, postFix);
510 
511    return pos;
512 }
513 
print(char * buf,size_t size,DataType ty) const514 int ImmediateValue::print(char *buf, size_t size, DataType ty) const
515 {
516    size_t pos = 0;
517 
518    PRINT("%s", colour[TXT_IMMD]);
519 
520    switch (ty) {
521    case TYPE_F32: PRINT("%f", reg.data.f32); break;
522    case TYPE_F64: PRINT("%f", reg.data.f64); break;
523    case TYPE_U8:  PRINT("0x%02x", reg.data.u8); break;
524    case TYPE_S8:  PRINT("%i", reg.data.s8); break;
525    case TYPE_U16: PRINT("0x%04x", reg.data.u16); break;
526    case TYPE_S16: PRINT("%i", reg.data.s16); break;
527    case TYPE_U32: PRINT("0x%08x", reg.data.u32); break;
528    case TYPE_S32: PRINT("%i", reg.data.s32); break;
529    case TYPE_U64:
530    case TYPE_S64:
531    default:
532       PRINT("0x%016" PRIx64, reg.data.u64);
533       break;
534    }
535    return pos;
536 }
537 
print(char * buf,size_t size,DataType ty) const538 int Symbol::print(char *buf, size_t size, DataType ty) const
539 {
540    return print(buf, size, NULL, NULL, ty);
541 }
542 
print(char * buf,size_t size,Value * rel,Value * dimRel,DataType ty) const543 int Symbol::print(char *buf, size_t size,
544                   Value *rel, Value *dimRel, DataType ty) const
545 {
546    STATIC_ASSERT(ARRAY_SIZE(SemanticStr) == SV_LAST + 1);
547 
548    size_t pos = 0;
549    char c;
550 
551    if (ty == TYPE_NONE)
552       ty = typeOfSize(reg.size);
553 
554    if (reg.file == FILE_SYSTEM_VALUE) {
555       PRINT("%ssv[%s%s:%i%s", colour[TXT_MEM],
556             colour[TXT_REGISTER],
557             SemanticStr[reg.data.sv.sv], reg.data.sv.index, colour[TXT_MEM]);
558       if (rel) {
559          PRINT("%s+", colour[TXT_DEFAULT]);
560          pos += rel->print(&buf[pos], size - pos);
561       }
562       PRINT("%s]", colour[TXT_MEM]);
563       return pos;
564    } else if (reg.file == FILE_THREAD_STATE) {
565       PRINT("%sts[%s%s%s]", colour[TXT_MEM], colour[TXT_REGISTER],
566             TSStr[reg.data.ts], colour[TXT_MEM]);
567       return pos;
568    }
569 
570    switch (reg.file) {
571    case FILE_MEMORY_CONST:  c = 'c'; break;
572    case FILE_SHADER_INPUT:  c = 'a'; break;
573    case FILE_SHADER_OUTPUT: c = 'o'; break;
574    case FILE_MEMORY_BUFFER: c = 'b'; break; // Only used before lowering
575    case FILE_MEMORY_GLOBAL: c = 'g'; break;
576    case FILE_MEMORY_SHARED: c = 's'; break;
577    case FILE_MEMORY_LOCAL:  c = 'l'; break;
578    case FILE_BARRIER:       c = 'b'; break;
579    default:
580       assert(!"invalid file");
581       c = '?';
582       break;
583    }
584 
585    if (c == 'c')
586       PRINT("%s%c%i[", colour[TXT_MEM], c, reg.fileIndex);
587    else
588       PRINT("%s%c[", colour[TXT_MEM], c);
589 
590    if (dimRel) {
591       pos += dimRel->print(&buf[pos], size - pos, TYPE_S32);
592       PRINT("%s][", colour[TXT_MEM]);
593    }
594 
595    if (rel) {
596       pos += rel->print(&buf[pos], size - pos);
597       PRINT("%s%c", colour[TXT_DEFAULT], (reg.data.offset < 0) ? '-' : '+');
598    } else {
599       assert(reg.data.offset >= 0);
600    }
601    PRINT("%s0x%x%s]", colour[TXT_IMMD], abs(reg.data.offset), colour[TXT_MEM]);
602 
603    return pos;
604 }
605 
print() const606 void Instruction::print() const
607 {
608    #define BUFSZ 512
609 
610    const size_t size = BUFSZ;
611 
612    char buf[BUFSZ];
613    int s, d;
614    size_t pos = 0;
615 
616    PRINT("%s", colour[TXT_INSN]);
617 
618    if (join)
619       PRINT("join ");
620 
621    if (predSrc >= 0) {
622       const size_t pre = pos;
623       if (getSrc(predSrc)->reg.file == FILE_PREDICATE) {
624          if (cc == CC_NOT_P)
625             PRINT("not");
626       } else {
627          PRINT("%s", CondCodeStr[cc]);
628       }
629       if (pos > pre)
630          SPACE();
631       pos += getSrc(predSrc)->print(&buf[pos], BUFSZ - pos);
632       PRINT(" %s", colour[TXT_INSN]);
633    }
634 
635    if (saturate)
636       PRINT("sat ");
637 
638    if (asFlow()) {
639       PRINT("%s", operationStr[op]);
640       if (asFlow()->indirect)
641          PRINT(" ind");
642       if (asFlow()->absolute)
643          PRINT(" abs");
644       if (op == OP_CALL && asFlow()->builtin) {
645          PRINT(" %sBUILTIN:%i", colour[TXT_BRA], asFlow()->target.builtin);
646       } else
647       if (op == OP_CALL && asFlow()->target.fn) {
648          PRINT(" %s%s:%i", colour[TXT_BRA],
649                asFlow()->target.fn->getName(),
650                asFlow()->target.fn->getLabel());
651       } else
652       if (asFlow()->target.bb)
653          PRINT(" %sBB:%i", colour[TXT_BRA], asFlow()->target.bb->getId());
654    } else {
655       if (asTex())
656          PRINT("%s%s ", operationStr[op], asTex()->tex.scalar ? "s" : "");
657       else
658          PRINT("%s ", operationStr[op]);
659       if (op == OP_LINTERP || op == OP_PINTERP)
660          PRINT("%s ", interpStr[ipa]);
661       switch (op) {
662       case OP_SUREDP:
663       case OP_SUREDB:
664       case OP_ATOM:
665          if (subOp < ARRAY_SIZE(atomSubOpStr))
666             PRINT("%s ", atomSubOpStr[subOp]);
667          break;
668       case OP_LOAD:
669       case OP_STORE:
670          if (subOp < ARRAY_SIZE(ldstSubOpStr))
671             PRINT("%s ", ldstSubOpStr[subOp]);
672          break;
673       case OP_SUBFM:
674          if (subOp < ARRAY_SIZE(subfmOpStr))
675             PRINT("%s ", subfmOpStr[subOp]);
676          break;
677       case OP_SHFL:
678          if (subOp < ARRAY_SIZE(shflOpStr))
679             PRINT("%s ", shflOpStr[subOp]);
680          break;
681       case OP_PIXLD:
682          if (subOp < ARRAY_SIZE(pixldOpStr))
683             PRINT("%s ", pixldOpStr[subOp]);
684          break;
685       case OP_RCP:
686       case OP_RSQ:
687          if (subOp < ARRAY_SIZE(rcprsqOpStr))
688             PRINT("%s ", rcprsqOpStr[subOp]);
689          break;
690       case OP_EMIT:
691          if (subOp < ARRAY_SIZE(emitOpStr))
692             PRINT("%s ", emitOpStr[subOp]);
693          break;
694       case OP_CCTL:
695          if (subOp < ARRAY_SIZE(cctlOpStr))
696             PRINT("%s ", cctlOpStr[subOp]);
697          break;
698       case OP_BAR:
699          if (subOp < ARRAY_SIZE(barOpStr))
700             PRINT("%s ", barOpStr[subOp]);
701          break;
702       case OP_XMAD: {
703          if (subOp & NV50_IR_SUBOP_XMAD_PSL)
704             PRINT("psl ");
705          if (subOp & NV50_IR_SUBOP_XMAD_MRG)
706             PRINT("mrg ");
707          unsigned cmode = (subOp & NV50_IR_SUBOP_XMAD_CMODE_MASK);
708          cmode >>= NV50_IR_SUBOP_XMAD_CMODE_SHIFT;
709          if (cmode && cmode <= ARRAY_SIZE(xmadOpCModeStr))
710             PRINT("%s ", xmadOpCModeStr[cmode - 1]);
711          for (int i = 0; i < 2; i++)
712             PRINT("h%d ", (subOp & NV50_IR_SUBOP_XMAD_H1(i)) ? 1 : 0);
713          break;
714       }
715       default:
716          if (subOp)
717             PRINT("(SUBOP:%u) ", subOp);
718          break;
719       }
720       if (perPatch)
721          PRINT("patch ");
722       if (asTex()) {
723          PRINT("%s %s$r%u $s%u ", asTex()->tex.target.getName(),
724                colour[TXT_MEM], asTex()->tex.r, asTex()->tex.s);
725          if (op == OP_TXG)
726             PRINT("%s ", gatherCompStr[asTex()->tex.gatherComp]);
727          PRINT("%s %s", texMaskStr[asTex()->tex.mask], colour[TXT_INSN]);
728       }
729 
730       if (postFactor)
731          PRINT("x2^%i ", postFactor);
732       PRINT("%s%s", dnz ? "dnz " : (ftz ? "ftz " : ""),  DataTypeStr[dType]);
733    }
734 
735    if (rnd != ROUND_N)
736       PRINT(" %s", RoundModeStr[rnd]);
737 
738    if (defExists(1))
739       PRINT(" {");
740    for (d = 0; defExists(d); ++d) {
741       SPACE();
742       pos += getDef(d)->print(&buf[pos], size - pos);
743    }
744    if (d > 1)
745       PRINT(" %s}", colour[TXT_INSN]);
746    else
747    if (!d && !asFlow())
748       PRINT(" %s#", colour[TXT_INSN]);
749 
750    if (asCmp())
751       PRINT(" %s%s", colour[TXT_INSN], CondCodeStr[asCmp()->setCond]);
752 
753    if (sType != dType)
754       PRINT(" %s%s", colour[TXT_INSN], DataTypeStr[sType]);
755 
756    for (s = 0; srcExists(s); ++s) {
757       if (s == predSrc || src(s).usedAsPtr)
758          continue;
759       const size_t pre = pos;
760       SPACE();
761       pos += src(s).mod.print(&buf[pos], BUFSZ - pos);
762       if (pos > pre + 1)
763          SPACE();
764       if (src(s).isIndirect(0) || src(s).isIndirect(1))
765          pos += getSrc(s)->asSym()->print(&buf[pos], BUFSZ - pos,
766                                           getIndirect(s, 0),
767                                           getIndirect(s, 1));
768       else
769          pos += getSrc(s)->print(&buf[pos], BUFSZ - pos, sType);
770    }
771    if (exit)
772       PRINT("%s exit", colour[TXT_INSN]);
773 
774    PRINT("%s", colour[TXT_DEFAULT]);
775 
776    buf[MIN2(pos, BUFSZ - 1)] = 0;
777 
778    INFO("%s (%u)\n", buf, encSize);
779 }
780 
781 class PrintPass : public Pass
782 {
783 public:
PrintPass(bool omitLineNum)784    PrintPass(bool omitLineNum) : serial(0), omit_serial(omitLineNum) { }
785 
786    virtual bool visit(Function *);
787    virtual bool visit(BasicBlock *);
788    virtual bool visit(Instruction *);
789 
790 private:
791    int serial;
792    bool omit_serial;
793 };
794 
795 bool
visit(Function * fn)796 PrintPass::visit(Function *fn)
797 {
798    char str[16];
799 
800    INFO("\n%s:%i (", fn->getName(), fn->getLabel());
801 
802    if (!fn->outs.empty())
803       INFO("out");
804    for (std::deque<ValueRef>::iterator it = fn->outs.begin();
805         it != fn->outs.end();
806         ++it) {
807       it->get()->print(str, sizeof(str), typeOfSize(it->get()->reg.size));
808       INFO(" %s", str);
809    }
810 
811    if (!fn->ins.empty())
812       INFO("%s%sin", colour[TXT_DEFAULT], fn->outs.empty() ? "" : ", ");
813    for (std::deque<ValueDef>::iterator it = fn->ins.begin();
814         it != fn->ins.end();
815         ++it) {
816       it->get()->print(str, sizeof(str), typeOfSize(it->get()->reg.size));
817       INFO(" %s", str);
818    }
819    INFO("%s)\n", colour[TXT_DEFAULT]);
820 
821    return true;
822 }
823 
824 bool
visit(BasicBlock * bb)825 PrintPass::visit(BasicBlock *bb)
826 {
827 #if 0
828    INFO("---\n");
829    for (Graph::EdgeIterator ei = bb->cfg.incident(); !ei.end(); ei.next())
830       INFO(" <- BB:%i (%s)\n",
831            BasicBlock::get(ei.getNode())->getId(),
832            ei.getEdge()->typeStr());
833 #endif
834    INFO("BB:%i (%u instructions) - ", bb->getId(), bb->getInsnCount());
835 
836    if (bb->idom())
837       INFO("idom = BB:%i, ", bb->idom()->getId());
838 
839    INFO("df = { ");
840    for (DLList::Iterator df = bb->getDF().iterator(); !df.end(); df.next())
841       INFO("BB:%i ", BasicBlock::get(df)->getId());
842 
843    INFO("}\n");
844 
845    for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next())
846       INFO(" -> BB:%i (%s)\n",
847            BasicBlock::get(ei.getNode())->getId(),
848            ei.getEdge()->typeStr());
849 
850    return true;
851 }
852 
853 bool
visit(Instruction * insn)854 PrintPass::visit(Instruction *insn)
855 {
856    if (omit_serial)
857       INFO("     ");
858    else
859       INFO("%3i: ", serial);
860    serial++;
861    insn->print();
862    return true;
863 }
864 
865 void
print()866 Function::print()
867 {
868    PrintPass pass(prog->driver->omitLineNum);
869    pass.run(this, true, false);
870 }
871 
872 void
print()873 Program::print()
874 {
875    PrintPass pass(driver->omitLineNum);
876    init_colours();
877    pass.run(this, true, false);
878 }
879 
880 void
printLiveIntervals() const881 Function::printLiveIntervals() const
882 {
883    INFO("printing live intervals ...\n");
884 
885    for (ArrayList::Iterator it = allLValues.iterator(); !it.end(); it.next()) {
886       const Value *lval = Value::get(it)->asLValue();
887       if (lval && !lval->livei.isEmpty()) {
888          INFO("livei(%%%i): ", lval->id);
889          lval->livei.print();
890       }
891    }
892 }
893 
894 } // namespace nv50_ir
895 
896 extern void
nv50_ir_prog_info_out_print(struct nv50_ir_prog_info_out * info_out)897 nv50_ir_prog_info_out_print(struct nv50_ir_prog_info_out *info_out)
898 {
899    int i;
900 
901    INFO("{\n");
902    INFO("   \"target\":\"%d\",\n", info_out->target);
903    INFO("   \"type\":\"%d\",\n", info_out->type);
904 
905    // Bin
906    INFO("   \"bin\":{\n");
907    INFO("      \"maxGPR\":\"%d\",\n", info_out->bin.maxGPR);
908    INFO("      \"tlsSpace\":\"%d\",\n", info_out->bin.tlsSpace);
909    INFO("      \"smemSize\":\"%d\",\n", info_out->bin.smemSize);
910    INFO("      \"codeSize\":\"%d\",\n", info_out->bin.codeSize);
911    INFO("      \"instructions\":\"%d\",\n", info_out->bin.instructions);
912 
913    // RelocInfo
914    INFO("      \"RelocInfo\":");
915    if (!info_out->bin.relocData) {
916       INFO("\"NULL\",\n");
917    } else {
918       nv50_ir::RelocInfo *reloc = (nv50_ir::RelocInfo *)info_out->bin.relocData;
919       INFO("{\n");
920       INFO("         \"codePos\":\"%d\",\n", reloc->codePos);
921       INFO("         \"libPos\":\"%d\",\n", reloc->libPos);
922       INFO("         \"dataPos\":\"%d\",\n", reloc->dataPos);
923       INFO("         \"count\":\"%d\",\n", reloc->count);
924       INFO("         \"RelocEntry\":[\n");
925       for (unsigned int i = 0; i < reloc->count; i++) {
926          INFO("            {\"data\":\"%d\",\t\"mask\":\"%d\",\t\"offset\":\"%d\",\t\"bitPos\":\"%d\",\t\"type\":\"%d\"}",
927                    reloc->entry[i].data, reloc->entry[i].mask, reloc->entry[i].offset, reloc->entry[i].bitPos, reloc->entry[i].type
928                    );
929       }
930       INFO("\n");
931       INFO("         ]\n");
932       INFO("      },\n");
933    }
934 
935    // FixupInfo
936    INFO("      \"FixupInfo\":");
937    if (!info_out->bin.fixupData) {
938       INFO("\"NULL\"\n");
939    } else {
940       nv50_ir::FixupInfo *fixup = (nv50_ir::FixupInfo *)info_out->bin.fixupData;
941       INFO("{\n");
942       INFO("         \"count\":\"%d\"\n", fixup->count);
943       INFO("         \"FixupEntry\":[\n");
944       for (unsigned int i = 0; i < fixup->count; i++) {
945          INFO("            {\"apply\":\"%p\",\t\"ipa\":\"%d\",\t\"reg\":\"%d\",\t\"loc\":\"%d\"}\n",
946                    fixup->entry[i].apply, fixup->entry[i].ipa, fixup->entry[i].reg, fixup->entry[i].loc);
947       }
948       INFO("\n");
949       INFO("         ]\n");
950       INFO("      }\n");
951 
952       INFO("   },\n");
953    }
954 
955    if (info_out->numSysVals) {
956       INFO("   \"sv\":[\n");
957       for (i = 0; i < info_out->numSysVals; i++) {
958          if (&(info_out->sv[i])) {
959             INFO("      {\"id\":\"%d\", \"sn\":\"%d\", \"si\":\"%d\"}\n",
960                    info_out->sv[i].id, info_out->sv[i].sn, info_out->sv[i].si);
961          }
962       }
963       INFO("\n   ],\n");
964    }
965    if (info_out->numInputs) {
966       INFO("   \"in\":[\n");
967       for (i = 0; i < info_out->numInputs; i++) {
968          if (&(info_out->in[i])) {
969             INFO("      {\"id\":\"%d\",\t\"sn\":\"%d\",\t\"si\":\"%d\"}\n",
970                 info_out->in[i].id, info_out->in[i].sn, info_out->in[i].si);
971          }
972       }
973       INFO("\n   ],\n");
974    }
975    if (info_out->numOutputs) {
976       INFO("   \"out\":[\n");
977       for (i = 0; i < info_out->numOutputs; i++) {
978          if (&(info_out->out[i])) {
979             INFO("      {\"id\":\"%d\",\t\"sn\":\"%d\",\t\"si\":\"%d\"}\n",
980                    info_out->out[i].id, info_out->out[i].sn, info_out->out[i].si);
981          }
982       }
983       INFO("\n   ],\n");
984    }
985 
986    INFO("   \"numInputs\":\"%d\",\n", info_out->numInputs);
987    INFO("   \"numOutputs\":\"%d\",\n", info_out->numOutputs);
988    INFO("   \"numPatchConstants\":\"%d\",\n", info_out->numPatchConstants);
989    INFO("   \"numSysVals\":\"%d\",\n", info_out->numSysVals);
990 
991    INFO("   \"prop\":{\n");
992    switch (info_out->type) {
993       case PIPE_SHADER_VERTEX:
994          INFO("      \"vp\": {\"usesDrawParameters\":\"%s\"}\n",
995                info_out->prop.vp.usesDrawParameters ? "true" : "false");
996          break;
997       case PIPE_SHADER_TESS_CTRL:
998       case PIPE_SHADER_TESS_EVAL:
999          INFO("      \"tp\":{\n");
1000          INFO("         \"outputPatchSize\":\"%d\"\n", info_out->prop.tp.outputPatchSize);
1001          INFO("         \"partitioning\":\"%d\"\n", info_out->prop.tp.partitioning);
1002          INFO("         \"winding\":\"%d\"\n", info_out->prop.tp.winding);
1003          INFO("         \"domain\":\"%d\"\n", info_out->prop.tp.domain);
1004          INFO("         \"outputPrim\":\"%d\"\n", info_out->prop.tp.outputPrim);
1005          break;
1006       case PIPE_SHADER_GEOMETRY:
1007          INFO("      \"gp\":{\n");
1008          INFO("         \"outputPrim\":\"%d\"\n", info_out->prop.gp.outputPrim);
1009          INFO("         \"instancesCount\":\"%d\"\n", info_out->prop.gp.instanceCount);
1010          INFO("         \"maxVertices\":\"%d\"\n", info_out->prop.gp.maxVertices);
1011          break;
1012       case PIPE_SHADER_FRAGMENT:
1013          INFO("      \"fp\":{\n");
1014          INFO("         \"numColourResults\":\"%d\"\n", info_out->prop.fp.numColourResults);
1015          INFO("         \"writesDepth\":\"%s\"\n", info_out->prop.fp.writesDepth ? "true" : "false");
1016          INFO("         \"earlyFragTests\":\"%s\"\n", info_out->prop.fp.earlyFragTests ? "true" : "false");
1017          INFO("         \"postDepthCoverage\":\"%s\"\n", info_out->prop.fp.postDepthCoverage ? "true" : "false");
1018          INFO("         \"usesDiscard\":\"%s\"\n", info_out->prop.fp.usesDiscard ? "true" : "false");
1019          INFO("         \"usesSampleMaskIn\":\"%s\"\n", info_out->prop.fp.usesSampleMaskIn ? "true" : "false");
1020          INFO("         \"readsFramebuffer\":\"%s\"\n", info_out->prop.fp.readsFramebuffer ? "true" : "false");
1021          INFO("         \"readsSampleLocations\":\"%s\"\n", info_out->prop.fp.readsSampleLocations ? "true" : "false");
1022          INFO("         \"separateFragData\":\"%s\"\n", info_out->prop.fp.separateFragData ? "true" : "false");
1023          break;
1024       default:
1025          assert("!unhandled pipe shader type\n");
1026    }
1027    INFO("      }\n");
1028    INFO("   }\n");
1029 
1030    INFO("   \"io\":{\n");
1031    INFO("      \"clipDistances\":\"%d\"\n", info_out->io.clipDistances);
1032    INFO("      \"cullDistances\":\"%d\"\n", info_out->io.cullDistances);
1033    INFO("      \"genUserClip\":\"%d\"\n", info_out->io.genUserClip);
1034    INFO("      \"instanceId\":\"%d\"\n", info_out->io.instanceId);
1035    INFO("      \"vertexId\":\"%d\"\n", info_out->io.vertexId);
1036    INFO("      \"edgeFlagIn\":\"%d\"\n", info_out->io.edgeFlagIn);
1037    INFO("      \"edgeFlagOut\":\"%d\"\n", info_out->io.edgeFlagOut);
1038    INFO("      \"fragDepth\":\"%d\"\n", info_out->io.fragDepth);
1039    INFO("      \"sampleMask\":\"%d\"\n", info_out->io.sampleMask);
1040    INFO("      \"globalAccess\":\"%d\"\n", info_out->io.globalAccess);
1041    INFO("      \"fp64\":\"%s\"\n", info_out->io.fp64 ? "true" : "false");
1042    INFO("      \"layer_viewport_relative\":\"%s\"\n", info_out->io.layer_viewport_relative ? "true" : "false");
1043    INFO("   \"}\n");
1044    INFO("   \"numBarriers\":\"%d\"\n", info_out->numBarriers);
1045    INFO("   \"driverPriv\":\"%p\"\n", info_out->driverPriv);
1046 
1047    INFO("}\n");
1048 }
1049