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