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 /** 25 * @file qpu_instr.h 26 * 27 * Definitions of the unpacked form of QPU instructions. Assembly and 28 * disassembly will use this for talking about instructions, with qpu_encode.c 29 * and qpu_decode.c handling the pack and unpack of the actual 64-bit QPU 30 * instruction. 31 */ 32 33 #ifndef QPU_INSTR_H 34 #define QPU_INSTR_H 35 36 #include <stdbool.h> 37 #include <stdint.h> 38 #include "util/macros.h" 39 40 struct v3d_device_info; 41 42 struct v3d_qpu_sig { 43 bool thrsw:1; 44 bool ldunif:1; 45 bool ldunifa:1; 46 bool ldunifrf:1; 47 bool ldunifarf:1; 48 bool ldtmu:1; 49 bool ldvary:1; 50 bool ldvpm:1; 51 bool ldtlb:1; 52 bool ldtlbu:1; 53 bool small_imm:1; 54 bool ucb:1; 55 bool rotate:1; 56 bool wrtmuc:1; 57 }; 58 59 enum v3d_qpu_cond { 60 V3D_QPU_COND_NONE, 61 V3D_QPU_COND_IFA, 62 V3D_QPU_COND_IFB, 63 V3D_QPU_COND_IFNA, 64 V3D_QPU_COND_IFNB, 65 }; 66 67 enum v3d_qpu_pf { 68 V3D_QPU_PF_NONE, 69 V3D_QPU_PF_PUSHZ, 70 V3D_QPU_PF_PUSHN, 71 V3D_QPU_PF_PUSHC, 72 }; 73 74 enum v3d_qpu_uf { 75 V3D_QPU_UF_NONE, 76 V3D_QPU_UF_ANDZ, 77 V3D_QPU_UF_ANDNZ, 78 V3D_QPU_UF_NORNZ, 79 V3D_QPU_UF_NORZ, 80 V3D_QPU_UF_ANDN, 81 V3D_QPU_UF_ANDNN, 82 V3D_QPU_UF_NORNN, 83 V3D_QPU_UF_NORN, 84 V3D_QPU_UF_ANDC, 85 V3D_QPU_UF_ANDNC, 86 V3D_QPU_UF_NORNC, 87 V3D_QPU_UF_NORC, 88 }; 89 90 enum v3d_qpu_waddr { 91 V3D_QPU_WADDR_R0 = 0, 92 V3D_QPU_WADDR_R1 = 1, 93 V3D_QPU_WADDR_R2 = 2, 94 V3D_QPU_WADDR_R3 = 3, 95 V3D_QPU_WADDR_R4 = 4, 96 V3D_QPU_WADDR_R5 = 5, 97 /* 6 is reserved, but note 3.2.2.8: "Result Writes" */ 98 V3D_QPU_WADDR_NOP = 6, 99 V3D_QPU_WADDR_TLB = 7, 100 V3D_QPU_WADDR_TLBU = 8, 101 V3D_QPU_WADDR_TMU = 9, 102 V3D_QPU_WADDR_TMUL = 10, 103 V3D_QPU_WADDR_TMUD = 11, 104 V3D_QPU_WADDR_TMUA = 12, 105 V3D_QPU_WADDR_TMUAU = 13, 106 V3D_QPU_WADDR_VPM = 14, 107 V3D_QPU_WADDR_VPMU = 15, 108 V3D_QPU_WADDR_SYNC = 16, 109 V3D_QPU_WADDR_SYNCU = 17, 110 /* reserved */ 111 V3D_QPU_WADDR_RECIP = 19, 112 V3D_QPU_WADDR_RSQRT = 20, 113 V3D_QPU_WADDR_EXP = 21, 114 V3D_QPU_WADDR_LOG = 22, 115 V3D_QPU_WADDR_SIN = 23, 116 V3D_QPU_WADDR_RSQRT2 = 24, 117 V3D_QPU_WADDR_TMUC = 32, 118 V3D_QPU_WADDR_TMUS = 33, 119 V3D_QPU_WADDR_TMUT = 34, 120 V3D_QPU_WADDR_TMUR = 35, 121 V3D_QPU_WADDR_TMUI = 36, 122 V3D_QPU_WADDR_TMUB = 37, 123 V3D_QPU_WADDR_TMUDREF = 38, 124 V3D_QPU_WADDR_TMUOFF = 39, 125 V3D_QPU_WADDR_TMUSCM = 40, 126 V3D_QPU_WADDR_TMUSF = 41, 127 V3D_QPU_WADDR_TMUSLOD = 42, 128 V3D_QPU_WADDR_TMUHS = 43, 129 V3D_QPU_WADDR_TMUHSCM = 44, 130 V3D_QPU_WADDR_TMUHSF = 45, 131 V3D_QPU_WADDR_TMUHSLOD = 46, 132 V3D_QPU_WADDR_R5REP = 55, 133 }; 134 135 struct v3d_qpu_flags { 136 enum v3d_qpu_cond ac, mc; 137 enum v3d_qpu_pf apf, mpf; 138 enum v3d_qpu_uf auf, muf; 139 }; 140 141 enum v3d_qpu_add_op { 142 V3D_QPU_A_FADD, 143 V3D_QPU_A_FADDNF, 144 V3D_QPU_A_VFPACK, 145 V3D_QPU_A_ADD, 146 V3D_QPU_A_SUB, 147 V3D_QPU_A_FSUB, 148 V3D_QPU_A_MIN, 149 V3D_QPU_A_MAX, 150 V3D_QPU_A_UMIN, 151 V3D_QPU_A_UMAX, 152 V3D_QPU_A_SHL, 153 V3D_QPU_A_SHR, 154 V3D_QPU_A_ASR, 155 V3D_QPU_A_ROR, 156 V3D_QPU_A_FMIN, 157 V3D_QPU_A_FMAX, 158 V3D_QPU_A_VFMIN, 159 V3D_QPU_A_AND, 160 V3D_QPU_A_OR, 161 V3D_QPU_A_XOR, 162 V3D_QPU_A_VADD, 163 V3D_QPU_A_VSUB, 164 V3D_QPU_A_NOT, 165 V3D_QPU_A_NEG, 166 V3D_QPU_A_FLAPUSH, 167 V3D_QPU_A_FLBPUSH, 168 V3D_QPU_A_FLBPOP, 169 V3D_QPU_A_SETMSF, 170 V3D_QPU_A_SETREVF, 171 V3D_QPU_A_NOP, 172 V3D_QPU_A_TIDX, 173 V3D_QPU_A_EIDX, 174 V3D_QPU_A_LR, 175 V3D_QPU_A_VFLA, 176 V3D_QPU_A_VFLNA, 177 V3D_QPU_A_VFLB, 178 V3D_QPU_A_VFLNB, 179 V3D_QPU_A_FXCD, 180 V3D_QPU_A_XCD, 181 V3D_QPU_A_FYCD, 182 V3D_QPU_A_YCD, 183 V3D_QPU_A_MSF, 184 V3D_QPU_A_REVF, 185 V3D_QPU_A_VDWWT, 186 V3D_QPU_A_IID, 187 V3D_QPU_A_SAMPID, 188 V3D_QPU_A_PATCHID, 189 V3D_QPU_A_TMUWT, 190 V3D_QPU_A_VPMSETUP, 191 V3D_QPU_A_VPMWT, 192 V3D_QPU_A_LDVPMV_IN, 193 V3D_QPU_A_LDVPMV_OUT, 194 V3D_QPU_A_LDVPMD_IN, 195 V3D_QPU_A_LDVPMD_OUT, 196 V3D_QPU_A_LDVPMP, 197 V3D_QPU_A_LDVPMG_IN, 198 V3D_QPU_A_LDVPMG_OUT, 199 V3D_QPU_A_FCMP, 200 V3D_QPU_A_VFMAX, 201 V3D_QPU_A_FROUND, 202 V3D_QPU_A_FTOIN, 203 V3D_QPU_A_FTRUNC, 204 V3D_QPU_A_FTOIZ, 205 V3D_QPU_A_FFLOOR, 206 V3D_QPU_A_FTOUZ, 207 V3D_QPU_A_FCEIL, 208 V3D_QPU_A_FTOC, 209 V3D_QPU_A_FDX, 210 V3D_QPU_A_FDY, 211 V3D_QPU_A_STVPMV, 212 V3D_QPU_A_STVPMD, 213 V3D_QPU_A_STVPMP, 214 V3D_QPU_A_ITOF, 215 V3D_QPU_A_CLZ, 216 V3D_QPU_A_UTOF, 217 }; 218 219 enum v3d_qpu_mul_op { 220 V3D_QPU_M_ADD, 221 V3D_QPU_M_SUB, 222 V3D_QPU_M_UMUL24, 223 V3D_QPU_M_VFMUL, 224 V3D_QPU_M_SMUL24, 225 V3D_QPU_M_MULTOP, 226 V3D_QPU_M_FMOV, 227 V3D_QPU_M_MOV, 228 V3D_QPU_M_NOP, 229 V3D_QPU_M_FMUL, 230 }; 231 232 enum v3d_qpu_output_pack { 233 V3D_QPU_PACK_NONE, 234 /** 235 * Convert to 16-bit float, put in low 16 bits of destination leaving 236 * high unmodified. 237 */ 238 V3D_QPU_PACK_L, 239 /** 240 * Convert to 16-bit float, put in high 16 bits of destination leaving 241 * low unmodified. 242 */ 243 V3D_QPU_PACK_H, 244 }; 245 246 enum v3d_qpu_input_unpack { 247 /** 248 * No-op input unpacking. Note that this enum's value doesn't match 249 * the packed QPU instruction value of the field (we use 0 so that the 250 * default on new instruction creation is no-op). 251 */ 252 V3D_QPU_UNPACK_NONE, 253 /** Absolute value. Only available for some operations. */ 254 V3D_QPU_UNPACK_ABS, 255 /** Convert low 16 bits from 16-bit float to 32-bit float. */ 256 V3D_QPU_UNPACK_L, 257 /** Convert high 16 bits from 16-bit float to 32-bit float. */ 258 V3D_QPU_UNPACK_H, 259 260 /** Convert to 16f and replicate it to the high bits. */ 261 V3D_QPU_UNPACK_REPLICATE_32F_16, 262 263 /** Replicate low 16 bits to high */ 264 V3D_QPU_UNPACK_REPLICATE_L_16, 265 266 /** Replicate high 16 bits to low */ 267 V3D_QPU_UNPACK_REPLICATE_H_16, 268 269 /** Swap high and low 16 bits */ 270 V3D_QPU_UNPACK_SWAP_16, 271 }; 272 273 enum v3d_qpu_mux { 274 V3D_QPU_MUX_R0, 275 V3D_QPU_MUX_R1, 276 V3D_QPU_MUX_R2, 277 V3D_QPU_MUX_R3, 278 V3D_QPU_MUX_R4, 279 V3D_QPU_MUX_R5, 280 V3D_QPU_MUX_A, 281 V3D_QPU_MUX_B, 282 }; 283 284 struct v3d_qpu_alu_instr { 285 struct { 286 enum v3d_qpu_add_op op; 287 enum v3d_qpu_mux a, b; 288 uint8_t waddr; 289 bool magic_write; 290 enum v3d_qpu_output_pack output_pack; 291 enum v3d_qpu_input_unpack a_unpack; 292 enum v3d_qpu_input_unpack b_unpack; 293 } add; 294 295 struct { 296 enum v3d_qpu_mul_op op; 297 enum v3d_qpu_mux a, b; 298 uint8_t waddr; 299 bool magic_write; 300 enum v3d_qpu_output_pack output_pack; 301 enum v3d_qpu_input_unpack a_unpack; 302 enum v3d_qpu_input_unpack b_unpack; 303 } mul; 304 }; 305 306 enum v3d_qpu_branch_cond { 307 V3D_QPU_BRANCH_COND_ALWAYS, 308 V3D_QPU_BRANCH_COND_A0, 309 V3D_QPU_BRANCH_COND_NA0, 310 V3D_QPU_BRANCH_COND_ALLA, 311 V3D_QPU_BRANCH_COND_ANYNA, 312 V3D_QPU_BRANCH_COND_ANYA, 313 V3D_QPU_BRANCH_COND_ALLNA, 314 }; 315 316 enum v3d_qpu_msfign { 317 /** Ignore multisample flags when determining branch condition. */ 318 V3D_QPU_MSFIGN_NONE, 319 /** 320 * If no multisample flags are set in the lane (a pixel in the FS, a 321 * vertex in the VS), ignore the lane's condition when computing the 322 * branch condition. 323 */ 324 V3D_QPU_MSFIGN_P, 325 /** 326 * If no multisample flags are set in a 2x2 quad in the FS, ignore the 327 * quad's a/b conditions. 328 */ 329 V3D_QPU_MSFIGN_Q, 330 }; 331 332 enum v3d_qpu_branch_dest { 333 V3D_QPU_BRANCH_DEST_ABS, 334 V3D_QPU_BRANCH_DEST_REL, 335 V3D_QPU_BRANCH_DEST_LINK_REG, 336 V3D_QPU_BRANCH_DEST_REGFILE, 337 }; 338 339 struct v3d_qpu_branch_instr { 340 enum v3d_qpu_branch_cond cond; 341 enum v3d_qpu_msfign msfign; 342 343 /** Selects how to compute the new IP if the branch is taken. */ 344 enum v3d_qpu_branch_dest bdi; 345 346 /** 347 * Selects how to compute the new uniforms pointer if the branch is 348 * taken. (ABS/REL implicitly load a uniform and use that) 349 */ 350 enum v3d_qpu_branch_dest bdu; 351 352 /** 353 * If set, then udest determines how the uniform stream will branch, 354 * otherwise the uniform stream is left as is. 355 */ 356 bool ub; 357 358 uint8_t raddr_a; 359 360 uint32_t offset; 361 }; 362 363 enum v3d_qpu_instr_type { 364 V3D_QPU_INSTR_TYPE_ALU, 365 V3D_QPU_INSTR_TYPE_BRANCH, 366 }; 367 368 struct v3d_qpu_instr { 369 enum v3d_qpu_instr_type type; 370 371 struct v3d_qpu_sig sig; 372 uint8_t sig_addr; 373 bool sig_magic; /* If the signal writes to a magic address */ 374 uint8_t raddr_a; 375 uint8_t raddr_b; 376 struct v3d_qpu_flags flags; 377 378 union { 379 struct v3d_qpu_alu_instr alu; 380 struct v3d_qpu_branch_instr branch; 381 }; 382 }; 383 384 const char *v3d_qpu_magic_waddr_name(enum v3d_qpu_waddr waddr); 385 const char *v3d_qpu_add_op_name(enum v3d_qpu_add_op op); 386 const char *v3d_qpu_mul_op_name(enum v3d_qpu_mul_op op); 387 const char *v3d_qpu_cond_name(enum v3d_qpu_cond cond); 388 const char *v3d_qpu_pf_name(enum v3d_qpu_pf pf); 389 const char *v3d_qpu_uf_name(enum v3d_qpu_uf uf); 390 const char *v3d_qpu_pack_name(enum v3d_qpu_output_pack pack); 391 const char *v3d_qpu_unpack_name(enum v3d_qpu_input_unpack unpack); 392 const char *v3d_qpu_branch_cond_name(enum v3d_qpu_branch_cond cond); 393 const char *v3d_qpu_msfign_name(enum v3d_qpu_msfign msfign); 394 395 bool v3d_qpu_add_op_has_dst(enum v3d_qpu_add_op op); 396 bool v3d_qpu_mul_op_has_dst(enum v3d_qpu_mul_op op); 397 int v3d_qpu_add_op_num_src(enum v3d_qpu_add_op op); 398 int v3d_qpu_mul_op_num_src(enum v3d_qpu_mul_op op); 399 400 bool v3d_qpu_sig_pack(const struct v3d_device_info *devinfo, 401 const struct v3d_qpu_sig *sig, 402 uint32_t *packed_sig); 403 bool v3d_qpu_sig_unpack(const struct v3d_device_info *devinfo, 404 uint32_t packed_sig, 405 struct v3d_qpu_sig *sig); 406 407 bool 408 v3d_qpu_flags_pack(const struct v3d_device_info *devinfo, 409 const struct v3d_qpu_flags *cond, 410 uint32_t *packed_cond); 411 bool 412 v3d_qpu_flags_unpack(const struct v3d_device_info *devinfo, 413 uint32_t packed_cond, 414 struct v3d_qpu_flags *cond); 415 416 bool 417 v3d_qpu_small_imm_pack(const struct v3d_device_info *devinfo, 418 uint32_t value, 419 uint32_t *packed_small_immediate); 420 421 bool 422 v3d_qpu_small_imm_unpack(const struct v3d_device_info *devinfo, 423 uint32_t packed_small_immediate, 424 uint32_t *small_immediate); 425 426 bool 427 v3d_qpu_instr_pack(const struct v3d_device_info *devinfo, 428 const struct v3d_qpu_instr *instr, 429 uint64_t *packed_instr); 430 bool 431 v3d_qpu_instr_unpack(const struct v3d_device_info *devinfo, 432 uint64_t packed_instr, 433 struct v3d_qpu_instr *instr); 434 435 bool v3d_qpu_magic_waddr_is_sfu(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST; 436 bool v3d_qpu_magic_waddr_is_tmu(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST; 437 bool v3d_qpu_magic_waddr_is_tlb(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST; 438 bool v3d_qpu_magic_waddr_is_vpm(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST; 439 bool v3d_qpu_magic_waddr_is_tsy(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST; 440 bool v3d_qpu_writes_r3(const struct v3d_device_info *devinfo, 441 const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; 442 bool v3d_qpu_writes_r4(const struct v3d_device_info *devinfo, 443 const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; 444 bool v3d_qpu_writes_r5(const struct v3d_device_info *devinfo, 445 const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; 446 bool v3d_qpu_uses_mux(const struct v3d_qpu_instr *inst, enum v3d_qpu_mux mux); 447 bool v3d_qpu_uses_vpm(const struct v3d_qpu_instr *inst); 448 bool v3d_qpu_sig_writes_address(const struct v3d_device_info *devinfo, 449 const struct v3d_qpu_sig *sig) ATTRIBUTE_CONST; 450 451 #endif 452