Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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@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:3;              /* 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:12;
  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:3;              /* 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:6;
  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.    /* BRW_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.    /* BRW_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.