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