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_REG_H
     29 #define TOY_REG_H
     30 
     31 #include "pipe/p_compiler.h"
     32 #include "util/u_debug.h" /* for assert() */
     33 #include "util/u_math.h" /* for union fi */
     34 
     35 /* a toy reg is 256-bit wide */
     36 #define TOY_REG_WIDTH        32
     37 
     38 /**
     39  * Register files.
     40  */
     41 enum toy_file {
     42    /* virtual register file */
     43    TOY_FILE_VRF,
     44 
     45    TOY_FILE_ARF,
     46    TOY_FILE_GRF,
     47    TOY_FILE_MRF,
     48    TOY_FILE_IMM,
     49 
     50    TOY_FILE_COUNT,
     51 };
     52 
     53 /**
     54  * Register types.
     55  */
     56 enum toy_type {
     57    TOY_TYPE_F,
     58    TOY_TYPE_D,
     59    TOY_TYPE_UD,
     60    TOY_TYPE_W,
     61    TOY_TYPE_UW,
     62    TOY_TYPE_V, /* only valid for immediates */
     63 
     64    TOY_TYPE_COUNT,
     65 };
     66 
     67 /**
     68  * Register rectangles.  The three numbers stand for vertical stride, width,
     69  * and horizontal stride respectively.
     70  */
     71 enum toy_rect {
     72    TOY_RECT_LINEAR,
     73    TOY_RECT_041,
     74    TOY_RECT_010,
     75    TOY_RECT_220,
     76    TOY_RECT_440,
     77    TOY_RECT_240,
     78 
     79    TOY_RECT_COUNT,
     80 };
     81 
     82 /**
     83  * Source swizzles.  They are compatible with TGSI_SWIZZLE_x and hardware
     84  * values.
     85  */
     86 enum toy_swizzle {
     87    TOY_SWIZZLE_X = 0,
     88    TOY_SWIZZLE_Y = 1,
     89    TOY_SWIZZLE_Z = 2,
     90    TOY_SWIZZLE_W = 3,
     91 };
     92 
     93 /**
     94  * Destination writemasks.  They are compatible with TGSI_WRITEMASK_x and
     95  * hardware values.
     96  */
     97 enum toy_writemask {
     98    TOY_WRITEMASK_X    = (1 << TOY_SWIZZLE_X),
     99    TOY_WRITEMASK_Y    = (1 << TOY_SWIZZLE_Y),
    100    TOY_WRITEMASK_Z    = (1 << TOY_SWIZZLE_Z),
    101    TOY_WRITEMASK_W    = (1 << TOY_SWIZZLE_W),
    102    TOY_WRITEMASK_XY   = (TOY_WRITEMASK_X | TOY_WRITEMASK_Y),
    103    TOY_WRITEMASK_XZ   = (TOY_WRITEMASK_X | TOY_WRITEMASK_Z),
    104    TOY_WRITEMASK_XW   = (TOY_WRITEMASK_X | TOY_WRITEMASK_W),
    105    TOY_WRITEMASK_YZ   = (TOY_WRITEMASK_Y | TOY_WRITEMASK_Z),
    106    TOY_WRITEMASK_YW   = (TOY_WRITEMASK_Y | TOY_WRITEMASK_W),
    107    TOY_WRITEMASK_ZW   = (TOY_WRITEMASK_Z | TOY_WRITEMASK_W),
    108    TOY_WRITEMASK_XYZ  = (TOY_WRITEMASK_X | TOY_WRITEMASK_Y | TOY_WRITEMASK_Z),
    109    TOY_WRITEMASK_XYW  = (TOY_WRITEMASK_X | TOY_WRITEMASK_Y | TOY_WRITEMASK_W),
    110    TOY_WRITEMASK_XZW  = (TOY_WRITEMASK_X | TOY_WRITEMASK_Z | TOY_WRITEMASK_W),
    111    TOY_WRITEMASK_YZW  = (TOY_WRITEMASK_Y | TOY_WRITEMASK_Z | TOY_WRITEMASK_W),
    112    TOY_WRITEMASK_XYZW = (TOY_WRITEMASK_X | TOY_WRITEMASK_Y |
    113                          TOY_WRITEMASK_Z | TOY_WRITEMASK_W),
    114 };
    115 
    116 /**
    117  * Destination operand.
    118  */
    119 struct toy_dst {
    120    unsigned file:3;              /* TOY_FILE_x */
    121    unsigned type:4;              /* TOY_TYPE_x */
    122    unsigned rect:3;              /* TOY_RECT_x */
    123    unsigned indirect:1;          /* true or false */
    124    unsigned indirect_subreg:6;   /* which subreg of a0? */
    125 
    126    unsigned writemask:4;         /* TOY_WRITEMASK_x */
    127    unsigned pad:11;
    128 
    129    uint32_t val32;
    130 };
    131 
    132 /**
    133  * Source operand.
    134  */
    135 struct toy_src {
    136    unsigned file:3;              /* TOY_FILE_x */
    137    unsigned type:4;              /* TOY_TYPE_x */
    138    unsigned rect:3;              /* TOY_RECT_x */
    139    unsigned indirect:1;          /* true or false */
    140    unsigned indirect_subreg:6;   /* which subreg of a0? */
    141 
    142    unsigned swizzle_x:2;         /* TOY_SWIZZLE_x */
    143    unsigned swizzle_y:2;         /* TOY_SWIZZLE_x */
    144    unsigned swizzle_z:2;         /* TOY_SWIZZLE_x */
    145    unsigned swizzle_w:2;         /* TOY_SWIZZLE_x */
    146    unsigned absolute:1;          /* true or false */
    147    unsigned negate:1;            /* true or false */
    148    unsigned pad:5;
    149 
    150    uint32_t val32;
    151 };
    152 
    153 /**
    154  * Return true if the file is virtual.
    155  */
    156 static inline bool
    157 toy_file_is_virtual(enum toy_file file)
    158 {
    159    return (file == TOY_FILE_VRF);
    160 }
    161 
    162 /**
    163  * Return true if the file is a hardware one.
    164  */
    165 static inline bool
    166 toy_file_is_hw(enum toy_file file)
    167 {
    168    return !toy_file_is_virtual(file);
    169 }
    170 
    171 /**
    172  * Return the size of the file.
    173  */
    174 static inline uint32_t
    175 toy_file_size(enum toy_file file)
    176 {
    177    switch (file) {
    178    case TOY_FILE_GRF:
    179       return 256 * TOY_REG_WIDTH;
    180    case TOY_FILE_MRF:
    181       /* there is no MRF on GEN7+ */
    182       return 256 * TOY_REG_WIDTH;
    183    default:
    184       assert(!"invalid toy file");
    185       return 0;
    186    }
    187 }
    188 
    189 /**
    190  * Return the size of the type.
    191  */
    192 static inline int
    193 toy_type_size(enum toy_type type)
    194 {
    195    switch (type) {
    196    case TOY_TYPE_F:
    197    case TOY_TYPE_D:
    198    case TOY_TYPE_UD:
    199       return 4;
    200    case TOY_TYPE_W:
    201    case TOY_TYPE_UW:
    202       return 2;
    203    case TOY_TYPE_V:
    204    default:
    205       assert(!"invalid toy type");
    206       return 0;
    207    }
    208 }
    209 
    210 /**
    211  * Return true if the destination operand is null.
    212  */
    213 static inline bool
    214 tdst_is_null(struct toy_dst dst)
    215 {
    216    /* GEN6_ARF_NULL happens to be 0 */
    217    return (dst.file == TOY_FILE_ARF && dst.val32 == 0);
    218 }
    219 
    220 /**
    221  * Validate the destination operand.
    222  */
    223 static inline struct toy_dst
    224 tdst_validate(struct toy_dst dst)
    225 {
    226    switch (dst.file) {
    227    case TOY_FILE_VRF:
    228    case TOY_FILE_ARF:
    229    case TOY_FILE_MRF:
    230       assert(!dst.indirect);
    231       if (dst.file == TOY_FILE_MRF)
    232          assert(dst.val32 < toy_file_size(dst.file));
    233       break;
    234    case TOY_FILE_GRF:
    235       if (!dst.indirect)
    236          assert(dst.val32 < toy_file_size(dst.file));
    237       break;
    238    case TOY_FILE_IMM:
    239       /* yes, dst can be IMM of type W (for IF/ELSE/ENDIF/WHILE) */
    240       assert(!dst.indirect);
    241       assert(dst.type == TOY_TYPE_W);
    242       break;
    243    default:
    244       assert(!"invalid dst file");
    245       break;
    246    }
    247 
    248    switch (dst.type) {
    249    case TOY_TYPE_V:
    250       assert(!"invalid dst type");
    251       break;
    252    default:
    253       break;
    254    }
    255 
    256    assert(dst.rect == TOY_RECT_LINEAR);
    257    if (dst.file != TOY_FILE_IMM)
    258       assert(dst.val32 % toy_type_size(dst.type) == 0);
    259 
    260    assert(dst.writemask <= TOY_WRITEMASK_XYZW);
    261 
    262    return dst;
    263 }
    264 
    265 /**
    266  * Change the type of the destination operand.
    267  */
    268 static inline struct toy_dst
    269 tdst_type(struct toy_dst dst, enum toy_type type)
    270 {
    271    dst.type = type;
    272    return tdst_validate(dst);
    273 }
    274 
    275 /**
    276  * Change the type of the destination operand to TOY_TYPE_D.
    277  */
    278 static inline struct toy_dst
    279 tdst_d(struct toy_dst dst)
    280 {
    281    return tdst_type(dst, TOY_TYPE_D);
    282 }
    283 
    284 /**
    285  * Change the type of the destination operand to TOY_TYPE_UD.
    286  */
    287 static inline struct toy_dst
    288 tdst_ud(struct toy_dst dst)
    289 {
    290    return tdst_type(dst, TOY_TYPE_UD);
    291 }
    292 
    293 /**
    294  * Change the type of the destination operand to TOY_TYPE_W.
    295  */
    296 static inline struct toy_dst
    297 tdst_w(struct toy_dst dst)
    298 {
    299    return tdst_type(dst, TOY_TYPE_W);
    300 }
    301 
    302 /**
    303  * Change the type of the destination operand to TOY_TYPE_UW.
    304  */
    305 static inline struct toy_dst
    306 tdst_uw(struct toy_dst dst)
    307 {
    308    return tdst_type(dst, TOY_TYPE_UW);
    309 }
    310 
    311 /**
    312  * Change the rectangle of the destination operand.
    313  */
    314 static inline struct toy_dst
    315 tdst_rect(struct toy_dst dst, enum toy_rect rect)
    316 {
    317    dst.rect = rect;
    318    return tdst_validate(dst);
    319 }
    320 
    321 /**
    322  * Apply writemask to the destination operand.  Note that the current
    323  * writemask is honored.
    324  */
    325 static inline struct toy_dst
    326 tdst_writemask(struct toy_dst dst, enum toy_writemask writemask)
    327 {
    328    dst.writemask &= writemask;
    329    return tdst_validate(dst);
    330 }
    331 
    332 /**
    333  * Offset the destination operand.
    334  */
    335 static inline struct toy_dst
    336 tdst_offset(struct toy_dst dst, int reg, int subreg)
    337 {
    338    dst.val32 += reg * TOY_REG_WIDTH + subreg * toy_type_size(dst.type);
    339    return tdst_validate(dst);
    340 }
    341 
    342 /**
    343  * Construct a destination operand.
    344  */
    345 static inline struct toy_dst
    346 tdst_full(enum toy_file file, enum toy_type type, enum toy_rect rect,
    347           bool indirect, unsigned indirect_subreg,
    348           enum toy_writemask writemask, uint32_t val32)
    349 {
    350    struct toy_dst dst;
    351 
    352    dst.file = file;
    353    dst.type = type;
    354    dst.rect = rect;
    355    dst.indirect = indirect;
    356    dst.indirect_subreg = indirect_subreg;
    357    dst.writemask = writemask;
    358    dst.pad = 0;
    359 
    360    dst.val32 = val32;
    361 
    362    return tdst_validate(dst);
    363 }
    364 
    365 /**
    366  * Construct a null destination operand.
    367  */
    368 static inline struct toy_dst
    369 tdst_null(void)
    370 {
    371    static const struct toy_dst null_dst = {
    372       .file = TOY_FILE_ARF,
    373       .type = TOY_TYPE_F,
    374       .rect = TOY_RECT_LINEAR,
    375       .indirect = false,
    376       .indirect_subreg = 0,
    377       .writemask = TOY_WRITEMASK_XYZW,
    378       .pad = 0,
    379       .val32 = 0,
    380    };
    381 
    382    return null_dst;
    383 }
    384 
    385 /**
    386  * Construct a destination operand from a source operand.
    387  */
    388 static inline struct toy_dst
    389 tdst_from(struct toy_src src)
    390 {
    391    const enum toy_writemask writemask =
    392       (1 << src.swizzle_x) |
    393       (1 << src.swizzle_y) |
    394       (1 << src.swizzle_z) |
    395       (1 << src.swizzle_w);
    396 
    397    return tdst_full(src.file, src.type, src.rect,
    398          src.indirect, src.indirect_subreg, writemask, src.val32);
    399 }
    400 
    401 /**
    402  * Construct a destination operand, assuming the type is TOY_TYPE_F, the
    403  * rectangle is TOY_RECT_LINEAR, and the writemask is TOY_WRITEMASK_XYZW.
    404  */
    405 static inline struct toy_dst
    406 tdst(enum toy_file file, unsigned reg, unsigned subreg_in_bytes)
    407 {
    408    const enum toy_type type = TOY_TYPE_F;
    409    const enum toy_rect rect = TOY_RECT_LINEAR;
    410    const uint32_t val32 = reg * TOY_REG_WIDTH + subreg_in_bytes;
    411 
    412    return tdst_full(file, type, rect,
    413          false, 0, TOY_WRITEMASK_XYZW, val32);
    414 }
    415 
    416 /**
    417  * Construct an immediate destination operand of type TOY_TYPE_W.
    418  */
    419 static inline struct toy_dst
    420 tdst_imm_w(int16_t w)
    421 {
    422    const union fi fi = { .i = w };
    423 
    424    return tdst_full(TOY_FILE_IMM, TOY_TYPE_W, TOY_RECT_LINEAR,
    425          false, 0, TOY_WRITEMASK_XYZW, fi.ui);
    426 }
    427 
    428 /**
    429  * Return true if the source operand is null.
    430  */
    431 static inline bool
    432 tsrc_is_null(struct toy_src src)
    433 {
    434    /* GEN6_ARF_NULL happens to be 0 */
    435    return (src.file == TOY_FILE_ARF && src.val32 == 0);
    436 }
    437 
    438 /**
    439  * Return true if the source operand is swizzled.
    440  */
    441 static inline bool
    442 tsrc_is_swizzled(struct toy_src src)
    443 {
    444    return (src.swizzle_x != TOY_SWIZZLE_X ||
    445            src.swizzle_y != TOY_SWIZZLE_Y ||
    446            src.swizzle_z != TOY_SWIZZLE_Z ||
    447            src.swizzle_w != TOY_SWIZZLE_W);
    448 }
    449 
    450 /**
    451  * Return true if the source operand is swizzled to the same channel.
    452  */
    453 static inline bool
    454 tsrc_is_swizzle1(struct toy_src src)
    455 {
    456    return (src.swizzle_x == src.swizzle_y &&
    457            src.swizzle_x == src.swizzle_z &&
    458            src.swizzle_x == src.swizzle_w);
    459 }
    460 
    461 /**
    462  * Validate the source operand.
    463  */
    464 static inline struct toy_src
    465 tsrc_validate(struct toy_src src)
    466 {
    467    switch (src.file) {
    468    case TOY_FILE_VRF:
    469    case TOY_FILE_ARF:
    470    case TOY_FILE_MRF:
    471       assert(!src.indirect);
    472       if (src.file == TOY_FILE_MRF)
    473          assert(src.val32 < toy_file_size(src.file));
    474       break;
    475    case TOY_FILE_GRF:
    476       if (!src.indirect)
    477          assert(src.val32 < toy_file_size(src.file));
    478       break;
    479    case TOY_FILE_IMM:
    480       assert(!src.indirect);
    481       break;
    482    default:
    483       assert(!"invalid src file");
    484       break;
    485    }
    486 
    487    switch (src.type) {
    488    case TOY_TYPE_V:
    489       assert(src.file == TOY_FILE_IMM);
    490       break;
    491    default:
    492       break;
    493    }
    494 
    495    if (src.file != TOY_FILE_IMM)
    496       assert(src.val32 % toy_type_size(src.type) == 0);
    497 
    498    assert(src.swizzle_x < 4 && src.swizzle_y < 4 &&
    499           src.swizzle_z < 4 && src.swizzle_w < 4);
    500 
    501    return src;
    502 }
    503 
    504 /**
    505  * Change the type of the source operand.
    506  */
    507 static inline struct toy_src
    508 tsrc_type(struct toy_src src, enum toy_type type)
    509 {
    510    src.type = type;
    511    return tsrc_validate(src);
    512 }
    513 
    514 /**
    515  * Change the type of the source operand to TOY_TYPE_D.
    516  */
    517 static inline struct toy_src
    518 tsrc_d(struct toy_src src)
    519 {
    520    return tsrc_type(src, TOY_TYPE_D);
    521 }
    522 
    523 /**
    524  * Change the type of the source operand to TOY_TYPE_UD.
    525  */
    526 static inline struct toy_src
    527 tsrc_ud(struct toy_src src)
    528 {
    529    return tsrc_type(src, TOY_TYPE_UD);
    530 }
    531 
    532 /**
    533  * Change the type of the source operand to TOY_TYPE_W.
    534  */
    535 static inline struct toy_src
    536 tsrc_w(struct toy_src src)
    537 {
    538    return tsrc_type(src, TOY_TYPE_W);
    539 }
    540 
    541 /**
    542  * Change the type of the source operand to TOY_TYPE_UW.
    543  */
    544 static inline struct toy_src
    545 tsrc_uw(struct toy_src src)
    546 {
    547    return tsrc_type(src, TOY_TYPE_UW);
    548 }
    549 
    550 /**
    551  * Change the rectangle of the source operand.
    552  */
    553 static inline struct toy_src
    554 tsrc_rect(struct toy_src src, enum toy_rect rect)
    555 {
    556    src.rect = rect;
    557    return tsrc_validate(src);
    558 }
    559 
    560 /**
    561  * Swizzle the source operand.  Note that the current swizzles are honored.
    562  */
    563 static inline struct toy_src
    564 tsrc_swizzle(struct toy_src src,
    565              enum toy_swizzle swizzle_x, enum toy_swizzle swizzle_y,
    566              enum toy_swizzle swizzle_z, enum toy_swizzle swizzle_w)
    567 {
    568    const enum toy_swizzle current[4] = {
    569       src.swizzle_x, src.swizzle_y,
    570       src.swizzle_z, src.swizzle_w,
    571    };
    572 
    573    src.swizzle_x = current[swizzle_x];
    574    src.swizzle_y = current[swizzle_y];
    575    src.swizzle_z = current[swizzle_z];
    576    src.swizzle_w = current[swizzle_w];
    577 
    578    return tsrc_validate(src);
    579 }
    580 
    581 /**
    582  * Swizzle the source operand to the same channel.  Note that the current
    583  * swizzles are honored.
    584  */
    585 static inline struct toy_src
    586 tsrc_swizzle1(struct toy_src src, enum toy_swizzle swizzle)
    587 {
    588    return tsrc_swizzle(src, swizzle, swizzle, swizzle, swizzle);
    589 }
    590 
    591 /**
    592  * Set absolute and unset negate of the source operand.
    593  */
    594 static inline struct toy_src
    595 tsrc_absolute(struct toy_src src)
    596 {
    597    src.absolute = true;
    598    src.negate = false;
    599    return tsrc_validate(src);
    600 }
    601 
    602 /**
    603  * Negate the source operand.
    604  */
    605 static inline struct toy_src
    606 tsrc_negate(struct toy_src src)
    607 {
    608    src.negate = !src.negate;
    609    return tsrc_validate(src);
    610 }
    611 
    612 /**
    613  * Offset the source operand.
    614  */
    615 static inline struct toy_src
    616 tsrc_offset(struct toy_src src, int reg, int subreg)
    617 {
    618    src.val32 += reg * TOY_REG_WIDTH + subreg * toy_type_size(src.type);
    619    return tsrc_validate(src);
    620 }
    621 
    622 /**
    623  * Construct a source operand.
    624  */
    625 static inline struct toy_src
    626 tsrc_full(enum toy_file file, enum toy_type type,
    627           enum toy_rect rect, bool indirect, unsigned indirect_subreg,
    628           enum toy_swizzle swizzle_x, enum toy_swizzle swizzle_y,
    629           enum toy_swizzle swizzle_z, enum toy_swizzle swizzle_w,
    630           bool absolute, bool negate,
    631           uint32_t val32)
    632 {
    633    struct toy_src src;
    634 
    635    src.file = file;
    636    src.type = type;
    637    src.rect = rect;
    638    src.indirect = indirect;
    639    src.indirect_subreg = indirect_subreg;
    640    src.swizzle_x = swizzle_x;
    641    src.swizzle_y = swizzle_y;
    642    src.swizzle_z = swizzle_z;
    643    src.swizzle_w = swizzle_w;
    644    src.absolute = absolute;
    645    src.negate = negate;
    646    src.pad = 0;
    647 
    648    src.val32 = val32;
    649 
    650    return tsrc_validate(src);
    651 }
    652 
    653 /**
    654  * Construct a null source operand.
    655  */
    656 static inline struct toy_src
    657 tsrc_null(void)
    658 {
    659    static const struct toy_src null_src = {
    660       .file = TOY_FILE_ARF,
    661       .type = TOY_TYPE_F,
    662       .rect = TOY_RECT_LINEAR,
    663       .indirect = false,
    664       .indirect_subreg = 0,
    665       .swizzle_x = TOY_SWIZZLE_X,
    666       .swizzle_y = TOY_SWIZZLE_Y,
    667       .swizzle_z = TOY_SWIZZLE_Z,
    668       .swizzle_w = TOY_SWIZZLE_W,
    669       .absolute = false,
    670       .negate = false,
    671       .pad = 0,
    672       .val32 = 0,
    673    };
    674 
    675    return null_src;
    676 }
    677 
    678 /**
    679  * Construct a source operand from a destination operand.
    680  */
    681 static inline struct toy_src
    682 tsrc_from(struct toy_dst dst)
    683 {
    684    enum toy_swizzle swizzle[4];
    685 
    686    if (dst.writemask == TOY_WRITEMASK_XYZW) {
    687       swizzle[0] = TOY_SWIZZLE_X;
    688       swizzle[1] = TOY_SWIZZLE_Y;
    689       swizzle[2] = TOY_SWIZZLE_Z;
    690       swizzle[3] = TOY_SWIZZLE_W;
    691    }
    692    else {
    693       const enum toy_swizzle first =
    694          (dst.writemask & TOY_WRITEMASK_X) ? TOY_SWIZZLE_X :
    695          (dst.writemask & TOY_WRITEMASK_Y) ? TOY_SWIZZLE_Y :
    696          (dst.writemask & TOY_WRITEMASK_Z) ? TOY_SWIZZLE_Z :
    697          (dst.writemask & TOY_WRITEMASK_W) ? TOY_SWIZZLE_W :
    698          TOY_SWIZZLE_X;
    699 
    700       swizzle[0] = (dst.writemask & TOY_WRITEMASK_X) ? TOY_SWIZZLE_X : first;
    701       swizzle[1] = (dst.writemask & TOY_WRITEMASK_Y) ? TOY_SWIZZLE_Y : first;
    702       swizzle[2] = (dst.writemask & TOY_WRITEMASK_Z) ? TOY_SWIZZLE_Z : first;
    703       swizzle[3] = (dst.writemask & TOY_WRITEMASK_W) ? TOY_SWIZZLE_W : first;
    704    }
    705 
    706    return tsrc_full(dst.file, dst.type, dst.rect,
    707                     dst.indirect, dst.indirect_subreg,
    708                     swizzle[0], swizzle[1], swizzle[2], swizzle[3],
    709                     false, false, dst.val32);
    710 }
    711 
    712 /**
    713  * Construct a source operand, assuming the type is TOY_TYPE_F, the
    714  * rectangle is TOY_RECT_LINEAR, and no swizzles/absolute/negate.
    715  */
    716 static inline struct toy_src
    717 tsrc(enum toy_file file, unsigned reg, unsigned subreg_in_bytes)
    718 {
    719    const enum toy_type type = TOY_TYPE_F;
    720    const enum toy_rect rect = TOY_RECT_LINEAR;
    721    const uint32_t val32 = reg * TOY_REG_WIDTH + subreg_in_bytes;
    722 
    723    return tsrc_full(file, type, rect, false, 0,
    724                     TOY_SWIZZLE_X, TOY_SWIZZLE_Y,
    725                     TOY_SWIZZLE_Z, TOY_SWIZZLE_W,
    726                     false, false, val32);
    727 }
    728 
    729 /**
    730  * Construct an immediate source operand.
    731  */
    732 static inline struct toy_src
    733 tsrc_imm(enum toy_type type, uint32_t val32)
    734 {
    735    return tsrc_full(TOY_FILE_IMM, type, TOY_RECT_LINEAR, false, 0,
    736                     TOY_SWIZZLE_X, TOY_SWIZZLE_Y,
    737                     TOY_SWIZZLE_Z, TOY_SWIZZLE_W,
    738                     false, false, val32);
    739 }
    740 
    741 /**
    742  * Construct an immediate source operand of type TOY_TYPE_F.
    743  */
    744 static inline struct toy_src
    745 tsrc_imm_f(float f)
    746 {
    747    const union fi fi = { .f = f };
    748    return tsrc_imm(TOY_TYPE_F, fi.ui);
    749 }
    750 
    751 /**
    752  * Construct an immediate source operand of type TOY_TYPE_D.
    753  */
    754 static inline struct toy_src
    755 tsrc_imm_d(int32_t d)
    756 {
    757    const union fi fi = { .i = d };
    758    return tsrc_imm(TOY_TYPE_D, fi.ui);
    759 }
    760 
    761 /**
    762  * Construct an immediate source operand of type TOY_TYPE_UD.
    763  */
    764 static inline struct toy_src
    765 tsrc_imm_ud(uint32_t ud)
    766 {
    767    const union fi fi = { .ui = ud };
    768    return tsrc_imm(TOY_TYPE_UD, fi.ui);
    769 }
    770 
    771 /**
    772  * Construct an immediate source operand of type TOY_TYPE_W.
    773  */
    774 static inline struct toy_src
    775 tsrc_imm_w(int16_t w)
    776 {
    777    const union fi fi = { .i = w };
    778    return tsrc_imm(TOY_TYPE_W, fi.ui);
    779 }
    780 
    781 /**
    782  * Construct an immediate source operand of type TOY_TYPE_UW.
    783  */
    784 static inline struct toy_src
    785 tsrc_imm_uw(uint16_t uw)
    786 {
    787    const union fi fi = { .ui = uw };
    788    return tsrc_imm(TOY_TYPE_UW, fi.ui);
    789 }
    790 
    791 /**
    792  * Construct an immediate source operand of type TOY_TYPE_V.
    793  */
    794 static inline struct toy_src
    795 tsrc_imm_v(uint32_t v)
    796 {
    797    return tsrc_imm(TOY_TYPE_V, v);
    798 }
    799 
    800 #endif /* TOY_REG_H */
    801