broadcom/vc5: Add the new TMU write addresses for V3D 4.x (and r5rep).
[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 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 }