1b8e80941Smrg/* 2b8e80941Smrg * Copyright © 2016-2017 Broadcom 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21b8e80941Smrg * IN THE SOFTWARE. 22b8e80941Smrg */ 23b8e80941Smrg 24b8e80941Smrg#include "broadcom/common/v3d_device_info.h" 25b8e80941Smrg#include "v3d_compiler.h" 26b8e80941Smrg 27b8e80941Smrg/* Prints a human-readable description of the uniform reference. */ 28b8e80941Smrgvoid 29b8e80941Smrgvir_dump_uniform(enum quniform_contents contents, 30b8e80941Smrg uint32_t data) 31b8e80941Smrg{ 32b8e80941Smrg static const char *quniform_names[] = { 33b8e80941Smrg [QUNIFORM_ALPHA_REF] = "alpha_ref", 34b8e80941Smrg [QUNIFORM_VIEWPORT_X_SCALE] = "vp_x_scale", 35b8e80941Smrg [QUNIFORM_VIEWPORT_Y_SCALE] = "vp_y_scale", 36b8e80941Smrg [QUNIFORM_VIEWPORT_Z_OFFSET] = "vp_z_offset", 37b8e80941Smrg [QUNIFORM_VIEWPORT_Z_SCALE] = "vp_z_scale", 38b8e80941Smrg [QUNIFORM_SHARED_OFFSET] = "shared_offset", 39b8e80941Smrg }; 40b8e80941Smrg 41b8e80941Smrg switch (contents) { 42b8e80941Smrg case QUNIFORM_CONSTANT: 43b8e80941Smrg fprintf(stderr, "0x%08x / %f", data, uif(data)); 44b8e80941Smrg break; 45b8e80941Smrg 46b8e80941Smrg case QUNIFORM_UNIFORM: 47b8e80941Smrg fprintf(stderr, "push[%d]", data); 48b8e80941Smrg break; 49b8e80941Smrg 50b8e80941Smrg case QUNIFORM_TEXTURE_CONFIG_P1: 51b8e80941Smrg fprintf(stderr, "tex[%d].p1", data); 52b8e80941Smrg break; 53b8e80941Smrg 54b8e80941Smrg case QUNIFORM_TMU_CONFIG_P0: 55b8e80941Smrg fprintf(stderr, "tex[%d].p0 | 0x%x", 56b8e80941Smrg v3d_unit_data_get_unit(data), 57b8e80941Smrg v3d_unit_data_get_offset(data)); 58b8e80941Smrg break; 59b8e80941Smrg 60b8e80941Smrg case QUNIFORM_TMU_CONFIG_P1: 61b8e80941Smrg fprintf(stderr, "tex[%d].p1 | 0x%x", 62b8e80941Smrg v3d_unit_data_get_unit(data), 63b8e80941Smrg v3d_unit_data_get_offset(data)); 64b8e80941Smrg break; 65b8e80941Smrg 66b8e80941Smrg case QUNIFORM_IMAGE_TMU_CONFIG_P0: 67b8e80941Smrg fprintf(stderr, "img[%d].p0 | 0x%x", 68b8e80941Smrg v3d_unit_data_get_unit(data), 69b8e80941Smrg v3d_unit_data_get_offset(data)); 70b8e80941Smrg break; 71b8e80941Smrg 72b8e80941Smrg case QUNIFORM_TEXTURE_WIDTH: 73b8e80941Smrg fprintf(stderr, "tex[%d].width", data); 74b8e80941Smrg break; 75b8e80941Smrg case QUNIFORM_TEXTURE_HEIGHT: 76b8e80941Smrg fprintf(stderr, "tex[%d].height", data); 77b8e80941Smrg break; 78b8e80941Smrg case QUNIFORM_TEXTURE_DEPTH: 79b8e80941Smrg fprintf(stderr, "tex[%d].depth", data); 80b8e80941Smrg break; 81b8e80941Smrg case QUNIFORM_TEXTURE_ARRAY_SIZE: 82b8e80941Smrg fprintf(stderr, "tex[%d].array_size", data); 83b8e80941Smrg break; 84b8e80941Smrg case QUNIFORM_TEXTURE_LEVELS: 85b8e80941Smrg fprintf(stderr, "tex[%d].levels", data); 86b8e80941Smrg break; 87b8e80941Smrg 88b8e80941Smrg case QUNIFORM_IMAGE_WIDTH: 89b8e80941Smrg fprintf(stderr, "img[%d].width", data); 90b8e80941Smrg break; 91b8e80941Smrg case QUNIFORM_IMAGE_HEIGHT: 92b8e80941Smrg fprintf(stderr, "img[%d].height", data); 93b8e80941Smrg break; 94b8e80941Smrg case QUNIFORM_IMAGE_DEPTH: 95b8e80941Smrg fprintf(stderr, "img[%d].depth", data); 96b8e80941Smrg break; 97b8e80941Smrg case QUNIFORM_IMAGE_ARRAY_SIZE: 98b8e80941Smrg fprintf(stderr, "img[%d].array_size", data); 99b8e80941Smrg break; 100b8e80941Smrg 101b8e80941Smrg case QUNIFORM_SPILL_OFFSET: 102b8e80941Smrg fprintf(stderr, "spill_offset"); 103b8e80941Smrg break; 104b8e80941Smrg 105b8e80941Smrg case QUNIFORM_SPILL_SIZE_PER_THREAD: 106b8e80941Smrg fprintf(stderr, "spill_size_per_thread"); 107b8e80941Smrg break; 108b8e80941Smrg 109b8e80941Smrg case QUNIFORM_UBO_ADDR: 110b8e80941Smrg fprintf(stderr, "ubo[%d]+0x%x", 111b8e80941Smrg v3d_unit_data_get_unit(data), 112b8e80941Smrg v3d_unit_data_get_offset(data)); 113b8e80941Smrg break; 114b8e80941Smrg 115b8e80941Smrg case QUNIFORM_SSBO_OFFSET: 116b8e80941Smrg fprintf(stderr, "ssbo[%d]", data); 117b8e80941Smrg break; 118b8e80941Smrg 119b8e80941Smrg case QUNIFORM_GET_BUFFER_SIZE: 120b8e80941Smrg fprintf(stderr, "ssbo_size[%d]", data); 121b8e80941Smrg break; 122b8e80941Smrg 123b8e80941Smrg case QUNIFORM_NUM_WORK_GROUPS: 124b8e80941Smrg fprintf(stderr, "num_wg.%c", data < 3 ? "xyz"[data] : '?'); 125b8e80941Smrg break; 126b8e80941Smrg 127b8e80941Smrg default: 128b8e80941Smrg if (quniform_contents_is_texture_p0(contents)) { 129b8e80941Smrg fprintf(stderr, "tex[%d].p0: 0x%08x", 130b8e80941Smrg contents - QUNIFORM_TEXTURE_CONFIG_P0_0, 131b8e80941Smrg data); 132b8e80941Smrg } else if (contents < ARRAY_SIZE(quniform_names) && 133b8e80941Smrg quniform_names[contents]) { 134b8e80941Smrg fprintf(stderr, "%s", 135b8e80941Smrg quniform_names[contents]); 136b8e80941Smrg } else { 137b8e80941Smrg fprintf(stderr, "%d / 0x%08x", contents, data); 138b8e80941Smrg } 139b8e80941Smrg } 140b8e80941Smrg} 141b8e80941Smrg 142b8e80941Smrgstatic void 143b8e80941Smrgvir_print_reg(struct v3d_compile *c, const struct qinst *inst, 144b8e80941Smrg struct qreg reg) 145b8e80941Smrg{ 146b8e80941Smrg switch (reg.file) { 147b8e80941Smrg 148b8e80941Smrg case QFILE_NULL: 149b8e80941Smrg fprintf(stderr, "null"); 150b8e80941Smrg break; 151b8e80941Smrg 152b8e80941Smrg case QFILE_LOAD_IMM: 153b8e80941Smrg fprintf(stderr, "0x%08x (%f)", reg.index, uif(reg.index)); 154b8e80941Smrg break; 155b8e80941Smrg 156b8e80941Smrg case QFILE_REG: 157b8e80941Smrg fprintf(stderr, "rf%d", reg.index); 158b8e80941Smrg break; 159b8e80941Smrg 160b8e80941Smrg case QFILE_MAGIC: 161b8e80941Smrg fprintf(stderr, "%s", v3d_qpu_magic_waddr_name(reg.index)); 162b8e80941Smrg break; 163b8e80941Smrg 164b8e80941Smrg case QFILE_SMALL_IMM: { 165b8e80941Smrg uint32_t unpacked; 166b8e80941Smrg bool ok = v3d_qpu_small_imm_unpack(c->devinfo, 167b8e80941Smrg inst->qpu.raddr_b, 168b8e80941Smrg &unpacked); 169b8e80941Smrg assert(ok); (void) ok; 170b8e80941Smrg 171b8e80941Smrg if ((int)inst->qpu.raddr_b >= -16 && 172b8e80941Smrg (int)inst->qpu.raddr_b <= 15) 173b8e80941Smrg fprintf(stderr, "%d", unpacked); 174b8e80941Smrg else 175b8e80941Smrg fprintf(stderr, "%f", uif(unpacked)); 176b8e80941Smrg break; 177b8e80941Smrg } 178b8e80941Smrg 179b8e80941Smrg case QFILE_VPM: 180b8e80941Smrg fprintf(stderr, "vpm%d.%d", 181b8e80941Smrg reg.index / 4, reg.index % 4); 182b8e80941Smrg break; 183b8e80941Smrg 184b8e80941Smrg case QFILE_TEMP: 185b8e80941Smrg fprintf(stderr, "t%d", reg.index); 186b8e80941Smrg break; 187b8e80941Smrg } 188b8e80941Smrg} 189b8e80941Smrg 190b8e80941Smrgstatic void 191b8e80941Smrgvir_dump_sig_addr(const struct v3d_device_info *devinfo, 192b8e80941Smrg const struct v3d_qpu_instr *instr) 193b8e80941Smrg{ 194b8e80941Smrg if (devinfo->ver < 41) 195b8e80941Smrg return; 196b8e80941Smrg 197b8e80941Smrg if (!instr->sig_magic) 198b8e80941Smrg fprintf(stderr, ".rf%d", instr->sig_addr); 199b8e80941Smrg else { 200b8e80941Smrg const char *name = v3d_qpu_magic_waddr_name(instr->sig_addr); 201b8e80941Smrg if (name) 202b8e80941Smrg fprintf(stderr, ".%s", name); 203b8e80941Smrg else 204b8e80941Smrg fprintf(stderr, ".UNKNOWN%d", instr->sig_addr); 205b8e80941Smrg } 206b8e80941Smrg} 207b8e80941Smrg 208b8e80941Smrgstatic void 209b8e80941Smrgvir_dump_sig(struct v3d_compile *c, struct qinst *inst) 210b8e80941Smrg{ 211b8e80941Smrg struct v3d_qpu_sig *sig = &inst->qpu.sig; 212b8e80941Smrg 213b8e80941Smrg if (sig->thrsw) 214b8e80941Smrg fprintf(stderr, "; thrsw"); 215b8e80941Smrg if (sig->ldvary) { 216b8e80941Smrg fprintf(stderr, "; ldvary"); 217b8e80941Smrg vir_dump_sig_addr(c->devinfo, &inst->qpu); 218b8e80941Smrg } 219b8e80941Smrg if (sig->ldvpm) 220b8e80941Smrg fprintf(stderr, "; ldvpm"); 221b8e80941Smrg if (sig->ldtmu) { 222b8e80941Smrg fprintf(stderr, "; ldtmu"); 223b8e80941Smrg vir_dump_sig_addr(c->devinfo, &inst->qpu); 224b8e80941Smrg } 225b8e80941Smrg if (sig->ldtlb) { 226b8e80941Smrg fprintf(stderr, "; ldtlb"); 227b8e80941Smrg vir_dump_sig_addr(c->devinfo, &inst->qpu); 228b8e80941Smrg } 229b8e80941Smrg if (sig->ldtlbu) { 230b8e80941Smrg fprintf(stderr, "; ldtlbu"); 231b8e80941Smrg vir_dump_sig_addr(c->devinfo, &inst->qpu); 232b8e80941Smrg } 233b8e80941Smrg if (sig->ldunif) 234b8e80941Smrg fprintf(stderr, "; ldunif"); 235b8e80941Smrg if (sig->ldunifrf) { 236b8e80941Smrg fprintf(stderr, "; ldunifrf"); 237b8e80941Smrg vir_dump_sig_addr(c->devinfo, &inst->qpu); 238b8e80941Smrg } 239b8e80941Smrg if (sig->ldunifa) 240b8e80941Smrg fprintf(stderr, "; ldunifa"); 241b8e80941Smrg if (sig->ldunifarf) { 242b8e80941Smrg fprintf(stderr, "; ldunifarf"); 243b8e80941Smrg vir_dump_sig_addr(c->devinfo, &inst->qpu); 244b8e80941Smrg } 245b8e80941Smrg if (sig->wrtmuc) 246b8e80941Smrg fprintf(stderr, "; wrtmuc"); 247b8e80941Smrg} 248b8e80941Smrg 249b8e80941Smrgstatic void 250b8e80941Smrgvir_dump_alu(struct v3d_compile *c, struct qinst *inst) 251b8e80941Smrg{ 252b8e80941Smrg struct v3d_qpu_instr *instr = &inst->qpu; 253b8e80941Smrg int nsrc = vir_get_nsrc(inst); 254b8e80941Smrg enum v3d_qpu_input_unpack unpack[2]; 255b8e80941Smrg 256b8e80941Smrg if (inst->qpu.alu.add.op != V3D_QPU_A_NOP) { 257b8e80941Smrg fprintf(stderr, "%s", v3d_qpu_add_op_name(instr->alu.add.op)); 258b8e80941Smrg fprintf(stderr, "%s", v3d_qpu_cond_name(instr->flags.ac)); 259b8e80941Smrg fprintf(stderr, "%s", v3d_qpu_pf_name(instr->flags.apf)); 260b8e80941Smrg fprintf(stderr, "%s", v3d_qpu_uf_name(instr->flags.auf)); 261b8e80941Smrg fprintf(stderr, " "); 262b8e80941Smrg 263b8e80941Smrg vir_print_reg(c, inst, inst->dst); 264b8e80941Smrg fprintf(stderr, "%s", v3d_qpu_pack_name(instr->alu.add.output_pack)); 265b8e80941Smrg 266b8e80941Smrg unpack[0] = instr->alu.add.a_unpack; 267b8e80941Smrg unpack[1] = instr->alu.add.b_unpack; 268b8e80941Smrg } else { 269b8e80941Smrg fprintf(stderr, "%s", v3d_qpu_mul_op_name(instr->alu.mul.op)); 270b8e80941Smrg fprintf(stderr, "%s", v3d_qpu_cond_name(instr->flags.mc)); 271b8e80941Smrg fprintf(stderr, "%s", v3d_qpu_pf_name(instr->flags.mpf)); 272b8e80941Smrg fprintf(stderr, "%s", v3d_qpu_uf_name(instr->flags.muf)); 273b8e80941Smrg fprintf(stderr, " "); 274b8e80941Smrg 275b8e80941Smrg vir_print_reg(c, inst, inst->dst); 276b8e80941Smrg fprintf(stderr, "%s", v3d_qpu_pack_name(instr->alu.mul.output_pack)); 277b8e80941Smrg 278b8e80941Smrg unpack[0] = instr->alu.mul.a_unpack; 279b8e80941Smrg unpack[1] = instr->alu.mul.b_unpack; 280b8e80941Smrg } 281b8e80941Smrg 282b8e80941Smrg for (int i = 0; i < nsrc; i++) { 283b8e80941Smrg fprintf(stderr, ", "); 284b8e80941Smrg vir_print_reg(c, inst, inst->src[i]); 285b8e80941Smrg fprintf(stderr, "%s", v3d_qpu_unpack_name(unpack[i])); 286b8e80941Smrg } 287b8e80941Smrg 288b8e80941Smrg vir_dump_sig(c, inst); 289b8e80941Smrg} 290b8e80941Smrg 291b8e80941Smrgvoid 292b8e80941Smrgvir_dump_inst(struct v3d_compile *c, struct qinst *inst) 293b8e80941Smrg{ 294b8e80941Smrg struct v3d_qpu_instr *instr = &inst->qpu; 295b8e80941Smrg 296b8e80941Smrg switch (inst->qpu.type) { 297b8e80941Smrg case V3D_QPU_INSTR_TYPE_ALU: 298b8e80941Smrg vir_dump_alu(c, inst); 299b8e80941Smrg break; 300b8e80941Smrg case V3D_QPU_INSTR_TYPE_BRANCH: 301b8e80941Smrg fprintf(stderr, "b"); 302b8e80941Smrg if (instr->branch.ub) 303b8e80941Smrg fprintf(stderr, "u"); 304b8e80941Smrg 305b8e80941Smrg fprintf(stderr, "%s", 306b8e80941Smrg v3d_qpu_branch_cond_name(instr->branch.cond)); 307b8e80941Smrg fprintf(stderr, "%s", v3d_qpu_msfign_name(instr->branch.msfign)); 308b8e80941Smrg 309b8e80941Smrg switch (instr->branch.bdi) { 310b8e80941Smrg case V3D_QPU_BRANCH_DEST_ABS: 311b8e80941Smrg fprintf(stderr, " zero_addr+0x%08x", instr->branch.offset); 312b8e80941Smrg break; 313b8e80941Smrg 314b8e80941Smrg case V3D_QPU_BRANCH_DEST_REL: 315b8e80941Smrg fprintf(stderr, " %d", instr->branch.offset); 316b8e80941Smrg break; 317b8e80941Smrg 318b8e80941Smrg case V3D_QPU_BRANCH_DEST_LINK_REG: 319b8e80941Smrg fprintf(stderr, " lri"); 320b8e80941Smrg break; 321b8e80941Smrg 322b8e80941Smrg case V3D_QPU_BRANCH_DEST_REGFILE: 323b8e80941Smrg fprintf(stderr, " rf%d", instr->branch.raddr_a); 324b8e80941Smrg break; 325b8e80941Smrg } 326b8e80941Smrg 327b8e80941Smrg if (instr->branch.ub) { 328b8e80941Smrg switch (instr->branch.bdu) { 329b8e80941Smrg case V3D_QPU_BRANCH_DEST_ABS: 330b8e80941Smrg fprintf(stderr, ", a:unif"); 331b8e80941Smrg break; 332b8e80941Smrg 333b8e80941Smrg case V3D_QPU_BRANCH_DEST_REL: 334b8e80941Smrg fprintf(stderr, ", r:unif"); 335b8e80941Smrg break; 336b8e80941Smrg 337b8e80941Smrg case V3D_QPU_BRANCH_DEST_LINK_REG: 338b8e80941Smrg fprintf(stderr, ", lri"); 339b8e80941Smrg break; 340b8e80941Smrg 341b8e80941Smrg case V3D_QPU_BRANCH_DEST_REGFILE: 342b8e80941Smrg fprintf(stderr, ", rf%d", instr->branch.raddr_a); 343b8e80941Smrg break; 344b8e80941Smrg } 345b8e80941Smrg } 346b8e80941Smrg break; 347b8e80941Smrg } 348b8e80941Smrg 349b8e80941Smrg if (vir_has_uniform(inst)) { 350b8e80941Smrg fprintf(stderr, " ("); 351b8e80941Smrg vir_dump_uniform(c->uniform_contents[inst->uniform], 352b8e80941Smrg c->uniform_data[inst->uniform]); 353b8e80941Smrg fprintf(stderr, ")"); 354b8e80941Smrg } 355b8e80941Smrg} 356b8e80941Smrg 357b8e80941Smrgvoid 358b8e80941Smrgvir_dump(struct v3d_compile *c) 359b8e80941Smrg{ 360b8e80941Smrg int ip = 0; 361b8e80941Smrg int pressure = 0; 362b8e80941Smrg 363b8e80941Smrg vir_for_each_block(block, c) { 364b8e80941Smrg fprintf(stderr, "BLOCK %d:\n", block->index); 365b8e80941Smrg vir_for_each_inst(inst, block) { 366b8e80941Smrg if (c->live_intervals_valid) { 367b8e80941Smrg for (int i = 0; i < c->num_temps; i++) { 368b8e80941Smrg if (c->temp_start[i] == ip) 369b8e80941Smrg pressure++; 370b8e80941Smrg } 371b8e80941Smrg 372b8e80941Smrg fprintf(stderr, "P%4d ", pressure); 373b8e80941Smrg 374b8e80941Smrg bool first = true; 375b8e80941Smrg 376b8e80941Smrg for (int i = 0; i < c->num_temps; i++) { 377b8e80941Smrg if (c->temp_start[i] != ip) 378b8e80941Smrg continue; 379b8e80941Smrg 380b8e80941Smrg if (first) { 381b8e80941Smrg first = false; 382b8e80941Smrg } else { 383b8e80941Smrg fprintf(stderr, ", "); 384b8e80941Smrg } 385b8e80941Smrg if (BITSET_TEST(c->spillable, i)) 386b8e80941Smrg fprintf(stderr, "S%4d", i); 387b8e80941Smrg else 388b8e80941Smrg fprintf(stderr, "U%4d", i); 389b8e80941Smrg } 390b8e80941Smrg 391b8e80941Smrg if (first) 392b8e80941Smrg fprintf(stderr, " "); 393b8e80941Smrg else 394b8e80941Smrg fprintf(stderr, " "); 395b8e80941Smrg } 396b8e80941Smrg 397b8e80941Smrg if (c->live_intervals_valid) { 398b8e80941Smrg bool first = true; 399b8e80941Smrg 400b8e80941Smrg for (int i = 0; i < c->num_temps; i++) { 401b8e80941Smrg if (c->temp_end[i] != ip) 402b8e80941Smrg continue; 403b8e80941Smrg 404b8e80941Smrg if (first) { 405b8e80941Smrg first = false; 406b8e80941Smrg } else { 407b8e80941Smrg fprintf(stderr, ", "); 408b8e80941Smrg } 409b8e80941Smrg fprintf(stderr, "E%4d", i); 410b8e80941Smrg pressure--; 411b8e80941Smrg } 412b8e80941Smrg 413b8e80941Smrg if (first) 414b8e80941Smrg fprintf(stderr, " "); 415b8e80941Smrg else 416b8e80941Smrg fprintf(stderr, " "); 417b8e80941Smrg } 418b8e80941Smrg 419b8e80941Smrg vir_dump_inst(c, inst); 420b8e80941Smrg fprintf(stderr, "\n"); 421b8e80941Smrg ip++; 422b8e80941Smrg } 423b8e80941Smrg if (block->successors[1]) { 424b8e80941Smrg fprintf(stderr, "-> BLOCK %d, %d\n", 425b8e80941Smrg block->successors[0]->index, 426b8e80941Smrg block->successors[1]->index); 427b8e80941Smrg } else if (block->successors[0]) { 428b8e80941Smrg fprintf(stderr, "-> BLOCK %d\n", 429b8e80941Smrg block->successors[0]->index); 430b8e80941Smrg } 431b8e80941Smrg } 432b8e80941Smrg} 433