1 /* 2 * Copyright 2016 Broadcom 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 (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24 #include <stdlib.h> 25 #include "util/macros.h" 26 #include "broadcom/common/v3d_device_info.h" 27 #include "qpu_instr.h" 28 29 const char * 30 v3d_qpu_magic_waddr_name(enum v3d_qpu_waddr waddr) 31 { 32 static const char *waddr_magic[] = { 33 [V3D_QPU_WADDR_R0] = "r0", 34 [V3D_QPU_WADDR_R1] = "r1", 35 [V3D_QPU_WADDR_R2] = "r2", 36 [V3D_QPU_WADDR_R3] = "r3", 37 [V3D_QPU_WADDR_R4] = "r4", 38 [V3D_QPU_WADDR_R5] = "r5", 39 [V3D_QPU_WADDR_NOP] = "-", 40 [V3D_QPU_WADDR_TLB] = "tlb", 41 [V3D_QPU_WADDR_TLBU] = "tlbu", 42 [V3D_QPU_WADDR_TMU] = "tmu", 43 [V3D_QPU_WADDR_TMUL] = "tmul", 44 [V3D_QPU_WADDR_TMUD] = "tmud", 45 [V3D_QPU_WADDR_TMUA] = "tmua", 46 [V3D_QPU_WADDR_TMUAU] = "tmuau", 47 [V3D_QPU_WADDR_VPM] = "vpm", 48 [V3D_QPU_WADDR_VPMU] = "vpmu", 49 [V3D_QPU_WADDR_SYNC] = "sync", 50 [V3D_QPU_WADDR_SYNCU] = "syncu", 51 [V3D_QPU_WADDR_RECIP] = "recip", 52 [V3D_QPU_WADDR_RSQRT] = "rsqrt", 53 [V3D_QPU_WADDR_EXP] = "exp", 54 [V3D_QPU_WADDR_LOG] = "log", 55 [V3D_QPU_WADDR_SIN] = "sin", 56 [V3D_QPU_WADDR_RSQRT2] = "rsqrt2", 57 [V3D_QPU_WADDR_TMUC] = "tmuc", 58 [V3D_QPU_WADDR_TMUS] = "tmus", 59 [V3D_QPU_WADDR_TMUT] = "tmut", 60 [V3D_QPU_WADDR_TMUR] = "tmur", 61 [V3D_QPU_WADDR_TMUI] = "tmui", 62 [V3D_QPU_WADDR_TMUB] = "tmub", 63 [V3D_QPU_WADDR_TMUDREF] = "tmudref", 64 [V3D_QPU_WADDR_TMUOFF] = "tmuoff", 65 [V3D_QPU_WADDR_TMUSCM] = "tmuscm", 66 [V3D_QPU_WADDR_TMUSF] = "tmusf", 67 [V3D_QPU_WADDR_TMUSLOD] = "tmuslod", 68 [V3D_QPU_WADDR_TMUHS] = "tmuhs", 69 [V3D_QPU_WADDR_TMUHSCM] = "tmuscm", 70 [V3D_QPU_WADDR_TMUHSF] = "tmuhsf", 71 [V3D_QPU_WADDR_TMUHSLOD] = "tmuhslod", 72 [V3D_QPU_WADDR_R5REP] = "r5rep", 73 }; 74 75 return waddr_magic[waddr]; 76 } 77 78 const char * 79 v3d_qpu_add_op_name(enum v3d_qpu_add_op op) 80 { 81 static const char *op_names[] = { 82 [V3D_QPU_A_FADD] = "fadd", 83 [V3D_QPU_A_FADDNF] = "faddnf", 84 [V3D_QPU_A_VFPACK] = "vfpack", 85 [V3D_QPU_A_ADD] = "add", 86 [V3D_QPU_A_SUB] = "sub", 87 [V3D_QPU_A_FSUB] = "fsub", 88 [V3D_QPU_A_MIN] = "min", 89 [V3D_QPU_A_MAX] = "max", 90 [V3D_QPU_A_UMIN] = "umin", 91 [V3D_QPU_A_UMAX] = "umax", 92 [V3D_QPU_A_SHL] = "shl", 93 [V3D_QPU_A_SHR] = "shr", 94 [V3D_QPU_A_ASR] = "asr", 95 [V3D_QPU_A_ROR] = "ror", 96 [V3D_QPU_A_FMIN] = "fmin", 97 [V3D_QPU_A_FMAX] = "fmax", 98 [V3D_QPU_A_VFMIN] = "vfmin", 99 [V3D_QPU_A_AND] = "and", 100 [V3D_QPU_A_OR] = "or", 101 [V3D_QPU_A_XOR] = "xor", 102 [V3D_QPU_A_VADD] = "vadd", 103 [V3D_QPU_A_VSUB] = "vsub", 104 [V3D_QPU_A_NOT] = "not", 105 [V3D_QPU_A_NEG] = "neg", 106 [V3D_QPU_A_FLAPUSH] = "flapush", 107 [V3D_QPU_A_FLBPUSH] = "flbpush", 108 [V3D_QPU_A_FLBPOP] = "flbpop", 109 [V3D_QPU_A_SETMSF] = "setmsf", 110 [V3D_QPU_A_SETREVF] = "setrevf", 111 [V3D_QPU_A_NOP] = "nop", 112 [V3D_QPU_A_TIDX] = "tidx", 113 [V3D_QPU_A_EIDX] = "eidx", 114 [V3D_QPU_A_LR] = "lr", 115 [V3D_QPU_A_VFLA] = "vfla", 116 [V3D_QPU_A_VFLNA] = "vflna", 117 [V3D_QPU_A_VFLB] = "vflb", 118 [V3D_QPU_A_VFLNB] = "vflnb", 119 [V3D_QPU_A_FXCD] = "fxcd", 120 [V3D_QPU_A_XCD] = "xcd", 121 [V3D_QPU_A_FYCD] = "fycd", 122 [V3D_QPU_A_YCD] = "ycd", 123 [V3D_QPU_A_MSF] = "msf", 124 [V3D_QPU_A_REVF] = "revf", 125 [V3D_QPU_A_VDWWT] = "vdwwt", 126 [V3D_QPU_A_IID] = "iid", 127 [V3D_QPU_A_SAMPID] = "sampid", 128 [V3D_QPU_A_PATCHID] = "patchid", 129 [V3D_QPU_A_TMUWT] = "tmuwt", 130 [V3D_QPU_A_VPMSETUP] = "vpmsetup", 131 [V3D_QPU_A_VPMWT] = "vpmwt", 132 [V3D_QPU_A_LDVPMV_IN] = "ldvpmv_in", 133 [V3D_QPU_A_LDVPMV_OUT] = "ldvpmv_out", 134 [V3D_QPU_A_LDVPMD_IN] = "ldvpmd_in", 135 [V3D_QPU_A_LDVPMD_OUT] = "ldvpmd_out", 136 [V3D_QPU_A_LDVPMP] = "ldvpmp", 137 [V3D_QPU_A_LDVPMG_IN] = "ldvpmg_in", 138 [V3D_QPU_A_LDVPMG_OUT] = "ldvpmg_out", 139 [V3D_QPU_A_FCMP] = "fcmp", 140 [V3D_QPU_A_VFMAX] = "vfmax", 141 [V3D_QPU_A_FROUND] = "fround", 142 [V3D_QPU_A_FTOIN] = "ftoin", 143 [V3D_QPU_A_FTRUNC] = "ftrunc", 144 [V3D_QPU_A_FTOIZ] = "ftoiz", 145 [V3D_QPU_A_FFLOOR] = "ffloor", 146 [V3D_QPU_A_FTOUZ] = "ftouz", 147 [V3D_QPU_A_FCEIL] = "fceil", 148 [V3D_QPU_A_FTOC] = "ftoc", 149 [V3D_QPU_A_FDX] = "fdx", 150 [V3D_QPU_A_FDY] = "fdy", 151 [V3D_QPU_A_STVPMV] = "stvpmv", 152 [V3D_QPU_A_STVPMD] = "stvpmd", 153 [V3D_QPU_A_STVPMP] = "stvpmp", 154 [V3D_QPU_A_ITOF] = "itof", 155 [V3D_QPU_A_CLZ] = "clz", 156 [V3D_QPU_A_UTOF] = "utof", 157 }; 158 159 if (op >= ARRAY_SIZE(op_names)) 160 return NULL; 161 162 return op_names[op]; 163 } 164 165 const char * 166 v3d_qpu_mul_op_name(enum v3d_qpu_mul_op op) 167 { 168 static const char *op_names[] = { 169 [V3D_QPU_M_ADD] = "add", 170 [V3D_QPU_M_SUB] = "sub", 171 [V3D_QPU_M_UMUL24] = "umul24", 172 [V3D_QPU_M_VFMUL] = "vfmul", 173 [V3D_QPU_M_SMUL24] = "smul24", 174 [V3D_QPU_M_MULTOP] = "multop", 175 [V3D_QPU_M_FMOV] = "fmov", 176 [V3D_QPU_M_MOV] = "mov", 177 [V3D_QPU_M_NOP] = "nop", 178 [V3D_QPU_M_FMUL] = "fmul", 179 }; 180 181 if (op >= ARRAY_SIZE(op_names)) 182 return NULL; 183 184 return op_names[op]; 185 } 186 187 const char * 188 v3d_qpu_cond_name(enum v3d_qpu_cond cond) 189 { 190 switch (cond) { 191 case V3D_QPU_COND_NONE: 192 return ""; 193 case V3D_QPU_COND_IFA: 194 return ".ifa"; 195 case V3D_QPU_COND_IFB: 196 return ".ifb"; 197 case V3D_QPU_COND_IFNA: 198 return ".ifna"; 199 case V3D_QPU_COND_IFNB: 200 return ".ifnb"; 201 default: 202 unreachable("bad cond value"); 203 } 204 } 205 206 const char * 207 v3d_qpu_branch_cond_name(enum v3d_qpu_branch_cond cond) 208 { 209 switch (cond) { 210 case V3D_QPU_BRANCH_COND_ALWAYS: 211 return ""; 212 case V3D_QPU_BRANCH_COND_A0: 213 return ".a0"; 214 case V3D_QPU_BRANCH_COND_NA0: 215 return ".na0"; 216 case V3D_QPU_BRANCH_COND_ALLA: 217 return ".alla"; 218 case V3D_QPU_BRANCH_COND_ANYNA: 219 return ".anyna"; 220 case V3D_QPU_BRANCH_COND_ANYA: 221 return ".anya"; 222 case V3D_QPU_BRANCH_COND_ALLNA: 223 return ".allna"; 224 default: 225 unreachable("bad branch cond value"); 226 } 227 } 228 229 const char * 230 v3d_qpu_msfign_name(enum v3d_qpu_msfign msfign) 231 { 232 switch (msfign) { 233 case V3D_QPU_MSFIGN_NONE: 234 return ""; 235 case V3D_QPU_MSFIGN_P: 236 return "p"; 237 case V3D_QPU_MSFIGN_Q: 238 return "q"; 239 default: 240 unreachable("bad branch cond value"); 241 } 242 } 243 244 const char * 245 v3d_qpu_pf_name(enum v3d_qpu_pf pf) 246 { 247 switch (pf) { 248 case V3D_QPU_PF_NONE: 249 return ""; 250 case V3D_QPU_PF_PUSHZ: 251 return ".pushz"; 252 case V3D_QPU_PF_PUSHN: 253 return ".pushn"; 254 case V3D_QPU_PF_PUSHC: 255 return ".pushc"; 256 default: 257 unreachable("bad pf value"); 258 } 259 } 260 261 const char * 262 v3d_qpu_uf_name(enum v3d_qpu_uf uf) 263 { 264 switch (uf) { 265 case V3D_QPU_UF_NONE: 266 return ""; 267 case V3D_QPU_UF_ANDZ: 268 return ".andz"; 269 case V3D_QPU_UF_ANDNZ: 270 return ".andnz"; 271 case V3D_QPU_UF_NORZ: 272 return ".norz"; 273 case V3D_QPU_UF_NORNZ: 274 return ".nornz"; 275 case V3D_QPU_UF_ANDN: 276 return ".andn"; 277 case V3D_QPU_UF_ANDNN: 278 return ".andnn"; 279 case V3D_QPU_UF_NORN: 280 return ".norn"; 281 case V3D_QPU_UF_NORNN: 282 return ".nornn"; 283 case V3D_QPU_UF_ANDC: 284 return ".andc"; 285 case V3D_QPU_UF_ANDNC: 286 return ".andnc"; 287 case V3D_QPU_UF_NORC: 288 return ".norc"; 289 case V3D_QPU_UF_NORNC: 290 return ".nornc"; 291 default: 292 unreachable("bad pf value"); 293 } 294 } 295 296 const char * 297 v3d_qpu_pack_name(enum v3d_qpu_output_pack pack) 298 { 299 switch (pack) { 300 case V3D_QPU_PACK_NONE: 301 return ""; 302 case V3D_QPU_PACK_L: 303 return ".l"; 304 case V3D_QPU_PACK_H: 305 return ".h"; 306 default: 307 unreachable("bad pack value"); 308 } 309 } 310 311 const char * 312 v3d_qpu_unpack_name(enum v3d_qpu_input_unpack unpack) 313 { 314 switch (unpack) { 315 case V3D_QPU_UNPACK_NONE: 316 return ""; 317 case V3D_QPU_UNPACK_L: 318 return ".l"; 319 case V3D_QPU_UNPACK_H: 320 return ".h"; 321 case V3D_QPU_UNPACK_ABS: 322 return ".abs"; 323 case V3D_QPU_UNPACK_REPLICATE_32F_16: 324 return ".ff"; 325 case V3D_QPU_UNPACK_REPLICATE_L_16: 326 return ".ll"; 327 case V3D_QPU_UNPACK_REPLICATE_H_16: 328 return ".hh"; 329 case V3D_QPU_UNPACK_SWAP_16: 330 return ".swp"; 331 default: 332 unreachable("bad unpack value"); 333 } 334 } 335 336 #define D 1 337 #define A 2 338 #define B 4 339 static const uint8_t add_op_args[] = { 340 [V3D_QPU_A_FADD] = D | A | B, 341 [V3D_QPU_A_FADDNF] = D | A | B, 342 [V3D_QPU_A_VFPACK] = D | A | B, 343 [V3D_QPU_A_ADD] = D | A | B, 344 [V3D_QPU_A_VFPACK] = D | A | B, 345 [V3D_QPU_A_SUB] = D | A | B, 346 [V3D_QPU_A_VFPACK] = D | A | B, 347 [V3D_QPU_A_FSUB] = D | A | B, 348 [V3D_QPU_A_MIN] = D | A | B, 349 [V3D_QPU_A_MAX] = D | A | B, 350 [V3D_QPU_A_UMIN] = D | A | B, 351 [V3D_QPU_A_UMAX] = D | A | B, 352 [V3D_QPU_A_SHL] = D | A | B, 353 [V3D_QPU_A_SHR] = D | A | B, 354 [V3D_QPU_A_ASR] = D | A | B, 355 [V3D_QPU_A_ROR] = D | A | B, 356 [V3D_QPU_A_FMIN] = D | A | B, 357 [V3D_QPU_A_FMAX] = D | A | B, 358 [V3D_QPU_A_VFMIN] = D | A | B, 359 360 [V3D_QPU_A_AND] = D | A | B, 361 [V3D_QPU_A_OR] = D | A | B, 362 [V3D_QPU_A_XOR] = D | A | B, 363 364 [V3D_QPU_A_VADD] = D | A | B, 365 [V3D_QPU_A_VSUB] = D | A | B, 366 [V3D_QPU_A_NOT] = D | A, 367 [V3D_QPU_A_NEG] = D | A, 368 [V3D_QPU_A_FLAPUSH] = D | A, 369 [V3D_QPU_A_FLBPUSH] = D | A, 370 [V3D_QPU_A_FLBPOP] = D | A, 371 [V3D_QPU_A_SETMSF] = D | A, 372 [V3D_QPU_A_SETREVF] = D | A, 373 [V3D_QPU_A_NOP] = 0, 374 [V3D_QPU_A_TIDX] = D, 375 [V3D_QPU_A_EIDX] = D, 376 [V3D_QPU_A_LR] = D, 377 [V3D_QPU_A_VFLA] = D, 378 [V3D_QPU_A_VFLNA] = D, 379 [V3D_QPU_A_VFLB] = D, 380 [V3D_QPU_A_VFLNB] = D, 381 382 [V3D_QPU_A_FXCD] = D, 383 [V3D_QPU_A_XCD] = D, 384 [V3D_QPU_A_FYCD] = D, 385 [V3D_QPU_A_YCD] = D, 386 387 [V3D_QPU_A_MSF] = D, 388 [V3D_QPU_A_REVF] = D, 389 [V3D_QPU_A_VDWWT] = D, 390 [V3D_QPU_A_IID] = D, 391 [V3D_QPU_A_SAMPID] = D, 392 [V3D_QPU_A_PATCHID] = D, 393 [V3D_QPU_A_TMUWT] = D, 394 [V3D_QPU_A_VPMWT] = D, 395 396 [V3D_QPU_A_VPMSETUP] = D | A, 397 398 [V3D_QPU_A_LDVPMV_IN] = D | A, 399 [V3D_QPU_A_LDVPMV_OUT] = D | A, 400 [V3D_QPU_A_LDVPMD_IN] = D | A, 401 [V3D_QPU_A_LDVPMD_OUT] = D | A, 402 [V3D_QPU_A_LDVPMP] = D | A, 403 [V3D_QPU_A_LDVPMG_IN] = D | A | B, 404 [V3D_QPU_A_LDVPMG_OUT] = D | A | B, 405 406 /* FIXME: MOVABSNEG */ 407 408 [V3D_QPU_A_FCMP] = D | A | B, 409 [V3D_QPU_A_VFMAX] = D | A | B, 410 411 [V3D_QPU_A_FROUND] = D | A, 412 [V3D_QPU_A_FTOIN] = D | A, 413 [V3D_QPU_A_FTRUNC] = D | A, 414 [V3D_QPU_A_FTOIZ] = D | A, 415 [V3D_QPU_A_FFLOOR] = D | A, 416 [V3D_QPU_A_FTOUZ] = D | A, 417 [V3D_QPU_A_FCEIL] = D | A, 418 [V3D_QPU_A_FTOC] = D | A, 419 420 [V3D_QPU_A_FDX] = D | A, 421 [V3D_QPU_A_FDY] = D | A, 422 423 [V3D_QPU_A_STVPMV] = A | B, 424 [V3D_QPU_A_STVPMD] = A | B, 425 [V3D_QPU_A_STVPMP] = A | B, 426 427 [V3D_QPU_A_ITOF] = D | A, 428 [V3D_QPU_A_CLZ] = D | A, 429 [V3D_QPU_A_UTOF] = D | A, 430 }; 431 432 static const uint8_t mul_op_args[] = { 433 [V3D_QPU_M_ADD] = D | A | B, 434 [V3D_QPU_M_SUB] = D | A | B, 435 [V3D_QPU_M_UMUL24] = D | A | B, 436 [V3D_QPU_M_VFMUL] = D | A | B, 437 [V3D_QPU_M_SMUL24] = D | A | B, 438 [V3D_QPU_M_MULTOP] = D | A | B, 439 [V3D_QPU_M_FMOV] = D | A, 440 [V3D_QPU_M_NOP] = 0, 441 [V3D_QPU_M_MOV] = D | A, 442 [V3D_QPU_M_FMUL] = D | A | B, 443 }; 444 445 bool 446 v3d_qpu_add_op_has_dst(enum v3d_qpu_add_op op) 447 { 448 assert(op < ARRAY_SIZE(add_op_args)); 449 450 return add_op_args[op] & D; 451 } 452 453 bool 454 v3d_qpu_mul_op_has_dst(enum v3d_qpu_mul_op op) 455 { 456 assert(op < ARRAY_SIZE(mul_op_args)); 457 458 return mul_op_args[op] & D; 459 } 460 461 int 462 v3d_qpu_add_op_num_src(enum v3d_qpu_add_op op) 463 { 464 assert(op < ARRAY_SIZE(add_op_args)); 465 466 uint8_t args = add_op_args[op]; 467 if (args & B) 468 return 2; 469 else if (args & A) 470 return 1; 471 else 472 return 0; 473 } 474 475 int 476 v3d_qpu_mul_op_num_src(enum v3d_qpu_mul_op op) 477 { 478 assert(op < ARRAY_SIZE(mul_op_args)); 479 480 uint8_t args = mul_op_args[op]; 481 if (args & B) 482 return 2; 483 else if (args & A) 484 return 1; 485 else 486 return 0; 487 } 488 489 bool 490 v3d_qpu_magic_waddr_is_sfu(enum v3d_qpu_waddr waddr) 491 { 492 switch (waddr) { 493 case V3D_QPU_WADDR_RECIP: 494 case V3D_QPU_WADDR_RSQRT: 495 case V3D_QPU_WADDR_EXP: 496 case V3D_QPU_WADDR_LOG: 497 case V3D_QPU_WADDR_SIN: 498 case V3D_QPU_WADDR_RSQRT2: 499 return true; 500 default: 501 return false; 502 } 503 } 504 505 bool 506 v3d_qpu_magic_waddr_is_tmu(enum v3d_qpu_waddr waddr) 507 { 508 /* XXX: WADDR_TMU changed to UNIFA on 4.x */ 509 return ((waddr >= V3D_QPU_WADDR_TMU && 510 waddr <= V3D_QPU_WADDR_TMUAU) || 511 (waddr >= V3D_QPU_WADDR_TMUC && 512 waddr <= V3D_QPU_WADDR_TMUHSLOD)); 513 } 514 515 bool 516 v3d_qpu_magic_waddr_is_tlb(enum v3d_qpu_waddr waddr) 517 { 518 return (waddr == V3D_QPU_WADDR_TLB || 519 waddr == V3D_QPU_WADDR_TLBU); 520 } 521 522 bool 523 v3d_qpu_magic_waddr_is_vpm(enum v3d_qpu_waddr waddr) 524 { 525 return (waddr == V3D_QPU_WADDR_VPM || 526 waddr == V3D_QPU_WADDR_VPMU); 527 } 528 529 bool 530 v3d_qpu_magic_waddr_is_tsy(enum v3d_qpu_waddr waddr) 531 { 532 return (waddr == V3D_QPU_WADDR_SYNC || 533 waddr == V3D_QPU_WADDR_SYNCU); 534 } 535 536 static bool 537 v3d_qpu_add_op_uses_vpm(enum v3d_qpu_add_op op) 538 { 539 switch (op) { 540 case V3D_QPU_A_VPMSETUP: 541 case V3D_QPU_A_VPMWT: 542 case V3D_QPU_A_LDVPMV_IN: 543 case V3D_QPU_A_LDVPMV_OUT: 544 case V3D_QPU_A_LDVPMD_IN: 545 case V3D_QPU_A_LDVPMD_OUT: 546 case V3D_QPU_A_LDVPMP: 547 case V3D_QPU_A_LDVPMG_IN: 548 case V3D_QPU_A_LDVPMG_OUT: 549 case V3D_QPU_A_STVPMV: 550 case V3D_QPU_A_STVPMD: 551 case V3D_QPU_A_STVPMP: 552 return true; 553 default: 554 return false; 555 } 556 } 557 558 bool 559 v3d_qpu_uses_vpm(const struct v3d_qpu_instr *inst) 560 { 561 if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { 562 if (v3d_qpu_add_op_uses_vpm(inst->alu.add.op)) 563 return true; 564 565 if (inst->alu.add.magic_write && 566 v3d_qpu_magic_waddr_is_vpm(inst->alu.add.waddr)) { 567 return true; 568 } 569 570 if (inst->alu.mul.magic_write && 571 v3d_qpu_magic_waddr_is_vpm(inst->alu.mul.waddr)) { 572 return true; 573 } 574 } 575 576 return false; 577 } 578 579 bool 580 v3d_qpu_writes_r3(const struct v3d_device_info *devinfo, 581 const struct v3d_qpu_instr *inst) 582 { 583 if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { 584 if (inst->alu.add.magic_write && 585 inst->alu.add.waddr == V3D_QPU_WADDR_R3) { 586 return true; 587 } 588 589 if (inst->alu.mul.magic_write && 590 inst->alu.mul.waddr == V3D_QPU_WADDR_R3) { 591 return true; 592 } 593 } 594 595 if (v3d_qpu_sig_writes_address(devinfo, &inst->sig) && 596 inst->sig_magic && inst->sig_addr == V3D_QPU_WADDR_R3) { 597 return true; 598 } 599 600 return inst->sig.ldvary || inst->sig.ldvpm; 601 } 602 603 bool 604 v3d_qpu_writes_r4(const struct v3d_device_info *devinfo, 605 const struct v3d_qpu_instr *inst) 606 { 607 if (inst->sig.ldtmu) 608 return true; 609 610 if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { 611 if (inst->alu.add.magic_write && 612 (inst->alu.add.waddr == V3D_QPU_WADDR_R4 || 613 v3d_qpu_magic_waddr_is_sfu(inst->alu.add.waddr))) { 614 return true; 615 } 616 617 if (inst->alu.mul.magic_write && 618 (inst->alu.mul.waddr == V3D_QPU_WADDR_R4 || 619 v3d_qpu_magic_waddr_is_sfu(inst->alu.mul.waddr))) { 620 return true; 621 } 622 } 623 624 if (v3d_qpu_sig_writes_address(devinfo, &inst->sig) && 625 inst->sig_magic && inst->sig_addr == V3D_QPU_WADDR_R4) { 626 return true; 627 } 628 629 return false; 630 } 631 632 bool 633 v3d_qpu_writes_r5(const struct v3d_device_info *devinfo, 634 const struct v3d_qpu_instr *inst) 635 { 636 if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { 637 if (inst->alu.add.magic_write && 638 inst->alu.add.waddr == V3D_QPU_WADDR_R5) { 639 return true; 640 } 641 642 if (inst->alu.mul.magic_write && 643 inst->alu.mul.waddr == V3D_QPU_WADDR_R5) { 644 return true; 645 } 646 } 647 648 if (v3d_qpu_sig_writes_address(devinfo, &inst->sig) && 649 inst->sig_magic && inst->sig_addr == V3D_QPU_WADDR_R5) { 650 return true; 651 } 652 653 return inst->sig.ldvary || inst->sig.ldunif || inst->sig.ldunifa; 654 } 655 656 bool 657 v3d_qpu_uses_mux(const struct v3d_qpu_instr *inst, enum v3d_qpu_mux mux) 658 { 659 int add_nsrc = v3d_qpu_add_op_num_src(inst->alu.add.op); 660 int mul_nsrc = v3d_qpu_mul_op_num_src(inst->alu.mul.op); 661 662 return ((add_nsrc > 0 && inst->alu.add.a == mux) || 663 (add_nsrc > 1 && inst->alu.add.b == mux) || 664 (mul_nsrc > 0 && inst->alu.mul.a == mux) || 665 (mul_nsrc > 1 && inst->alu.mul.b == mux)); 666 } 667 668 bool 669 v3d_qpu_sig_writes_address(const struct v3d_device_info *devinfo, 670 const struct v3d_qpu_sig *sig) 671 { 672 if (devinfo->ver < 41) 673 return false; 674 675 return (sig->ldunifrf || 676 sig->ldunifarf || 677 sig->ldvary || 678 sig->ldtmu || 679 sig->ldtlb || 680 sig->ldtlbu); 681 } 682