Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
  3.  Intel funded Tungsten Graphics to
  4.  develop this 3D driver.
  5.  
  6.  Permission is hereby granted, free of charge, to any person obtaining
  7.  a copy of this software and associated documentation files (the
  8.  "Software"), to deal in the Software without restriction, including
  9.  without limitation the rights to use, copy, modify, merge, publish,
  10.  distribute, sublicense, and/or sell copies of the Software, and to
  11.  permit persons to whom the Software is furnished to do so, subject to
  12.  the following conditions:
  13.  
  14.  The above copyright notice and this permission notice (including the
  15.  next paragraph) shall be included in all copies or substantial
  16.  portions of the Software.
  17.  
  18.  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19.  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  21.  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
  22.  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  23.  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  24.  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  
  26.  **********************************************************************/
  27.  /*
  28.   * Authors:
  29.   *   Keith Whitwell <keithw@vmware.com>
  30.   */
  31.  
  32. /** @file brw_reg.h
  33.  *
  34.  * This file defines struct brw_reg, which is our representation for EU
  35.  * registers.  They're not a hardware specific format, just an abstraction
  36.  * that intends to capture the full flexibility of the hardware registers.
  37.  *
  38.  * The brw_eu_emit.c layer's brw_set_dest/brw_set_src[01] functions encode
  39.  * the abstract brw_reg type into the actual hardware instruction encoding.
  40.  */
  41.  
  42. #ifndef BRW_REG_H
  43. #define BRW_REG_H
  44.  
  45. #include <stdbool.h>
  46. #include "main/imports.h"
  47. #include "main/compiler.h"
  48. #include "main/macros.h"
  49. #include "program/prog_instruction.h"
  50. #include "brw_defines.h"
  51.  
  52. #ifdef __cplusplus
  53. extern "C" {
  54. #endif
  55.  
  56. struct brw_device_info;
  57.  
  58. /** Number of general purpose registers (VS, WM, etc) */
  59. #define BRW_MAX_GRF 128
  60.  
  61. /**
  62.  * First GRF used for the MRF hack.
  63.  *
  64.  * On gen7, MRFs are no longer used, and contiguous GRFs are used instead.  We
  65.  * haven't converted our compiler to be aware of this, so it asks for MRFs and
  66.  * brw_eu_emit.c quietly converts them to be accesses of the top GRFs.  The
  67.  * register allocators have to be careful of this to avoid corrupting the "MRF"s
  68.  * with actual GRF allocations.
  69.  */
  70. #define GEN7_MRF_HACK_START 112
  71.  
  72. /** Number of message register file registers */
  73. #define BRW_MAX_MRF 16
  74.  
  75. #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
  76. #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
  77.  
  78. #define BRW_SWIZZLE_NOOP      BRW_SWIZZLE4(0,1,2,3)
  79. #define BRW_SWIZZLE_XYZW      BRW_SWIZZLE4(0,1,2,3)
  80. #define BRW_SWIZZLE_XXXX      BRW_SWIZZLE4(0,0,0,0)
  81. #define BRW_SWIZZLE_YYYY      BRW_SWIZZLE4(1,1,1,1)
  82. #define BRW_SWIZZLE_ZZZZ      BRW_SWIZZLE4(2,2,2,2)
  83. #define BRW_SWIZZLE_WWWW      BRW_SWIZZLE4(3,3,3,3)
  84. #define BRW_SWIZZLE_XYXY      BRW_SWIZZLE4(0,1,0,1)
  85. #define BRW_SWIZZLE_YZXW      BRW_SWIZZLE4(1,2,0,3)
  86. #define BRW_SWIZZLE_ZXYW      BRW_SWIZZLE4(2,0,1,3)
  87. #define BRW_SWIZZLE_ZWZW      BRW_SWIZZLE4(2,3,2,3)
  88.  
  89. static inline bool
  90. brw_is_single_value_swizzle(unsigned swiz)
  91. {
  92.    return (swiz == BRW_SWIZZLE_XXXX ||
  93.            swiz == BRW_SWIZZLE_YYYY ||
  94.            swiz == BRW_SWIZZLE_ZZZZ ||
  95.            swiz == BRW_SWIZZLE_WWWW);
  96. }
  97.  
  98. /**
  99.  * Compute the swizzle obtained from the application of \p swz0 on the result
  100.  * of \p swz1.  The argument ordering is expected to match function
  101.  * composition.
  102.  */
  103. static inline unsigned
  104. brw_compose_swizzle(unsigned swz0, unsigned swz1)
  105. {
  106.    return BRW_SWIZZLE4(
  107.       BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 0)),
  108.       BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 1)),
  109.       BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 2)),
  110.       BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 3)));
  111. }
  112.  
  113. /**
  114.  * Return the result of applying swizzle \p swz to shuffle the bits of \p mask
  115.  * (AKA image).
  116.  */
  117. static inline unsigned
  118. brw_apply_swizzle_to_mask(unsigned swz, unsigned mask)
  119. {
  120.    unsigned result = 0;
  121.  
  122.    for (unsigned i = 0; i < 4; i++) {
  123.       if (mask & (1 << BRW_GET_SWZ(swz, i)))
  124.          result |= 1 << i;
  125.    }
  126.  
  127.    return result;
  128. }
  129.  
  130. /**
  131.  * Return the result of applying the inverse of swizzle \p swz to shuffle the
  132.  * bits of \p mask (AKA preimage).  Useful to find out which components are
  133.  * read from a swizzled source given the instruction writemask.
  134.  */
  135. static inline unsigned
  136. brw_apply_inv_swizzle_to_mask(unsigned swz, unsigned mask)
  137. {
  138.    unsigned result = 0;
  139.  
  140.    for (unsigned i = 0; i < 4; i++) {
  141.       if (mask & (1 << i))
  142.          result |= 1 << BRW_GET_SWZ(swz, i);
  143.    }
  144.  
  145.    return result;
  146. }
  147.  
  148. /**
  149.  * Construct an identity swizzle for the set of enabled channels given by \p
  150.  * mask.  The result will only reference channels enabled in the provided \p
  151.  * mask, assuming that \p mask is non-zero.  The constructed swizzle will
  152.  * satisfy the property that for any instruction OP and any mask:
  153.  *
  154.  *    brw_OP(p, brw_writemask(dst, mask),
  155.  *           brw_swizzle(src, brw_swizzle_for_mask(mask)));
  156.  *
  157.  * will be equivalent to the same instruction without swizzle:
  158.  *
  159.  *    brw_OP(p, brw_writemask(dst, mask), src);
  160.  */
  161. static inline unsigned
  162. brw_swizzle_for_mask(unsigned mask)
  163. {
  164.    unsigned last = (mask ? ffs(mask) - 1 : 0);
  165.    unsigned swz[4];
  166.  
  167.    for (unsigned i = 0; i < 4; i++)
  168.       last = swz[i] = (mask & (1 << i) ? i : last);
  169.  
  170.    return BRW_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
  171. }
  172.  
  173. /**
  174.  * Construct an identity swizzle for the first \p n components of a vector.
  175.  * When only a subset of channels of a vec4 are used we don't want to
  176.  * reference the other channels, as that will tell optimization passes that
  177.  * those other channels are used.
  178.  */
  179. static inline unsigned
  180. brw_swizzle_for_size(unsigned n)
  181. {
  182.    return brw_swizzle_for_mask((1 << n) - 1);
  183. }
  184.  
  185. /**
  186.  * Converse of brw_swizzle_for_mask().  Returns the mask of components
  187.  * accessed by the specified swizzle \p swz.
  188.  */
  189. static inline unsigned
  190. brw_mask_for_swizzle(unsigned swz)
  191. {
  192.    return brw_apply_inv_swizzle_to_mask(swz, ~0);
  193. }
  194.  
  195. enum PACKED brw_reg_type {
  196.    BRW_REGISTER_TYPE_UD = 0,
  197.    BRW_REGISTER_TYPE_D,
  198.    BRW_REGISTER_TYPE_UW,
  199.    BRW_REGISTER_TYPE_W,
  200.    BRW_REGISTER_TYPE_F,
  201.  
  202.    /** Non-immediates only: @{ */
  203.    BRW_REGISTER_TYPE_UB,
  204.    BRW_REGISTER_TYPE_B,
  205.    /** @} */
  206.  
  207.    /** Immediates only: @{ */
  208.    BRW_REGISTER_TYPE_UV,
  209.    BRW_REGISTER_TYPE_V,
  210.    BRW_REGISTER_TYPE_VF,
  211.    /** @} */
  212.  
  213.    BRW_REGISTER_TYPE_DF, /* Gen7+ (no immediates until Gen8+) */
  214.  
  215.    /* Gen8+ */
  216.    BRW_REGISTER_TYPE_HF,
  217.    BRW_REGISTER_TYPE_UQ,
  218.    BRW_REGISTER_TYPE_Q,
  219. };
  220.  
  221. unsigned brw_reg_type_to_hw_type(const struct brw_device_info *devinfo,
  222.                                  enum brw_reg_type type, unsigned file);
  223. const char *brw_reg_type_letters(unsigned brw_reg_type);
  224.  
  225. #define REG_SIZE (8*4)
  226.  
  227. /* These aren't hardware structs, just something useful for us to pass around:
  228.  *
  229.  * Align1 operation has a lot of control over input ranges.  Used in
  230.  * WM programs to implement shaders decomposed into "channel serial"
  231.  * or "structure of array" form:
  232.  */
  233. struct brw_reg {
  234.    enum brw_reg_type type:4;
  235.    unsigned file:2;
  236.    unsigned nr:8;
  237.    unsigned subnr:5;              /* :1 in align16 */
  238.    unsigned negate:1;             /* source only */
  239.    unsigned abs:1;                /* source only */
  240.    unsigned vstride:4;            /* source only */
  241.    unsigned width:3;              /* src only, align1 only */
  242.    unsigned hstride:2;            /* align1 only */
  243.    unsigned address_mode:1;       /* relative addressing, hopefully! */
  244.    unsigned pad0:1;
  245.  
  246.    union {
  247.       struct {
  248.          unsigned swizzle:8;      /* src only, align16 only */
  249.          unsigned writemask:4;    /* dest only, align16 only */
  250.          int  indirect_offset:10; /* relative addressing offset */
  251.          unsigned pad1:10;        /* two dwords total */
  252.       } bits;
  253.  
  254.       float f;
  255.       int   d;
  256.       unsigned ud;
  257.    } dw1;
  258. };
  259.  
  260.  
  261. struct brw_indirect {
  262.    unsigned addr_subnr:4;
  263.    int addr_offset:10;
  264.    unsigned pad:18;
  265. };
  266.  
  267.  
  268. static inline unsigned
  269. type_sz(unsigned type)
  270. {
  271.    switch(type) {
  272.    case BRW_REGISTER_TYPE_UQ:
  273.    case BRW_REGISTER_TYPE_Q:
  274.       return 8;
  275.    case BRW_REGISTER_TYPE_UD:
  276.    case BRW_REGISTER_TYPE_D:
  277.    case BRW_REGISTER_TYPE_F:
  278.       return 4;
  279.    case BRW_REGISTER_TYPE_UW:
  280.    case BRW_REGISTER_TYPE_W:
  281.       return 2;
  282.    case BRW_REGISTER_TYPE_UB:
  283.    case BRW_REGISTER_TYPE_B:
  284.       return 1;
  285.    default:
  286.       return 0;
  287.    }
  288. }
  289.  
  290. static inline bool
  291. type_is_signed(unsigned type)
  292. {
  293.    switch(type) {
  294.    case BRW_REGISTER_TYPE_D:
  295.    case BRW_REGISTER_TYPE_W:
  296.    case BRW_REGISTER_TYPE_F:
  297.    case BRW_REGISTER_TYPE_B:
  298.    case BRW_REGISTER_TYPE_V:
  299.    case BRW_REGISTER_TYPE_VF:
  300.    case BRW_REGISTER_TYPE_DF:
  301.    case BRW_REGISTER_TYPE_HF:
  302.    case BRW_REGISTER_TYPE_Q:
  303.       return true;
  304.  
  305.    case BRW_REGISTER_TYPE_UD:
  306.    case BRW_REGISTER_TYPE_UW:
  307.    case BRW_REGISTER_TYPE_UB:
  308.    case BRW_REGISTER_TYPE_UV:
  309.    case BRW_REGISTER_TYPE_UQ:
  310.       return false;
  311.  
  312.    default:
  313.       unreachable("not reached");
  314.    }
  315. }
  316.  
  317. /**
  318.  * Construct a brw_reg.
  319.  * \param file      one of the BRW_x_REGISTER_FILE values
  320.  * \param nr        register number/index
  321.  * \param subnr     register sub number
  322.  * \param negate    register negate modifier
  323.  * \param abs       register abs modifier
  324.  * \param type      one of BRW_REGISTER_TYPE_x
  325.  * \param vstride   one of BRW_VERTICAL_STRIDE_x
  326.  * \param width     one of BRW_WIDTH_x
  327.  * \param hstride   one of BRW_HORIZONTAL_STRIDE_x
  328.  * \param swizzle   one of BRW_SWIZZLE_x
  329.  * \param writemask WRITEMASK_X/Y/Z/W bitfield
  330.  */
  331. static inline struct brw_reg
  332. brw_reg(unsigned file,
  333.         unsigned nr,
  334.         unsigned subnr,
  335.         unsigned negate,
  336.         unsigned abs,
  337.         enum brw_reg_type type,
  338.         unsigned vstride,
  339.         unsigned width,
  340.         unsigned hstride,
  341.         unsigned swizzle,
  342.         unsigned writemask)
  343. {
  344.    struct brw_reg reg;
  345.    if (file == BRW_GENERAL_REGISTER_FILE)
  346.       assert(nr < BRW_MAX_GRF);
  347.    else if (file == BRW_MESSAGE_REGISTER_FILE)
  348.       assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
  349.    else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
  350.       assert(nr <= BRW_ARF_TIMESTAMP);
  351.  
  352.    reg.type = type;
  353.    reg.file = file;
  354.    reg.nr = nr;
  355.    reg.subnr = subnr * type_sz(type);
  356.    reg.negate = negate;
  357.    reg.abs = abs;
  358.    reg.vstride = vstride;
  359.    reg.width = width;
  360.    reg.hstride = hstride;
  361.    reg.address_mode = BRW_ADDRESS_DIRECT;
  362.    reg.pad0 = 0;
  363.  
  364.    /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
  365.     * set swizzle and writemask to W, as the lower bits of subnr will
  366.     * be lost when converted to align16.  This is probably too much to
  367.     * keep track of as you'd want it adjusted by suboffset(), etc.
  368.     * Perhaps fix up when converting to align16?
  369.     */
  370.    reg.dw1.bits.swizzle = swizzle;
  371.    reg.dw1.bits.writemask = writemask;
  372.    reg.dw1.bits.indirect_offset = 0;
  373.    reg.dw1.bits.pad1 = 0;
  374.    return reg;
  375. }
  376.  
  377. /** Construct float[16] register */
  378. static inline struct brw_reg
  379. brw_vec16_reg(unsigned file, unsigned nr, unsigned subnr)
  380. {
  381.    return brw_reg(file,
  382.                   nr,
  383.                   subnr,
  384.                   0,
  385.                   0,
  386.                   BRW_REGISTER_TYPE_F,
  387.                   BRW_VERTICAL_STRIDE_16,
  388.                   BRW_WIDTH_16,
  389.                   BRW_HORIZONTAL_STRIDE_1,
  390.                   BRW_SWIZZLE_XYZW,
  391.                   WRITEMASK_XYZW);
  392. }
  393.  
  394. /** Construct float[8] register */
  395. static inline struct brw_reg
  396. brw_vec8_reg(unsigned file, unsigned nr, unsigned subnr)
  397. {
  398.    return brw_reg(file,
  399.                   nr,
  400.                   subnr,
  401.                   0,
  402.                   0,
  403.                   BRW_REGISTER_TYPE_F,
  404.                   BRW_VERTICAL_STRIDE_8,
  405.                   BRW_WIDTH_8,
  406.                   BRW_HORIZONTAL_STRIDE_1,
  407.                   BRW_SWIZZLE_XYZW,
  408.                   WRITEMASK_XYZW);
  409. }
  410.  
  411. /** Construct float[4] register */
  412. static inline struct brw_reg
  413. brw_vec4_reg(unsigned file, unsigned nr, unsigned subnr)
  414. {
  415.    return brw_reg(file,
  416.                   nr,
  417.                   subnr,
  418.                   0,
  419.                   0,
  420.                   BRW_REGISTER_TYPE_F,
  421.                   BRW_VERTICAL_STRIDE_4,
  422.                   BRW_WIDTH_4,
  423.                   BRW_HORIZONTAL_STRIDE_1,
  424.                   BRW_SWIZZLE_XYZW,
  425.                   WRITEMASK_XYZW);
  426. }
  427.  
  428. /** Construct float[2] register */
  429. static inline struct brw_reg
  430. brw_vec2_reg(unsigned file, unsigned nr, unsigned subnr)
  431. {
  432.    return brw_reg(file,
  433.                   nr,
  434.                   subnr,
  435.                   0,
  436.                   0,
  437.                   BRW_REGISTER_TYPE_F,
  438.                   BRW_VERTICAL_STRIDE_2,
  439.                   BRW_WIDTH_2,
  440.                   BRW_HORIZONTAL_STRIDE_1,
  441.                   BRW_SWIZZLE_XYXY,
  442.                   WRITEMASK_XY);
  443. }
  444.  
  445. /** Construct float[1] register */
  446. static inline struct brw_reg
  447. brw_vec1_reg(unsigned file, unsigned nr, unsigned subnr)
  448. {
  449.    return brw_reg(file,
  450.                   nr,
  451.                   subnr,
  452.                   0,
  453.                   0,
  454.                   BRW_REGISTER_TYPE_F,
  455.                   BRW_VERTICAL_STRIDE_0,
  456.                   BRW_WIDTH_1,
  457.                   BRW_HORIZONTAL_STRIDE_0,
  458.                   BRW_SWIZZLE_XXXX,
  459.                   WRITEMASK_X);
  460. }
  461.  
  462. static inline struct brw_reg
  463. brw_vecn_reg(unsigned width, unsigned file, unsigned nr, unsigned subnr)
  464. {
  465.    switch (width) {
  466.    case 1:
  467.       return brw_vec1_reg(file, nr, subnr);
  468.    case 2:
  469.       return brw_vec2_reg(file, nr, subnr);
  470.    case 4:
  471.       return brw_vec4_reg(file, nr, subnr);
  472.    case 8:
  473.       return brw_vec8_reg(file, nr, subnr);
  474.    case 16:
  475.       return brw_vec16_reg(file, nr, subnr);
  476.    default:
  477.       unreachable("Invalid register width");
  478.    }
  479. }
  480.  
  481. static inline struct brw_reg
  482. retype(struct brw_reg reg, enum brw_reg_type type)
  483. {
  484.    reg.type = type;
  485.    return reg;
  486. }
  487.  
  488. static inline struct brw_reg
  489. firsthalf(struct brw_reg reg)
  490. {
  491.    return reg;
  492. }
  493.  
  494. static inline struct brw_reg
  495. sechalf(struct brw_reg reg)
  496. {
  497.    if (reg.vstride)
  498.       reg.nr++;
  499.    return reg;
  500. }
  501.  
  502. static inline struct brw_reg
  503. suboffset(struct brw_reg reg, unsigned delta)
  504. {
  505.    reg.subnr += delta * type_sz(reg.type);
  506.    return reg;
  507. }
  508.  
  509.  
  510. static inline struct brw_reg
  511. offset(struct brw_reg reg, unsigned delta)
  512. {
  513.    reg.nr += delta;
  514.    return reg;
  515. }
  516.  
  517.  
  518. static inline struct brw_reg
  519. byte_offset(struct brw_reg reg, unsigned bytes)
  520. {
  521.    unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
  522.    reg.nr = newoffset / REG_SIZE;
  523.    reg.subnr = newoffset % REG_SIZE;
  524.    return reg;
  525. }
  526.  
  527.  
  528. /** Construct unsigned word[16] register */
  529. static inline struct brw_reg
  530. brw_uw16_reg(unsigned file, unsigned nr, unsigned subnr)
  531. {
  532.    return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
  533. }
  534.  
  535. /** Construct unsigned word[8] register */
  536. static inline struct brw_reg
  537. brw_uw8_reg(unsigned file, unsigned nr, unsigned subnr)
  538. {
  539.    return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
  540. }
  541.  
  542. /** Construct unsigned word[1] register */
  543. static inline struct brw_reg
  544. brw_uw1_reg(unsigned file, unsigned nr, unsigned subnr)
  545. {
  546.    return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
  547. }
  548.  
  549. static inline struct brw_reg
  550. brw_imm_reg(enum brw_reg_type type)
  551. {
  552.    return brw_reg(BRW_IMMEDIATE_VALUE,
  553.                   0,
  554.                   0,
  555.                   0,
  556.                   0,
  557.                   type,
  558.                   BRW_VERTICAL_STRIDE_0,
  559.                   BRW_WIDTH_1,
  560.                   BRW_HORIZONTAL_STRIDE_0,
  561.                   0,
  562.                   0);
  563. }
  564.  
  565. /** Construct float immediate register */
  566. static inline struct brw_reg
  567. brw_imm_f(float f)
  568. {
  569.    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
  570.    imm.dw1.f = f;
  571.    return imm;
  572. }
  573.  
  574. /** Construct integer immediate register */
  575. static inline struct brw_reg
  576. brw_imm_d(int d)
  577. {
  578.    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
  579.    imm.dw1.d = d;
  580.    return imm;
  581. }
  582.  
  583. /** Construct uint immediate register */
  584. static inline struct brw_reg
  585. brw_imm_ud(unsigned ud)
  586. {
  587.    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
  588.    imm.dw1.ud = ud;
  589.    return imm;
  590. }
  591.  
  592. /** Construct ushort immediate register */
  593. static inline struct brw_reg
  594. brw_imm_uw(uint16_t uw)
  595. {
  596.    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
  597.    imm.dw1.ud = uw | (uw << 16);
  598.    return imm;
  599. }
  600.  
  601. /** Construct short immediate register */
  602. static inline struct brw_reg
  603. brw_imm_w(int16_t w)
  604. {
  605.    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
  606.    imm.dw1.d = w | (w << 16);
  607.    return imm;
  608. }
  609.  
  610. /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
  611.  * numbers alias with _V and _VF below:
  612.  */
  613.  
  614. /** Construct vector of eight signed half-byte values */
  615. static inline struct brw_reg
  616. brw_imm_v(unsigned v)
  617. {
  618.    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
  619.    imm.vstride = BRW_VERTICAL_STRIDE_0;
  620.    imm.width = BRW_WIDTH_8;
  621.    imm.hstride = BRW_HORIZONTAL_STRIDE_1;
  622.    imm.dw1.ud = v;
  623.    return imm;
  624. }
  625.  
  626. /** Construct vector of four 8-bit float values */
  627. static inline struct brw_reg
  628. brw_imm_vf(unsigned v)
  629. {
  630.    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
  631.    imm.vstride = BRW_VERTICAL_STRIDE_0;
  632.    imm.width = BRW_WIDTH_4;
  633.    imm.hstride = BRW_HORIZONTAL_STRIDE_1;
  634.    imm.dw1.ud = v;
  635.    return imm;
  636. }
  637.  
  638. /**
  639.  * Convert an integer into a "restricted" 8-bit float, used in vector
  640.  * immediates.  The 8-bit floating point format has a sign bit, an
  641.  * excess-3 3-bit exponent, and a 4-bit mantissa.  All integer values
  642.  * from -31 to 31 can be represented exactly.
  643.  */
  644. static inline uint8_t
  645. int_to_float8(int x)
  646. {
  647.    if (x == 0) {
  648.       return 0;
  649.    } else if (x < 0) {
  650.       return 1 << 7 | int_to_float8(-x);
  651.    } else {
  652.       const unsigned exponent = _mesa_logbase2(x);
  653.       const unsigned mantissa = (x - (1 << exponent)) << (4 - exponent);
  654.       assert(exponent <= 4);
  655.       return (exponent + 3) << 4 | mantissa;
  656.    }
  657. }
  658.  
  659. /**
  660.  * Construct a floating-point packed vector immediate from its integer
  661.  * values. \sa int_to_float8()
  662.  */
  663. static inline struct brw_reg
  664. brw_imm_vf4(int v0, int v1, int v2, int v3)
  665. {
  666.    return brw_imm_vf((int_to_float8(v0) << 0) |
  667.                      (int_to_float8(v1) << 8) |
  668.                      (int_to_float8(v2) << 16) |
  669.                      (int_to_float8(v3) << 24));
  670. }
  671.  
  672.  
  673. static inline struct brw_reg
  674. brw_address(struct brw_reg reg)
  675. {
  676.    return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
  677. }
  678.  
  679. /** Construct float[1] general-purpose register */
  680. static inline struct brw_reg
  681. brw_vec1_grf(unsigned nr, unsigned subnr)
  682. {
  683.    return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
  684. }
  685.  
  686. /** Construct float[2] general-purpose register */
  687. static inline struct brw_reg
  688. brw_vec2_grf(unsigned nr, unsigned subnr)
  689. {
  690.    return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
  691. }
  692.  
  693. /** Construct float[4] general-purpose register */
  694. static inline struct brw_reg
  695. brw_vec4_grf(unsigned nr, unsigned subnr)
  696. {
  697.    return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
  698. }
  699.  
  700. /** Construct float[8] general-purpose register */
  701. static inline struct brw_reg
  702. brw_vec8_grf(unsigned nr, unsigned subnr)
  703. {
  704.    return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
  705. }
  706.  
  707. /** Construct float[16] general-purpose register */
  708. static inline struct brw_reg
  709. brw_vec16_grf(unsigned nr, unsigned subnr)
  710. {
  711.    return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
  712. }
  713.  
  714.  
  715. static inline struct brw_reg
  716. brw_uw8_grf(unsigned nr, unsigned subnr)
  717. {
  718.    return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
  719. }
  720.  
  721. static inline struct brw_reg
  722. brw_uw16_grf(unsigned nr, unsigned subnr)
  723. {
  724.    return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
  725. }
  726.  
  727.  
  728. /** Construct null register (usually used for setting condition codes) */
  729. static inline struct brw_reg
  730. brw_null_reg(void)
  731. {
  732.    return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
  733. }
  734.  
  735. static inline struct brw_reg
  736. brw_null_vec(unsigned width)
  737. {
  738.    return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
  739. }
  740.  
  741. static inline struct brw_reg
  742. brw_address_reg(unsigned subnr)
  743. {
  744.    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
  745. }
  746.  
  747. /* If/else instructions break in align16 mode if writemask & swizzle
  748.  * aren't xyzw.  This goes against the convention for other scalar
  749.  * regs:
  750.  */
  751. static inline struct brw_reg
  752. brw_ip_reg(void)
  753. {
  754.    return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
  755.                   BRW_ARF_IP,
  756.                   0,
  757.                   0,
  758.                   0,
  759.                   BRW_REGISTER_TYPE_UD,
  760.                   BRW_VERTICAL_STRIDE_4, /* ? */
  761.                   BRW_WIDTH_1,
  762.                   BRW_HORIZONTAL_STRIDE_0,
  763.                   BRW_SWIZZLE_XYZW, /* NOTE! */
  764.                   WRITEMASK_XYZW); /* NOTE! */
  765. }
  766.  
  767. static inline struct brw_reg
  768. brw_acc_reg(unsigned width)
  769. {
  770.    return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE,
  771.                        BRW_ARF_ACCUMULATOR, 0);
  772. }
  773.  
  774. static inline struct brw_reg
  775. brw_flag_reg(int reg, int subreg)
  776. {
  777.    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
  778.                       BRW_ARF_FLAG + reg, subreg);
  779. }
  780.  
  781. /**
  782.  * Return the mask register present in Gen4-5, or the related register present
  783.  * in Gen7.5 and later hardware referred to as "channel enable" register in
  784.  * the documentation.
  785.  */
  786. static inline struct brw_reg
  787. brw_mask_reg(unsigned subnr)
  788. {
  789.    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
  790. }
  791.  
  792. static inline struct brw_reg
  793. brw_message_reg(unsigned nr)
  794. {
  795.    assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
  796.    return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
  797. }
  798.  
  799. static inline struct brw_reg
  800. brw_uvec_mrf(unsigned width, unsigned nr, unsigned subnr)
  801. {
  802.    return retype(brw_vecn_reg(width, BRW_MESSAGE_REGISTER_FILE, nr, subnr),
  803.                  BRW_REGISTER_TYPE_UD);
  804. }
  805.  
  806. /* This is almost always called with a numeric constant argument, so
  807.  * make things easy to evaluate at compile time:
  808.  */
  809. static inline unsigned cvt(unsigned val)
  810. {
  811.    switch (val) {
  812.    case 0: return 0;
  813.    case 1: return 1;
  814.    case 2: return 2;
  815.    case 4: return 3;
  816.    case 8: return 4;
  817.    case 16: return 5;
  818.    case 32: return 6;
  819.    }
  820.    return 0;
  821. }
  822.  
  823. static inline struct brw_reg
  824. stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
  825. {
  826.    reg.vstride = cvt(vstride);
  827.    reg.width = cvt(width) - 1;
  828.    reg.hstride = cvt(hstride);
  829.    return reg;
  830. }
  831.  
  832. /**
  833.  * Multiply the vertical and horizontal stride of a register by the given
  834.  * factor \a s.
  835.  */
  836. static inline struct brw_reg
  837. spread(struct brw_reg reg, unsigned s)
  838. {
  839.    if (s) {
  840.       assert(is_power_of_two(s));
  841.  
  842.       if (reg.hstride)
  843.          reg.hstride += cvt(s) - 1;
  844.  
  845.       if (reg.vstride)
  846.          reg.vstride += cvt(s) - 1;
  847.  
  848.       return reg;
  849.    } else {
  850.       return stride(reg, 0, 1, 0);
  851.    }
  852. }
  853.  
  854. static inline struct brw_reg
  855. vec16(struct brw_reg reg)
  856. {
  857.    return stride(reg, 16,16,1);
  858. }
  859.  
  860. static inline struct brw_reg
  861. vec8(struct brw_reg reg)
  862. {
  863.    return stride(reg, 8,8,1);
  864. }
  865.  
  866. static inline struct brw_reg
  867. vec4(struct brw_reg reg)
  868. {
  869.    return stride(reg, 4,4,1);
  870. }
  871.  
  872. static inline struct brw_reg
  873. vec2(struct brw_reg reg)
  874. {
  875.    return stride(reg, 2,2,1);
  876. }
  877.  
  878. static inline struct brw_reg
  879. vec1(struct brw_reg reg)
  880. {
  881.    return stride(reg, 0,1,0);
  882. }
  883.  
  884.  
  885. static inline struct brw_reg
  886. get_element(struct brw_reg reg, unsigned elt)
  887. {
  888.    return vec1(suboffset(reg, elt));
  889. }
  890.  
  891. static inline struct brw_reg
  892. get_element_ud(struct brw_reg reg, unsigned elt)
  893. {
  894.    return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
  895. }
  896.  
  897. static inline struct brw_reg
  898. get_element_d(struct brw_reg reg, unsigned elt)
  899. {
  900.    return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
  901. }
  902.  
  903.  
  904. static inline struct brw_reg
  905. brw_swizzle(struct brw_reg reg, unsigned x, unsigned y, unsigned z, unsigned w)
  906. {
  907.    assert(reg.file != BRW_IMMEDIATE_VALUE);
  908.  
  909.    reg.dw1.bits.swizzle = brw_compose_swizzle(BRW_SWIZZLE4(x, y, z, w),
  910.                                               reg.dw1.bits.swizzle);
  911.    return reg;
  912. }
  913.  
  914.  
  915. static inline struct brw_reg
  916. brw_swizzle1(struct brw_reg reg, unsigned x)
  917. {
  918.    return brw_swizzle(reg, x, x, x, x);
  919. }
  920.  
  921. static inline struct brw_reg
  922. brw_writemask(struct brw_reg reg, unsigned mask)
  923. {
  924.    assert(reg.file != BRW_IMMEDIATE_VALUE);
  925.    reg.dw1.bits.writemask &= mask;
  926.    return reg;
  927. }
  928.  
  929. static inline struct brw_reg
  930. brw_set_writemask(struct brw_reg reg, unsigned mask)
  931. {
  932.    assert(reg.file != BRW_IMMEDIATE_VALUE);
  933.    reg.dw1.bits.writemask = mask;
  934.    return reg;
  935. }
  936.  
  937. static inline struct brw_reg
  938. negate(struct brw_reg reg)
  939. {
  940.    reg.negate ^= 1;
  941.    return reg;
  942. }
  943.  
  944. static inline struct brw_reg
  945. brw_abs(struct brw_reg reg)
  946. {
  947.    reg.abs = 1;
  948.    reg.negate = 0;
  949.    return reg;
  950. }
  951.  
  952. /************************************************************************/
  953.  
  954. static inline struct brw_reg
  955. brw_vec4_indirect(unsigned subnr, int offset)
  956. {
  957.    struct brw_reg reg =  brw_vec4_grf(0, 0);
  958.    reg.subnr = subnr;
  959.    reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
  960.    reg.dw1.bits.indirect_offset = offset;
  961.    return reg;
  962. }
  963.  
  964. static inline struct brw_reg
  965. brw_vec1_indirect(unsigned subnr, int offset)
  966. {
  967.    struct brw_reg reg =  brw_vec1_grf(0, 0);
  968.    reg.subnr = subnr;
  969.    reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
  970.    reg.dw1.bits.indirect_offset = offset;
  971.    return reg;
  972. }
  973.  
  974. static inline struct brw_reg
  975. deref_4f(struct brw_indirect ptr, int offset)
  976. {
  977.    return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
  978. }
  979.  
  980. static inline struct brw_reg
  981. deref_1f(struct brw_indirect ptr, int offset)
  982. {
  983.    return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
  984. }
  985.  
  986. static inline struct brw_reg
  987. deref_4b(struct brw_indirect ptr, int offset)
  988. {
  989.    return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
  990. }
  991.  
  992. static inline struct brw_reg
  993. deref_1uw(struct brw_indirect ptr, int offset)
  994. {
  995.    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
  996. }
  997.  
  998. static inline struct brw_reg
  999. deref_1d(struct brw_indirect ptr, int offset)
  1000. {
  1001.    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
  1002. }
  1003.  
  1004. static inline struct brw_reg
  1005. deref_1ud(struct brw_indirect ptr, int offset)
  1006. {
  1007.    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
  1008. }
  1009.  
  1010. static inline struct brw_reg
  1011. get_addr_reg(struct brw_indirect ptr)
  1012. {
  1013.    return brw_address_reg(ptr.addr_subnr);
  1014. }
  1015.  
  1016. static inline struct brw_indirect
  1017. brw_indirect_offset(struct brw_indirect ptr, int offset)
  1018. {
  1019.    ptr.addr_offset += offset;
  1020.    return ptr;
  1021. }
  1022.  
  1023. static inline struct brw_indirect
  1024. brw_indirect(unsigned addr_subnr, int offset)
  1025. {
  1026.    struct brw_indirect ptr;
  1027.    ptr.addr_subnr = addr_subnr;
  1028.    ptr.addr_offset = offset;
  1029.    ptr.pad = 0;
  1030.    return ptr;
  1031. }
  1032.  
  1033. static inline bool
  1034. region_matches(struct brw_reg reg, enum brw_vertical_stride v,
  1035.                enum brw_width w, enum brw_horizontal_stride h)
  1036. {
  1037.    return reg.vstride == v &&
  1038.           reg.width == w &&
  1039.           reg.hstride == h;
  1040. }
  1041.  
  1042. #define has_scalar_region(reg) \
  1043.    region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
  1044.                   BRW_HORIZONTAL_STRIDE_0)
  1045.  
  1046. /* brw_packed_float.c */
  1047. int brw_float_to_vf(float f);
  1048. float brw_vf_to_float(unsigned char vf);
  1049.  
  1050. #ifdef __cplusplus
  1051. }
  1052. #endif
  1053.  
  1054. #endif
  1055.