Home | History | Annotate | Download | only in shader
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 2012-2013 LunarG, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Chia-I Wu <olv (at) lunarg.com>
     26  */
     27 
     28 #ifndef TOY_COMPILER_H
     29 #define TOY_COMPILER_H
     30 
     31 #include "genhw/genhw.h"
     32 #include "util/slab.h"
     33 
     34 #include "ilo_common.h"
     35 #include "toy_compiler_reg.h"
     36 
     37 /**
     38  * Toy opcodes.
     39  */
     40 enum toy_opcode {
     41    /* 0..127 are reserved for GEN6_OPCODE_x */
     42    TOY_OPCODE_LAST_HW = 127,
     43 
     44    TOY_OPCODE_DO,
     45 
     46    /* TGSI register functions */
     47    TOY_OPCODE_TGSI_IN,
     48    TOY_OPCODE_TGSI_CONST,
     49    TOY_OPCODE_TGSI_SV,
     50    TOY_OPCODE_TGSI_IMM,
     51    TOY_OPCODE_TGSI_INDIRECT_FETCH,
     52    TOY_OPCODE_TGSI_INDIRECT_STORE,
     53 
     54    /* TGSI sampling functions */
     55    TOY_OPCODE_TGSI_TEX,
     56    TOY_OPCODE_TGSI_TXB,
     57    TOY_OPCODE_TGSI_TXD,
     58    TOY_OPCODE_TGSI_TXL,
     59    TOY_OPCODE_TGSI_TXP,
     60    TOY_OPCODE_TGSI_TXF,
     61    TOY_OPCODE_TGSI_TXQ,
     62    TOY_OPCODE_TGSI_TXQ_LZ,
     63    TOY_OPCODE_TGSI_TEX2,
     64    TOY_OPCODE_TGSI_TXB2,
     65    TOY_OPCODE_TGSI_TXL2,
     66    TOY_OPCODE_TGSI_SAMPLE,
     67    TOY_OPCODE_TGSI_SAMPLE_I,
     68    TOY_OPCODE_TGSI_SAMPLE_I_MS,
     69    TOY_OPCODE_TGSI_SAMPLE_B,
     70    TOY_OPCODE_TGSI_SAMPLE_C,
     71    TOY_OPCODE_TGSI_SAMPLE_C_LZ,
     72    TOY_OPCODE_TGSI_SAMPLE_D,
     73    TOY_OPCODE_TGSI_SAMPLE_L,
     74    TOY_OPCODE_TGSI_GATHER4,
     75    TOY_OPCODE_TGSI_SVIEWINFO,
     76    TOY_OPCODE_TGSI_SAMPLE_POS,
     77    TOY_OPCODE_TGSI_SAMPLE_INFO,
     78 
     79    /* math functions */
     80    TOY_OPCODE_INV,
     81    TOY_OPCODE_LOG,
     82    TOY_OPCODE_EXP,
     83    TOY_OPCODE_SQRT,
     84    TOY_OPCODE_RSQ,
     85    TOY_OPCODE_SIN,
     86    TOY_OPCODE_COS,
     87    TOY_OPCODE_FDIV,
     88    TOY_OPCODE_POW,
     89    TOY_OPCODE_INT_DIV_QUOTIENT,
     90    TOY_OPCODE_INT_DIV_REMAINDER,
     91 
     92    /* URB functions */
     93    TOY_OPCODE_URB_WRITE,
     94 
     95    /* GS-specific functions */
     96    TOY_OPCODE_EMIT,
     97    TOY_OPCODE_ENDPRIM,
     98 
     99    /* FS-specific functions */
    100    TOY_OPCODE_DDX,
    101    TOY_OPCODE_DDY,
    102    TOY_OPCODE_FB_WRITE,
    103    TOY_OPCODE_KIL,
    104 };
    105 
    106 /**
    107  * Toy instruction.
    108  */
    109 struct toy_inst {
    110    unsigned opcode:8;            /* enum toy_opcode      */
    111    unsigned access_mode:1;       /* GEN6_ALIGN_x          */
    112    unsigned mask_ctrl:1;         /* GEN6_MASKCTRL_x           */
    113    unsigned dep_ctrl:2;          /* GEN6_DEPCTRL_x     */
    114    unsigned qtr_ctrl:2;          /* GEN6_QTRCTRL_x   */
    115    unsigned thread_ctrl:2;       /* GEN6_THREADCTRL_x         */
    116    unsigned pred_ctrl:4;         /* GEN6_PREDCTRL_x      */
    117    unsigned pred_inv:1;          /* true or false        */
    118    unsigned exec_size:3;         /* GEN6_EXECSIZE_x        */
    119    unsigned cond_modifier:4;     /* GEN6_COND_x    */
    120    unsigned acc_wr_ctrl:1;       /* true or false        */
    121    unsigned saturate:1;          /* true or false        */
    122 
    123    /* true if the instruction should be ignored for instruction iteration */
    124    unsigned marker:1;
    125 
    126    unsigned pad:1;
    127 
    128    struct toy_dst dst;
    129    struct toy_src src[5];        /* match TGSI_FULL_MAX_SRC_REGISTERS */
    130 
    131    struct {
    132       int target;                /* TGSI_TEXTURE_x */
    133       struct toy_src offsets[1]; /* need to be 4 when GATHER4 is supported */
    134    } tex;
    135 
    136    struct list_head list;
    137 };
    138 
    139 struct toy_compaction_table {
    140    uint32_t control[32];
    141    uint32_t datatype[32];
    142    uint32_t subreg[32];
    143    uint32_t src[32];
    144 
    145    uint32_t control_3src[4];
    146    uint64_t source_3src[4];
    147 };
    148 
    149 /**
    150  * Toy compiler.
    151  */
    152 struct toy_compiler {
    153    const struct ilo_dev *dev;
    154 
    155    struct toy_inst templ;
    156    struct slab_mempool mempool;
    157    struct list_head instructions;
    158    struct list_head *iter, *iter_next;
    159 
    160    /* this is not set until toy_compiler_legalize_for_asm() */
    161    int num_instructions;
    162 
    163    int rect_linear_width;
    164    int next_vrf;
    165 
    166    bool fail;
    167    const char *reason;
    168 };
    169 
    170 /**
    171  * Allocate the given number of VRF registers.
    172  */
    173 static inline int
    174 tc_alloc_vrf(struct toy_compiler *tc, int count)
    175 {
    176    const int vrf = tc->next_vrf;
    177 
    178    tc->next_vrf += count;
    179 
    180    return vrf;
    181 }
    182 
    183 /**
    184  * Allocate a temporary register.
    185  */
    186 static inline struct toy_dst
    187 tc_alloc_tmp(struct toy_compiler *tc)
    188 {
    189    return tdst(TOY_FILE_VRF, tc_alloc_vrf(tc, 1), 0);
    190 }
    191 
    192 /**
    193  * Allocate four temporary registers.
    194  */
    195 static inline void
    196 tc_alloc_tmp4(struct toy_compiler *tc, struct toy_dst *tmp)
    197 {
    198    tmp[0] = tc_alloc_tmp(tc);
    199    tmp[1] = tc_alloc_tmp(tc);
    200    tmp[2] = tc_alloc_tmp(tc);
    201    tmp[3] = tc_alloc_tmp(tc);
    202 }
    203 
    204 /**
    205  * Duplicate an instruction at the current location.
    206  */
    207 static inline struct toy_inst *
    208 tc_duplicate_inst(struct toy_compiler *tc, const struct toy_inst *inst)
    209 {
    210    struct toy_inst *new_inst;
    211 
    212    new_inst = slab_alloc_st(&tc->mempool);
    213    if (!new_inst)
    214       return NULL;
    215 
    216    *new_inst = *inst;
    217    list_addtail(&new_inst->list, tc->iter_next);
    218 
    219    return new_inst;
    220 }
    221 
    222 /**
    223  * Move an instruction to the current location.
    224  */
    225 static inline void
    226 tc_move_inst(struct toy_compiler *tc, struct toy_inst *inst)
    227 {
    228    list_del(&inst->list);
    229    list_addtail(&inst->list, tc->iter_next);
    230 }
    231 
    232 /**
    233  * Discard an instruction.
    234  */
    235 static inline void
    236 tc_discard_inst(struct toy_compiler *tc, struct toy_inst *inst)
    237 {
    238    list_del(&inst->list);
    239    slab_free_st(&tc->mempool, inst);
    240 }
    241 
    242 /**
    243  * Add a new instruction at the current location, using tc->templ as the
    244  * template.
    245  */
    246 static inline struct toy_inst *
    247 tc_add(struct toy_compiler *tc)
    248 {
    249    return tc_duplicate_inst(tc, &tc->templ);
    250 }
    251 
    252 /**
    253  * A convenient version of tc_add() for instructions with 3 source operands.
    254  */
    255 static inline struct toy_inst *
    256 tc_add3(struct toy_compiler *tc, unsigned opcode,
    257         struct toy_dst dst,
    258         struct toy_src src0,
    259         struct toy_src src1,
    260         struct toy_src src2)
    261 {
    262    struct toy_inst *inst;
    263 
    264    inst = tc_add(tc);
    265    if (!inst)
    266       return NULL;
    267 
    268    inst->opcode = opcode;
    269    inst->dst = dst;
    270    inst->src[0] = src0;
    271    inst->src[1] = src1;
    272    inst->src[2] = src2;
    273 
    274    return inst;
    275 }
    276 
    277 /**
    278  * A convenient version of tc_add() for instructions with 2 source operands.
    279  */
    280 static inline struct toy_inst *
    281 tc_add2(struct toy_compiler *tc, int opcode,
    282             struct toy_dst dst,
    283             struct toy_src src0,
    284             struct toy_src src1)
    285 {
    286    return tc_add3(tc, opcode, dst, src0, src1, tsrc_null());
    287 }
    288 
    289 /**
    290  * A convenient version of tc_add() for instructions with 1 source operand.
    291  */
    292 static inline struct toy_inst *
    293 tc_add1(struct toy_compiler *tc, unsigned opcode,
    294         struct toy_dst dst,
    295         struct toy_src src0)
    296 {
    297    return tc_add2(tc, opcode, dst, src0, tsrc_null());
    298 }
    299 
    300 /**
    301  * A convenient version of tc_add() for instructions without source or
    302  * destination operands.
    303  */
    304 static inline struct toy_inst *
    305 tc_add0(struct toy_compiler *tc, unsigned opcode)
    306 {
    307    return tc_add1(tc, opcode, tdst_null(), tsrc_null());
    308 }
    309 
    310 #define TC_ALU0(func, opcode)             \
    311 static inline struct toy_inst *           \
    312 func(struct toy_compiler *tc)             \
    313 {                                         \
    314    return tc_add0(tc, opcode);            \
    315 }
    316 
    317 #define TC_ALU1(func, opcode)             \
    318 static inline struct toy_inst *           \
    319 func(struct toy_compiler *tc,             \
    320      struct toy_dst dst,                  \
    321      struct toy_src src)                  \
    322 {                                         \
    323    return tc_add1(tc, opcode, dst, src);  \
    324 }
    325 
    326 #define TC_ALU2(func, opcode)             \
    327 static inline struct toy_inst *           \
    328 func(struct toy_compiler *tc,             \
    329      struct toy_dst dst,                  \
    330      struct toy_src src0,                 \
    331      struct toy_src src1)                 \
    332 {                                         \
    333    return tc_add2(tc, opcode,             \
    334          dst, src0, src1);                \
    335 }
    336 
    337 #define TC_ALU3(func, opcode)             \
    338 static inline struct toy_inst *           \
    339 func(struct toy_compiler *tc,             \
    340      struct toy_dst dst,                  \
    341      struct toy_src src0,                 \
    342      struct toy_src src1,                 \
    343      struct toy_src src2)                 \
    344 {                                         \
    345    return tc_add3(tc, opcode,             \
    346          dst, src0, src1, src2);          \
    347 }
    348 
    349 #define TC_CND2(func, opcode)             \
    350 static inline struct toy_inst *           \
    351 func(struct toy_compiler *tc,             \
    352      struct toy_dst dst,                  \
    353      struct toy_src src0,                 \
    354      struct toy_src src1,                 \
    355      unsigned cond_modifier)              \
    356 {                                         \
    357    struct toy_inst *inst;                 \
    358    inst = tc_add2(tc, opcode,             \
    359          dst, src0, src1);                \
    360    inst->cond_modifier = cond_modifier;   \
    361    return inst;                           \
    362 }
    363 
    364 TC_ALU0(tc_NOP, GEN6_OPCODE_NOP)
    365 TC_ALU0(tc_ELSE, GEN6_OPCODE_ELSE)
    366 TC_ALU0(tc_ENDIF, GEN6_OPCODE_ENDIF)
    367 TC_ALU1(tc_MOV, GEN6_OPCODE_MOV)
    368 TC_ALU1(tc_RNDD, GEN6_OPCODE_RNDD)
    369 TC_ALU1(tc_INV, TOY_OPCODE_INV)
    370 TC_ALU1(tc_FRC, GEN6_OPCODE_FRC)
    371 TC_ALU1(tc_EXP, TOY_OPCODE_EXP)
    372 TC_ALU1(tc_LOG, TOY_OPCODE_LOG)
    373 TC_ALU2(tc_ADD, GEN6_OPCODE_ADD)
    374 TC_ALU2(tc_MUL, GEN6_OPCODE_MUL)
    375 TC_ALU2(tc_AND, GEN6_OPCODE_AND)
    376 TC_ALU2(tc_OR, GEN6_OPCODE_OR)
    377 TC_ALU2(tc_DP2, GEN6_OPCODE_DP2)
    378 TC_ALU2(tc_DP3, GEN6_OPCODE_DP3)
    379 TC_ALU2(tc_DP4, GEN6_OPCODE_DP4)
    380 TC_ALU2(tc_SHL, GEN6_OPCODE_SHL)
    381 TC_ALU2(tc_SHR, GEN6_OPCODE_SHR)
    382 TC_ALU2(tc_POW, TOY_OPCODE_POW)
    383 TC_ALU3(tc_MAC, GEN6_OPCODE_MAC)
    384 TC_CND2(tc_SEL, GEN6_OPCODE_SEL)
    385 TC_CND2(tc_CMP, GEN6_OPCODE_CMP)
    386 TC_CND2(tc_IF, GEN6_OPCODE_IF)
    387 TC_CND2(tc_SEND, GEN6_OPCODE_SEND)
    388 
    389 /**
    390  * Upcast a list_head to an instruction.
    391  */
    392 static inline struct toy_inst *
    393 tc_list_to_inst(struct toy_compiler *tc, struct list_head *item)
    394 {
    395    return container_of(item, (struct toy_inst *) NULL, list);
    396 }
    397 
    398 /**
    399  * Return the instruction at the current location.
    400  */
    401 static inline struct toy_inst *
    402 tc_current(struct toy_compiler *tc)
    403 {
    404    return (tc->iter != &tc->instructions) ?
    405       tc_list_to_inst(tc, tc->iter) : NULL;
    406 }
    407 
    408 /**
    409  * Set the current location to the head.
    410  */
    411 static inline void
    412 tc_head(struct toy_compiler *tc)
    413 {
    414    tc->iter = &tc->instructions;
    415    tc->iter_next = tc->iter->next;
    416 }
    417 
    418 /**
    419  * Set the current location to the tail.
    420  */
    421 static inline void
    422 tc_tail(struct toy_compiler *tc)
    423 {
    424    tc->iter = &tc->instructions;
    425    tc->iter_next = tc->iter;
    426 }
    427 
    428 /**
    429  * Advance the current location.
    430  */
    431 static inline struct toy_inst *
    432 tc_next_no_skip(struct toy_compiler *tc)
    433 {
    434    /* stay at the tail so that new instructions are added there */
    435    if (tc->iter_next == &tc->instructions) {
    436       tc_tail(tc);
    437       return NULL;
    438    }
    439 
    440    tc->iter = tc->iter_next;
    441    tc->iter_next = tc->iter_next->next;
    442 
    443    return tc_list_to_inst(tc, tc->iter);
    444 }
    445 
    446 /**
    447  * Advance the current location, skipping markers.
    448  */
    449 static inline struct toy_inst *
    450 tc_next(struct toy_compiler *tc)
    451 {
    452    struct toy_inst *inst;
    453 
    454    do {
    455       inst = tc_next_no_skip(tc);
    456    } while (inst && inst->marker);
    457 
    458    return inst;
    459 }
    460 
    461 static inline void
    462 tc_fail(struct toy_compiler *tc, const char *reason)
    463 {
    464    if (!tc->fail) {
    465       tc->fail = true;
    466       tc->reason = reason;
    467    }
    468 }
    469 
    470 void
    471 toy_compiler_init(struct toy_compiler *tc, const struct ilo_dev *dev);
    472 
    473 void
    474 toy_compiler_cleanup(struct toy_compiler *tc);
    475 
    476 void
    477 toy_compiler_dump(struct toy_compiler *tc);
    478 
    479 void *
    480 toy_compiler_assemble(struct toy_compiler *tc, int *size);
    481 
    482 const struct toy_compaction_table *
    483 toy_compiler_get_compaction_table(const struct ilo_dev *dev);
    484 
    485 void
    486 toy_compiler_disassemble(const struct ilo_dev *dev,
    487                          const void *kernel, int size,
    488                          bool dump_hex);
    489 
    490 #endif /* TOY_COMPILER_H */
    491