Home | History | Annotate | Download | only in qpu
      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 }
    682