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 29namespace nv50_ir { 30 31enum 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 43static 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 55static const char *_nocolour[8] = 56{ 57 "", "", "", "", "", "", "", "" 58}; 59 60static const char **colour; 61 62static void init_colours() 63{ 64 if (getenv("NV50_PROG_DEBUG_NO_COLORS") != NULL) 65 colour = _nocolour; 66 else 67 colour = _colour; 68} 69 70const 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 207static const char *atomSubOpStr[] = 208{ 209 "add", "min", "max", "inc", "dec", "and", "or", "xor", "cas", "exch" 210}; 211 212static const char *ldstSubOpStr[] = 213{ 214 "", "lock", "unlock" 215}; 216 217static const char *subfmOpStr[] = 218{ 219 "", "3d" 220}; 221 222static const char *shflOpStr[] = 223{ 224 "idx", "up", "down", "bfly" 225}; 226 227static const char *pixldOpStr[] = 228{ 229 "count", "covmask", "covered", "offset", "cent_offset", "sampleid" 230}; 231 232static const char *rcprsqOpStr[] = 233{ 234 "", "64h" 235}; 236 237static const char *emitOpStr[] = 238{ 239 "", "restart" 240}; 241 242static const char *cctlOpStr[] = 243{ 244 "", "", "", "", "", "iv", "ivall" 245}; 246 247static const char *barOpStr[] = 248{ 249 "sync", "arrive", "red and", "red or", "red popc" 250}; 251 252static const char *xmadOpCModeStr[] = 253{ 254 "clo", "chi", "csfu", "cbcc" 255}; 256 257static 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 268static const char *RoundModeStr[] = 269{ 270 "", "rm", "rz", "rp", "rni", "rmi", "rzi", "rpi" 271}; 272 273static 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 301static 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 351static 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 372static 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 392static 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 412static 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 435int 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 456int 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 514int 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 538int Symbol::print(char *buf, size_t size, DataType ty) const 539{ 540 return print(buf, size, NULL, NULL, ty); 541} 542 543int 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 606void 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 781class PrintPass : public Pass 782{ 783public: 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 790private: 791 int serial; 792 bool omit_serial; 793}; 794 795bool 796PrintPass::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 824bool 825PrintPass::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 853bool 854PrintPass::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 865void 866Function::print() 867{ 868 PrintPass pass(prog->driver->omitLineNum); 869 pass.run(this, true, false); 870} 871 872void 873Program::print() 874{ 875 PrintPass pass(driver->omitLineNum); 876 init_colours(); 877 pass.run(this, true, false); 878} 879 880void 881Function::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 896extern void 897nv50_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