• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *
v3d_qpu_magic_waddr_name(enum v3d_qpu_waddr waddr)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 *
v3d_qpu_add_op_name(enum v3d_qpu_add_op op)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 *
v3d_qpu_mul_op_name(enum v3d_qpu_mul_op op)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 *
v3d_qpu_cond_name(enum v3d_qpu_cond cond)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 *
v3d_qpu_branch_cond_name(enum v3d_qpu_branch_cond cond)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 *
v3d_qpu_msfign_name(enum v3d_qpu_msfign msfign)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 *
v3d_qpu_pf_name(enum v3d_qpu_pf pf)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 *
v3d_qpu_uf_name(enum v3d_qpu_uf uf)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 *
v3d_qpu_pack_name(enum v3d_qpu_output_pack pack)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 *
v3d_qpu_unpack_name(enum v3d_qpu_input_unpack unpack)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
v3d_qpu_add_op_has_dst(enum v3d_qpu_add_op op)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
v3d_qpu_mul_op_has_dst(enum v3d_qpu_mul_op op)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
v3d_qpu_add_op_num_src(enum v3d_qpu_add_op op)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
v3d_qpu_mul_op_num_src(enum v3d_qpu_mul_op op)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
v3d_qpu_magic_waddr_is_sfu(enum v3d_qpu_waddr waddr)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
v3d_qpu_magic_waddr_is_tmu(enum v3d_qpu_waddr waddr)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
v3d_qpu_magic_waddr_is_tlb(enum v3d_qpu_waddr waddr)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
v3d_qpu_magic_waddr_is_vpm(enum v3d_qpu_waddr waddr)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
v3d_qpu_magic_waddr_is_tsy(enum v3d_qpu_waddr waddr)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
v3d_qpu_add_op_uses_vpm(enum v3d_qpu_add_op op)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
v3d_qpu_uses_vpm(const struct v3d_qpu_instr * inst)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
v3d_qpu_writes_r3(const struct v3d_device_info * devinfo,const struct v3d_qpu_instr * inst)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
v3d_qpu_writes_r4(const struct v3d_device_info * devinfo,const struct v3d_qpu_instr * inst)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
v3d_qpu_writes_r5(const struct v3d_device_info * devinfo,const struct v3d_qpu_instr * inst)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
v3d_qpu_uses_mux(const struct v3d_qpu_instr * inst,enum v3d_qpu_mux mux)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
v3d_qpu_sig_writes_address(const struct v3d_device_info * devinfo,const struct v3d_qpu_sig * sig)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