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