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 /**
     25  * @file qpu_instr.h
     26  *
     27  * Definitions of the unpacked form of QPU instructions.  Assembly and
     28  * disassembly will use this for talking about instructions, with qpu_encode.c
     29  * and qpu_decode.c handling the pack and unpack of the actual 64-bit QPU
     30  * instruction.
     31  */
     32 
     33 #ifndef QPU_INSTR_H
     34 #define QPU_INSTR_H
     35 
     36 #include <stdbool.h>
     37 #include <stdint.h>
     38 #include "util/macros.h"
     39 
     40 struct v3d_device_info;
     41 
     42 struct v3d_qpu_sig {
     43         bool thrsw:1;
     44         bool ldunif:1;
     45         bool ldunifa:1;
     46         bool ldunifrf:1;
     47         bool ldunifarf:1;
     48         bool ldtmu:1;
     49         bool ldvary:1;
     50         bool ldvpm:1;
     51         bool ldtlb:1;
     52         bool ldtlbu:1;
     53         bool small_imm:1;
     54         bool ucb:1;
     55         bool rotate:1;
     56         bool wrtmuc:1;
     57 };
     58 
     59 enum v3d_qpu_cond {
     60         V3D_QPU_COND_NONE,
     61         V3D_QPU_COND_IFA,
     62         V3D_QPU_COND_IFB,
     63         V3D_QPU_COND_IFNA,
     64         V3D_QPU_COND_IFNB,
     65 };
     66 
     67 enum v3d_qpu_pf {
     68         V3D_QPU_PF_NONE,
     69         V3D_QPU_PF_PUSHZ,
     70         V3D_QPU_PF_PUSHN,
     71         V3D_QPU_PF_PUSHC,
     72 };
     73 
     74 enum v3d_qpu_uf {
     75         V3D_QPU_UF_NONE,
     76         V3D_QPU_UF_ANDZ,
     77         V3D_QPU_UF_ANDNZ,
     78         V3D_QPU_UF_NORNZ,
     79         V3D_QPU_UF_NORZ,
     80         V3D_QPU_UF_ANDN,
     81         V3D_QPU_UF_ANDNN,
     82         V3D_QPU_UF_NORNN,
     83         V3D_QPU_UF_NORN,
     84         V3D_QPU_UF_ANDC,
     85         V3D_QPU_UF_ANDNC,
     86         V3D_QPU_UF_NORNC,
     87         V3D_QPU_UF_NORC,
     88 };
     89 
     90 enum v3d_qpu_waddr {
     91         V3D_QPU_WADDR_R0 = 0,
     92         V3D_QPU_WADDR_R1 = 1,
     93         V3D_QPU_WADDR_R2 = 2,
     94         V3D_QPU_WADDR_R3 = 3,
     95         V3D_QPU_WADDR_R4 = 4,
     96         V3D_QPU_WADDR_R5 = 5,
     97         /* 6 is reserved, but note 3.2.2.8: "Result Writes" */
     98         V3D_QPU_WADDR_NOP = 6,
     99         V3D_QPU_WADDR_TLB = 7,
    100         V3D_QPU_WADDR_TLBU = 8,
    101         V3D_QPU_WADDR_TMU = 9,
    102         V3D_QPU_WADDR_TMUL = 10,
    103         V3D_QPU_WADDR_TMUD = 11,
    104         V3D_QPU_WADDR_TMUA = 12,
    105         V3D_QPU_WADDR_TMUAU = 13,
    106         V3D_QPU_WADDR_VPM = 14,
    107         V3D_QPU_WADDR_VPMU = 15,
    108         V3D_QPU_WADDR_SYNC = 16,
    109         V3D_QPU_WADDR_SYNCU = 17,
    110         /* reserved */
    111         V3D_QPU_WADDR_RECIP = 19,
    112         V3D_QPU_WADDR_RSQRT = 20,
    113         V3D_QPU_WADDR_EXP = 21,
    114         V3D_QPU_WADDR_LOG = 22,
    115         V3D_QPU_WADDR_SIN = 23,
    116         V3D_QPU_WADDR_RSQRT2 = 24,
    117         V3D_QPU_WADDR_TMUC = 32,
    118         V3D_QPU_WADDR_TMUS = 33,
    119         V3D_QPU_WADDR_TMUT = 34,
    120         V3D_QPU_WADDR_TMUR = 35,
    121         V3D_QPU_WADDR_TMUI = 36,
    122         V3D_QPU_WADDR_TMUB = 37,
    123         V3D_QPU_WADDR_TMUDREF = 38,
    124         V3D_QPU_WADDR_TMUOFF = 39,
    125         V3D_QPU_WADDR_TMUSCM = 40,
    126         V3D_QPU_WADDR_TMUSF = 41,
    127         V3D_QPU_WADDR_TMUSLOD = 42,
    128         V3D_QPU_WADDR_TMUHS = 43,
    129         V3D_QPU_WADDR_TMUHSCM = 44,
    130         V3D_QPU_WADDR_TMUHSF = 45,
    131         V3D_QPU_WADDR_TMUHSLOD = 46,
    132         V3D_QPU_WADDR_R5REP = 55,
    133 };
    134 
    135 struct v3d_qpu_flags {
    136         enum v3d_qpu_cond ac, mc;
    137         enum v3d_qpu_pf apf, mpf;
    138         enum v3d_qpu_uf auf, muf;
    139 };
    140 
    141 enum v3d_qpu_add_op {
    142         V3D_QPU_A_FADD,
    143         V3D_QPU_A_FADDNF,
    144         V3D_QPU_A_VFPACK,
    145         V3D_QPU_A_ADD,
    146         V3D_QPU_A_SUB,
    147         V3D_QPU_A_FSUB,
    148         V3D_QPU_A_MIN,
    149         V3D_QPU_A_MAX,
    150         V3D_QPU_A_UMIN,
    151         V3D_QPU_A_UMAX,
    152         V3D_QPU_A_SHL,
    153         V3D_QPU_A_SHR,
    154         V3D_QPU_A_ASR,
    155         V3D_QPU_A_ROR,
    156         V3D_QPU_A_FMIN,
    157         V3D_QPU_A_FMAX,
    158         V3D_QPU_A_VFMIN,
    159         V3D_QPU_A_AND,
    160         V3D_QPU_A_OR,
    161         V3D_QPU_A_XOR,
    162         V3D_QPU_A_VADD,
    163         V3D_QPU_A_VSUB,
    164         V3D_QPU_A_NOT,
    165         V3D_QPU_A_NEG,
    166         V3D_QPU_A_FLAPUSH,
    167         V3D_QPU_A_FLBPUSH,
    168         V3D_QPU_A_FLBPOP,
    169         V3D_QPU_A_SETMSF,
    170         V3D_QPU_A_SETREVF,
    171         V3D_QPU_A_NOP,
    172         V3D_QPU_A_TIDX,
    173         V3D_QPU_A_EIDX,
    174         V3D_QPU_A_LR,
    175         V3D_QPU_A_VFLA,
    176         V3D_QPU_A_VFLNA,
    177         V3D_QPU_A_VFLB,
    178         V3D_QPU_A_VFLNB,
    179         V3D_QPU_A_FXCD,
    180         V3D_QPU_A_XCD,
    181         V3D_QPU_A_FYCD,
    182         V3D_QPU_A_YCD,
    183         V3D_QPU_A_MSF,
    184         V3D_QPU_A_REVF,
    185         V3D_QPU_A_VDWWT,
    186         V3D_QPU_A_IID,
    187         V3D_QPU_A_SAMPID,
    188         V3D_QPU_A_PATCHID,
    189         V3D_QPU_A_TMUWT,
    190         V3D_QPU_A_VPMSETUP,
    191         V3D_QPU_A_VPMWT,
    192         V3D_QPU_A_LDVPMV_IN,
    193         V3D_QPU_A_LDVPMV_OUT,
    194         V3D_QPU_A_LDVPMD_IN,
    195         V3D_QPU_A_LDVPMD_OUT,
    196         V3D_QPU_A_LDVPMP,
    197         V3D_QPU_A_LDVPMG_IN,
    198         V3D_QPU_A_LDVPMG_OUT,
    199         V3D_QPU_A_FCMP,
    200         V3D_QPU_A_VFMAX,
    201         V3D_QPU_A_FROUND,
    202         V3D_QPU_A_FTOIN,
    203         V3D_QPU_A_FTRUNC,
    204         V3D_QPU_A_FTOIZ,
    205         V3D_QPU_A_FFLOOR,
    206         V3D_QPU_A_FTOUZ,
    207         V3D_QPU_A_FCEIL,
    208         V3D_QPU_A_FTOC,
    209         V3D_QPU_A_FDX,
    210         V3D_QPU_A_FDY,
    211         V3D_QPU_A_STVPMV,
    212         V3D_QPU_A_STVPMD,
    213         V3D_QPU_A_STVPMP,
    214         V3D_QPU_A_ITOF,
    215         V3D_QPU_A_CLZ,
    216         V3D_QPU_A_UTOF,
    217 };
    218 
    219 enum v3d_qpu_mul_op {
    220         V3D_QPU_M_ADD,
    221         V3D_QPU_M_SUB,
    222         V3D_QPU_M_UMUL24,
    223         V3D_QPU_M_VFMUL,
    224         V3D_QPU_M_SMUL24,
    225         V3D_QPU_M_MULTOP,
    226         V3D_QPU_M_FMOV,
    227         V3D_QPU_M_MOV,
    228         V3D_QPU_M_NOP,
    229         V3D_QPU_M_FMUL,
    230 };
    231 
    232 enum v3d_qpu_output_pack {
    233         V3D_QPU_PACK_NONE,
    234         /**
    235          * Convert to 16-bit float, put in low 16 bits of destination leaving
    236          * high unmodified.
    237          */
    238         V3D_QPU_PACK_L,
    239         /**
    240          * Convert to 16-bit float, put in high 16 bits of destination leaving
    241          * low unmodified.
    242          */
    243         V3D_QPU_PACK_H,
    244 };
    245 
    246 enum v3d_qpu_input_unpack {
    247         /**
    248          * No-op input unpacking.  Note that this enum's value doesn't match
    249          * the packed QPU instruction value of the field (we use 0 so that the
    250          * default on new instruction creation is no-op).
    251          */
    252         V3D_QPU_UNPACK_NONE,
    253         /** Absolute value.  Only available for some operations. */
    254         V3D_QPU_UNPACK_ABS,
    255         /** Convert low 16 bits from 16-bit float to 32-bit float. */
    256         V3D_QPU_UNPACK_L,
    257         /** Convert high 16 bits from 16-bit float to 32-bit float. */
    258         V3D_QPU_UNPACK_H,
    259 
    260         /** Convert to 16f and replicate it to the high bits. */
    261         V3D_QPU_UNPACK_REPLICATE_32F_16,
    262 
    263         /** Replicate low 16 bits to high */
    264         V3D_QPU_UNPACK_REPLICATE_L_16,
    265 
    266         /** Replicate high 16 bits to low */
    267         V3D_QPU_UNPACK_REPLICATE_H_16,
    268 
    269         /** Swap high and low 16 bits */
    270         V3D_QPU_UNPACK_SWAP_16,
    271 };
    272 
    273 enum v3d_qpu_mux {
    274         V3D_QPU_MUX_R0,
    275         V3D_QPU_MUX_R1,
    276         V3D_QPU_MUX_R2,
    277         V3D_QPU_MUX_R3,
    278         V3D_QPU_MUX_R4,
    279         V3D_QPU_MUX_R5,
    280         V3D_QPU_MUX_A,
    281         V3D_QPU_MUX_B,
    282 };
    283 
    284 struct v3d_qpu_alu_instr {
    285         struct {
    286                 enum v3d_qpu_add_op op;
    287                 enum v3d_qpu_mux a, b;
    288                 uint8_t waddr;
    289                 bool magic_write;
    290                 enum v3d_qpu_output_pack output_pack;
    291                 enum v3d_qpu_input_unpack a_unpack;
    292                 enum v3d_qpu_input_unpack b_unpack;
    293         } add;
    294 
    295         struct {
    296                 enum v3d_qpu_mul_op op;
    297                 enum v3d_qpu_mux a, b;
    298                 uint8_t waddr;
    299                 bool magic_write;
    300                 enum v3d_qpu_output_pack output_pack;
    301                 enum v3d_qpu_input_unpack a_unpack;
    302                 enum v3d_qpu_input_unpack b_unpack;
    303         } mul;
    304 };
    305 
    306 enum v3d_qpu_branch_cond {
    307         V3D_QPU_BRANCH_COND_ALWAYS,
    308         V3D_QPU_BRANCH_COND_A0,
    309         V3D_QPU_BRANCH_COND_NA0,
    310         V3D_QPU_BRANCH_COND_ALLA,
    311         V3D_QPU_BRANCH_COND_ANYNA,
    312         V3D_QPU_BRANCH_COND_ANYA,
    313         V3D_QPU_BRANCH_COND_ALLNA,
    314 };
    315 
    316 enum v3d_qpu_msfign {
    317         /** Ignore multisample flags when determining branch condition. */
    318         V3D_QPU_MSFIGN_NONE,
    319         /**
    320          * If no multisample flags are set in the lane (a pixel in the FS, a
    321          * vertex in the VS), ignore the lane's condition when computing the
    322          * branch condition.
    323          */
    324         V3D_QPU_MSFIGN_P,
    325         /**
    326          * If no multisample flags are set in a 2x2 quad in the FS, ignore the
    327          * quad's a/b conditions.
    328          */
    329         V3D_QPU_MSFIGN_Q,
    330 };
    331 
    332 enum v3d_qpu_branch_dest {
    333         V3D_QPU_BRANCH_DEST_ABS,
    334         V3D_QPU_BRANCH_DEST_REL,
    335         V3D_QPU_BRANCH_DEST_LINK_REG,
    336         V3D_QPU_BRANCH_DEST_REGFILE,
    337 };
    338 
    339 struct v3d_qpu_branch_instr {
    340         enum v3d_qpu_branch_cond cond;
    341         enum v3d_qpu_msfign msfign;
    342 
    343         /** Selects how to compute the new IP if the branch is taken. */
    344         enum v3d_qpu_branch_dest bdi;
    345 
    346         /**
    347          * Selects how to compute the new uniforms pointer if the branch is
    348          * taken.  (ABS/REL implicitly load a uniform and use that)
    349          */
    350         enum v3d_qpu_branch_dest bdu;
    351 
    352         /**
    353          * If set, then udest determines how the uniform stream will branch,
    354          * otherwise the uniform stream is left as is.
    355          */
    356         bool ub;
    357 
    358         uint8_t raddr_a;
    359 
    360         uint32_t offset;
    361 };
    362 
    363 enum v3d_qpu_instr_type {
    364         V3D_QPU_INSTR_TYPE_ALU,
    365         V3D_QPU_INSTR_TYPE_BRANCH,
    366 };
    367 
    368 struct v3d_qpu_instr {
    369         enum v3d_qpu_instr_type type;
    370 
    371         struct v3d_qpu_sig sig;
    372         uint8_t sig_addr;
    373         bool sig_magic; /* If the signal writes to a magic address */
    374         uint8_t raddr_a;
    375         uint8_t raddr_b;
    376         struct v3d_qpu_flags flags;
    377 
    378         union {
    379                 struct v3d_qpu_alu_instr alu;
    380                 struct v3d_qpu_branch_instr branch;
    381         };
    382 };
    383 
    384 const char *v3d_qpu_magic_waddr_name(enum v3d_qpu_waddr waddr);
    385 const char *v3d_qpu_add_op_name(enum v3d_qpu_add_op op);
    386 const char *v3d_qpu_mul_op_name(enum v3d_qpu_mul_op op);
    387 const char *v3d_qpu_cond_name(enum v3d_qpu_cond cond);
    388 const char *v3d_qpu_pf_name(enum v3d_qpu_pf pf);
    389 const char *v3d_qpu_uf_name(enum v3d_qpu_uf uf);
    390 const char *v3d_qpu_pack_name(enum v3d_qpu_output_pack pack);
    391 const char *v3d_qpu_unpack_name(enum v3d_qpu_input_unpack unpack);
    392 const char *v3d_qpu_branch_cond_name(enum v3d_qpu_branch_cond cond);
    393 const char *v3d_qpu_msfign_name(enum v3d_qpu_msfign msfign);
    394 
    395 bool v3d_qpu_add_op_has_dst(enum v3d_qpu_add_op op);
    396 bool v3d_qpu_mul_op_has_dst(enum v3d_qpu_mul_op op);
    397 int v3d_qpu_add_op_num_src(enum v3d_qpu_add_op op);
    398 int v3d_qpu_mul_op_num_src(enum v3d_qpu_mul_op op);
    399 
    400 bool v3d_qpu_sig_pack(const struct v3d_device_info *devinfo,
    401                       const struct v3d_qpu_sig *sig,
    402                       uint32_t *packed_sig);
    403 bool v3d_qpu_sig_unpack(const struct v3d_device_info *devinfo,
    404                         uint32_t packed_sig,
    405                         struct v3d_qpu_sig *sig);
    406 
    407 bool
    408 v3d_qpu_flags_pack(const struct v3d_device_info *devinfo,
    409                    const struct v3d_qpu_flags *cond,
    410                    uint32_t *packed_cond);
    411 bool
    412 v3d_qpu_flags_unpack(const struct v3d_device_info *devinfo,
    413                      uint32_t packed_cond,
    414                      struct v3d_qpu_flags *cond);
    415 
    416 bool
    417 v3d_qpu_small_imm_pack(const struct v3d_device_info *devinfo,
    418                        uint32_t value,
    419                        uint32_t *packed_small_immediate);
    420 
    421 bool
    422 v3d_qpu_small_imm_unpack(const struct v3d_device_info *devinfo,
    423                          uint32_t packed_small_immediate,
    424                          uint32_t *small_immediate);
    425 
    426 bool
    427 v3d_qpu_instr_pack(const struct v3d_device_info *devinfo,
    428                    const struct v3d_qpu_instr *instr,
    429                    uint64_t *packed_instr);
    430 bool
    431 v3d_qpu_instr_unpack(const struct v3d_device_info *devinfo,
    432                      uint64_t packed_instr,
    433                      struct v3d_qpu_instr *instr);
    434 
    435 bool v3d_qpu_magic_waddr_is_sfu(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
    436 bool v3d_qpu_magic_waddr_is_tmu(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
    437 bool v3d_qpu_magic_waddr_is_tlb(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
    438 bool v3d_qpu_magic_waddr_is_vpm(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
    439 bool v3d_qpu_magic_waddr_is_tsy(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
    440 bool v3d_qpu_writes_r3(const struct v3d_device_info *devinfo,
    441                        const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST;
    442 bool v3d_qpu_writes_r4(const struct v3d_device_info *devinfo,
    443                        const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST;
    444 bool v3d_qpu_writes_r5(const struct v3d_device_info *devinfo,
    445                        const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST;
    446 bool v3d_qpu_uses_mux(const struct v3d_qpu_instr *inst, enum v3d_qpu_mux mux);
    447 bool v3d_qpu_uses_vpm(const struct v3d_qpu_instr *inst);
    448 bool v3d_qpu_sig_writes_address(const struct v3d_device_info *devinfo,
    449                                 const struct v3d_qpu_sig *sig) ATTRIBUTE_CONST;
    450 
    451 #endif
    452