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