Home | History | Annotate | Download | only in i965
      1 /*
      2  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
      3  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) 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 <keith (at) tungstengraphics.com>
     30   */
     31 
     32 
     33 #ifndef BRW_EU_H
     34 #define BRW_EU_H
     35 
     36 #include <stdbool.h>
     37 #include "brw_structs.h"
     38 #include "brw_defines.h"
     39 #include "program/prog_instruction.h"
     40 
     41 #ifdef __cplusplus
     42 extern "C" {
     43 #endif
     44 
     45 #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
     46 #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
     47 
     48 #define BRW_SWIZZLE_NOOP      BRW_SWIZZLE4(0,1,2,3)
     49 #define BRW_SWIZZLE_XYZW      BRW_SWIZZLE4(0,1,2,3)
     50 #define BRW_SWIZZLE_XXXX      BRW_SWIZZLE4(0,0,0,0)
     51 #define BRW_SWIZZLE_YYYY      BRW_SWIZZLE4(1,1,1,1)
     52 #define BRW_SWIZZLE_ZZZZ      BRW_SWIZZLE4(2,2,2,2)
     53 #define BRW_SWIZZLE_WWWW      BRW_SWIZZLE4(3,3,3,3)
     54 #define BRW_SWIZZLE_XYXY      BRW_SWIZZLE4(0,1,0,1)
     55 
     56 static inline bool brw_is_single_value_swizzle(int swiz)
     57 {
     58    return (swiz == BRW_SWIZZLE_XXXX ||
     59 	   swiz == BRW_SWIZZLE_YYYY ||
     60 	   swiz == BRW_SWIZZLE_ZZZZ ||
     61 	   swiz == BRW_SWIZZLE_WWWW);
     62 }
     63 
     64 #define REG_SIZE (8*4)
     65 
     66 
     67 /* These aren't hardware structs, just something useful for us to pass around:
     68  *
     69  * Align1 operation has a lot of control over input ranges.  Used in
     70  * WM programs to implement shaders decomposed into "channel serial"
     71  * or "structure of array" form:
     72  */
     73 struct brw_reg
     74 {
     75    GLuint type:4;
     76    GLuint file:2;
     77    GLuint nr:8;
     78    GLuint subnr:5;		/* :1 in align16 */
     79    GLuint negate:1;		/* source only */
     80    GLuint abs:1;		/* source only */
     81    GLuint vstride:4;		/* source only */
     82    GLuint width:3;		/* src only, align1 only */
     83    GLuint hstride:2;   		/* align1 only */
     84    GLuint address_mode:1;	/* relative addressing, hopefully! */
     85    GLuint pad0:1;
     86 
     87    union {
     88       struct {
     89 	 GLuint swizzle:8;		/* src only, align16 only */
     90 	 GLuint writemask:4;		/* dest only, align16 only */
     91 	 GLint  indirect_offset:10;	/* relative addressing offset */
     92 	 GLuint pad1:10;		/* two dwords total */
     93       } bits;
     94 
     95       GLfloat f;
     96       GLint   d;
     97       GLuint ud;
     98    } dw1;
     99 };
    100 
    101 
    102 struct brw_indirect {
    103    GLuint addr_subnr:4;
    104    GLint addr_offset:10;
    105    GLuint pad:18;
    106 };
    107 
    108 
    109 #define BRW_EU_MAX_INSN_STACK 5
    110 
    111 struct brw_compile {
    112    struct brw_instruction *store;
    113    int store_size;
    114    GLuint nr_insn;
    115 
    116    void *mem_ctx;
    117 
    118    /* Allow clients to push/pop instruction state:
    119     */
    120    struct brw_instruction stack[BRW_EU_MAX_INSN_STACK];
    121    bool compressed_stack[BRW_EU_MAX_INSN_STACK];
    122    struct brw_instruction *current;
    123 
    124    GLuint flag_value;
    125    bool single_program_flow;
    126    bool compressed;
    127    struct brw_context *brw;
    128 
    129    /* Control flow stacks:
    130     * - if_stack contains IF and ELSE instructions which must be patched
    131     *   (and popped) once the matching ENDIF instruction is encountered.
    132     *
    133     *   Just store the instruction pointer(an index).
    134     */
    135    int *if_stack;
    136    int if_stack_depth;
    137    int if_stack_array_size;
    138 
    139    /**
    140     * loop_stack contains the instruction pointers of the starts of loops which
    141     * must be patched (and popped) once the matching WHILE instruction is
    142     * encountered.
    143     */
    144    int *loop_stack;
    145    /**
    146     * pre-gen6, the BREAK and CONT instructions had to tell how many IF/ENDIF
    147     * blocks they were popping out of, to fix up the mask stack.  This tracks
    148     * the IF/ENDIF nesting in each current nested loop level.
    149     */
    150    int *if_depth_in_loop;
    151    int loop_stack_depth;
    152    int loop_stack_array_size;
    153 };
    154 
    155 static INLINE int type_sz( GLuint type )
    156 {
    157    switch( type ) {
    158    case BRW_REGISTER_TYPE_UD:
    159    case BRW_REGISTER_TYPE_D:
    160    case BRW_REGISTER_TYPE_F:
    161       return 4;
    162    case BRW_REGISTER_TYPE_HF:
    163    case BRW_REGISTER_TYPE_UW:
    164    case BRW_REGISTER_TYPE_W:
    165       return 2;
    166    case BRW_REGISTER_TYPE_UB:
    167    case BRW_REGISTER_TYPE_B:
    168       return 1;
    169    default:
    170       return 0;
    171    }
    172 }
    173 
    174 /**
    175  * Construct a brw_reg.
    176  * \param file  one of the BRW_x_REGISTER_FILE values
    177  * \param nr  register number/index
    178  * \param subnr  register sub number
    179  * \param type  one of BRW_REGISTER_TYPE_x
    180  * \param vstride  one of BRW_VERTICAL_STRIDE_x
    181  * \param width  one of BRW_WIDTH_x
    182  * \param hstride  one of BRW_HORIZONTAL_STRIDE_x
    183  * \param swizzle  one of BRW_SWIZZLE_x
    184  * \param writemask  WRITEMASK_X/Y/Z/W bitfield
    185  */
    186 static INLINE struct brw_reg brw_reg( GLuint file,
    187                                       GLuint nr,
    188                                       GLuint subnr,
    189                                       GLuint type,
    190                                       GLuint vstride,
    191                                       GLuint width,
    192                                       GLuint hstride,
    193                                       GLuint swizzle,
    194                                       GLuint writemask )
    195 {
    196    struct brw_reg reg;
    197    if (file == BRW_GENERAL_REGISTER_FILE)
    198       assert(nr < BRW_MAX_GRF);
    199    else if (file == BRW_MESSAGE_REGISTER_FILE)
    200       assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
    201    else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
    202       assert(nr <= BRW_ARF_IP);
    203 
    204    reg.type = type;
    205    reg.file = file;
    206    reg.nr = nr;
    207    reg.subnr = subnr * type_sz(type);
    208    reg.negate = 0;
    209    reg.abs = 0;
    210    reg.vstride = vstride;
    211    reg.width = width;
    212    reg.hstride = hstride;
    213    reg.address_mode = BRW_ADDRESS_DIRECT;
    214    reg.pad0 = 0;
    215 
    216    /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
    217     * set swizzle and writemask to W, as the lower bits of subnr will
    218     * be lost when converted to align16.  This is probably too much to
    219     * keep track of as you'd want it adjusted by suboffset(), etc.
    220     * Perhaps fix up when converting to align16?
    221     */
    222    reg.dw1.bits.swizzle = swizzle;
    223    reg.dw1.bits.writemask = writemask;
    224    reg.dw1.bits.indirect_offset = 0;
    225    reg.dw1.bits.pad1 = 0;
    226    return reg;
    227 }
    228 
    229 /** Construct float[16] register */
    230 static INLINE struct brw_reg brw_vec16_reg( GLuint file,
    231 					      GLuint nr,
    232 					      GLuint subnr )
    233 {
    234    return brw_reg(file,
    235 		  nr,
    236 		  subnr,
    237 		  BRW_REGISTER_TYPE_F,
    238 		  BRW_VERTICAL_STRIDE_16,
    239 		  BRW_WIDTH_16,
    240 		  BRW_HORIZONTAL_STRIDE_1,
    241 		  BRW_SWIZZLE_XYZW,
    242 		  WRITEMASK_XYZW);
    243 }
    244 
    245 /** Construct float[8] register */
    246 static INLINE struct brw_reg brw_vec8_reg( GLuint file,
    247 					     GLuint nr,
    248 					     GLuint subnr )
    249 {
    250    return brw_reg(file,
    251 		  nr,
    252 		  subnr,
    253 		  BRW_REGISTER_TYPE_F,
    254 		  BRW_VERTICAL_STRIDE_8,
    255 		  BRW_WIDTH_8,
    256 		  BRW_HORIZONTAL_STRIDE_1,
    257 		  BRW_SWIZZLE_XYZW,
    258 		  WRITEMASK_XYZW);
    259 }
    260 
    261 /** Construct float[4] register */
    262 static INLINE struct brw_reg brw_vec4_reg( GLuint file,
    263 					      GLuint nr,
    264 					      GLuint subnr )
    265 {
    266    return brw_reg(file,
    267 		  nr,
    268 		  subnr,
    269 		  BRW_REGISTER_TYPE_F,
    270 		  BRW_VERTICAL_STRIDE_4,
    271 		  BRW_WIDTH_4,
    272 		  BRW_HORIZONTAL_STRIDE_1,
    273 		  BRW_SWIZZLE_XYZW,
    274 		  WRITEMASK_XYZW);
    275 }
    276 
    277 /** Construct float[2] register */
    278 static INLINE struct brw_reg brw_vec2_reg( GLuint file,
    279 					      GLuint nr,
    280 					      GLuint subnr )
    281 {
    282    return brw_reg(file,
    283 		  nr,
    284 		  subnr,
    285 		  BRW_REGISTER_TYPE_F,
    286 		  BRW_VERTICAL_STRIDE_2,
    287 		  BRW_WIDTH_2,
    288 		  BRW_HORIZONTAL_STRIDE_1,
    289 		  BRW_SWIZZLE_XYXY,
    290 		  WRITEMASK_XY);
    291 }
    292 
    293 /** Construct float[1] register */
    294 static INLINE struct brw_reg brw_vec1_reg( GLuint file,
    295 					     GLuint nr,
    296 					     GLuint subnr )
    297 {
    298    return brw_reg(file,
    299 		  nr,
    300 		  subnr,
    301 		  BRW_REGISTER_TYPE_F,
    302 		  BRW_VERTICAL_STRIDE_0,
    303 		  BRW_WIDTH_1,
    304 		  BRW_HORIZONTAL_STRIDE_0,
    305 		  BRW_SWIZZLE_XXXX,
    306 		  WRITEMASK_X);
    307 }
    308 
    309 
    310 static INLINE struct brw_reg retype( struct brw_reg reg,
    311 				       GLuint type )
    312 {
    313    reg.type = type;
    314    return reg;
    315 }
    316 
    317 static inline struct brw_reg
    318 sechalf(struct brw_reg reg)
    319 {
    320    if (reg.vstride)
    321       reg.nr++;
    322    return reg;
    323 }
    324 
    325 static INLINE struct brw_reg suboffset( struct brw_reg reg,
    326 					  GLuint delta )
    327 {
    328    reg.subnr += delta * type_sz(reg.type);
    329    return reg;
    330 }
    331 
    332 
    333 static INLINE struct brw_reg offset( struct brw_reg reg,
    334 				       GLuint delta )
    335 {
    336    reg.nr += delta;
    337    return reg;
    338 }
    339 
    340 
    341 static INLINE struct brw_reg byte_offset( struct brw_reg reg,
    342 					    GLuint bytes )
    343 {
    344    GLuint newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
    345    reg.nr = newoffset / REG_SIZE;
    346    reg.subnr = newoffset % REG_SIZE;
    347    return reg;
    348 }
    349 
    350 
    351 /** Construct unsigned word[16] register */
    352 static INLINE struct brw_reg brw_uw16_reg( GLuint file,
    353 					     GLuint nr,
    354 					     GLuint subnr )
    355 {
    356    return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
    357 }
    358 
    359 /** Construct unsigned word[8] register */
    360 static INLINE struct brw_reg brw_uw8_reg( GLuint file,
    361 					    GLuint nr,
    362 					    GLuint subnr )
    363 {
    364    return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
    365 }
    366 
    367 /** Construct unsigned word[1] register */
    368 static INLINE struct brw_reg brw_uw1_reg( GLuint file,
    369 					    GLuint nr,
    370 					    GLuint subnr )
    371 {
    372    return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
    373 }
    374 
    375 static INLINE struct brw_reg brw_imm_reg( GLuint type )
    376 {
    377    return brw_reg( BRW_IMMEDIATE_VALUE,
    378 		   0,
    379 		   0,
    380 		   type,
    381 		   BRW_VERTICAL_STRIDE_0,
    382 		   BRW_WIDTH_1,
    383 		   BRW_HORIZONTAL_STRIDE_0,
    384 		   0,
    385 		   0);
    386 }
    387 
    388 /** Construct float immediate register */
    389 static INLINE struct brw_reg brw_imm_f( GLfloat f )
    390 {
    391    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
    392    imm.dw1.f = f;
    393    return imm;
    394 }
    395 
    396 /** Construct integer immediate register */
    397 static INLINE struct brw_reg brw_imm_d( GLint d )
    398 {
    399    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
    400    imm.dw1.d = d;
    401    return imm;
    402 }
    403 
    404 /** Construct uint immediate register */
    405 static INLINE struct brw_reg brw_imm_ud( GLuint ud )
    406 {
    407    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
    408    imm.dw1.ud = ud;
    409    return imm;
    410 }
    411 
    412 /** Construct ushort immediate register */
    413 static INLINE struct brw_reg brw_imm_uw( GLushort uw )
    414 {
    415    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
    416    imm.dw1.ud = uw | (uw << 16);
    417    return imm;
    418 }
    419 
    420 /** Construct short immediate register */
    421 static INLINE struct brw_reg brw_imm_w( GLshort w )
    422 {
    423    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
    424    imm.dw1.d = w | (w << 16);
    425    return imm;
    426 }
    427 
    428 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
    429  * numbers alias with _V and _VF below:
    430  */
    431 
    432 /** Construct vector of eight signed half-byte values */
    433 static INLINE struct brw_reg brw_imm_v( GLuint v )
    434 {
    435    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
    436    imm.vstride = BRW_VERTICAL_STRIDE_0;
    437    imm.width = BRW_WIDTH_8;
    438    imm.hstride = BRW_HORIZONTAL_STRIDE_1;
    439    imm.dw1.ud = v;
    440    return imm;
    441 }
    442 
    443 /** Construct vector of four 8-bit float values */
    444 static INLINE struct brw_reg brw_imm_vf( GLuint v )
    445 {
    446    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
    447    imm.vstride = BRW_VERTICAL_STRIDE_0;
    448    imm.width = BRW_WIDTH_4;
    449    imm.hstride = BRW_HORIZONTAL_STRIDE_1;
    450    imm.dw1.ud = v;
    451    return imm;
    452 }
    453 
    454 #define VF_ZERO 0x0
    455 #define VF_ONE  0x30
    456 #define VF_NEG  (1<<7)
    457 
    458 static INLINE struct brw_reg brw_imm_vf4( GLuint v0,
    459 					    GLuint v1,
    460 					    GLuint v2,
    461 					    GLuint v3)
    462 {
    463    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
    464    imm.vstride = BRW_VERTICAL_STRIDE_0;
    465    imm.width = BRW_WIDTH_4;
    466    imm.hstride = BRW_HORIZONTAL_STRIDE_1;
    467    imm.dw1.ud = ((v0 << 0) |
    468 		 (v1 << 8) |
    469 		 (v2 << 16) |
    470 		 (v3 << 24));
    471    return imm;
    472 }
    473 
    474 
    475 static INLINE struct brw_reg brw_address( struct brw_reg reg )
    476 {
    477    return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
    478 }
    479 
    480 /** Construct float[1] general-purpose register */
    481 static INLINE struct brw_reg brw_vec1_grf( GLuint nr, GLuint subnr )
    482 {
    483    return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
    484 }
    485 
    486 /** Construct float[2] general-purpose register */
    487 static INLINE struct brw_reg brw_vec2_grf( GLuint nr, GLuint subnr )
    488 {
    489    return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
    490 }
    491 
    492 /** Construct float[4] general-purpose register */
    493 static INLINE struct brw_reg brw_vec4_grf( GLuint nr, GLuint subnr )
    494 {
    495    return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
    496 }
    497 
    498 /** Construct float[8] general-purpose register */
    499 static INLINE struct brw_reg brw_vec8_grf( GLuint nr, GLuint subnr )
    500 {
    501    return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
    502 }
    503 
    504 
    505 static INLINE struct brw_reg brw_uw8_grf( GLuint nr, GLuint subnr )
    506 {
    507    return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
    508 }
    509 
    510 static INLINE struct brw_reg brw_uw16_grf( GLuint nr, GLuint subnr )
    511 {
    512    return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
    513 }
    514 
    515 
    516 /** Construct null register (usually used for setting condition codes) */
    517 static INLINE struct brw_reg brw_null_reg( void )
    518 {
    519    return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
    520 		       BRW_ARF_NULL,
    521 		       0);
    522 }
    523 
    524 static INLINE struct brw_reg brw_address_reg( GLuint subnr )
    525 {
    526    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
    527 		      BRW_ARF_ADDRESS,
    528 		      subnr);
    529 }
    530 
    531 /* If/else instructions break in align16 mode if writemask & swizzle
    532  * aren't xyzw.  This goes against the convention for other scalar
    533  * regs:
    534  */
    535 static INLINE struct brw_reg brw_ip_reg( void )
    536 {
    537    return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
    538 		  BRW_ARF_IP,
    539 		  0,
    540 		  BRW_REGISTER_TYPE_UD,
    541 		  BRW_VERTICAL_STRIDE_4, /* ? */
    542 		  BRW_WIDTH_1,
    543 		  BRW_HORIZONTAL_STRIDE_0,
    544 		  BRW_SWIZZLE_XYZW, /* NOTE! */
    545 		  WRITEMASK_XYZW); /* NOTE! */
    546 }
    547 
    548 static INLINE struct brw_reg brw_acc_reg( void )
    549 {
    550    return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
    551 		       BRW_ARF_ACCUMULATOR,
    552 		       0);
    553 }
    554 
    555 static INLINE struct brw_reg brw_notification_1_reg(void)
    556 {
    557 
    558    return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
    559 		  BRW_ARF_NOTIFICATION_COUNT,
    560 		  1,
    561 		  BRW_REGISTER_TYPE_UD,
    562 		  BRW_VERTICAL_STRIDE_0,
    563 		  BRW_WIDTH_1,
    564 		  BRW_HORIZONTAL_STRIDE_0,
    565 		  BRW_SWIZZLE_XXXX,
    566 		  WRITEMASK_X);
    567 }
    568 
    569 
    570 static INLINE struct brw_reg brw_flag_reg( void )
    571 {
    572    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
    573 		      BRW_ARF_FLAG,
    574 		      0);
    575 }
    576 
    577 
    578 static INLINE struct brw_reg brw_mask_reg( GLuint subnr )
    579 {
    580    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
    581 		      BRW_ARF_MASK,
    582 		      subnr);
    583 }
    584 
    585 static INLINE struct brw_reg brw_message_reg( GLuint nr )
    586 {
    587    assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
    588    return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE,
    589 		       nr,
    590 		       0);
    591 }
    592 
    593 
    594 
    595 
    596 /* This is almost always called with a numeric constant argument, so
    597  * make things easy to evaluate at compile time:
    598  */
    599 static INLINE GLuint cvt( GLuint val )
    600 {
    601    switch (val) {
    602    case 0: return 0;
    603    case 1: return 1;
    604    case 2: return 2;
    605    case 4: return 3;
    606    case 8: return 4;
    607    case 16: return 5;
    608    case 32: return 6;
    609    }
    610    return 0;
    611 }
    612 
    613 static INLINE struct brw_reg stride( struct brw_reg reg,
    614 				       GLuint vstride,
    615 				       GLuint width,
    616 				       GLuint hstride )
    617 {
    618    reg.vstride = cvt(vstride);
    619    reg.width = cvt(width) - 1;
    620    reg.hstride = cvt(hstride);
    621    return reg;
    622 }
    623 
    624 
    625 static INLINE struct brw_reg vec16( struct brw_reg reg )
    626 {
    627    return stride(reg, 16,16,1);
    628 }
    629 
    630 static INLINE struct brw_reg vec8( struct brw_reg reg )
    631 {
    632    return stride(reg, 8,8,1);
    633 }
    634 
    635 static INLINE struct brw_reg vec4( struct brw_reg reg )
    636 {
    637    return stride(reg, 4,4,1);
    638 }
    639 
    640 static INLINE struct brw_reg vec2( struct brw_reg reg )
    641 {
    642    return stride(reg, 2,2,1);
    643 }
    644 
    645 static INLINE struct brw_reg vec1( struct brw_reg reg )
    646 {
    647    return stride(reg, 0,1,0);
    648 }
    649 
    650 
    651 static INLINE struct brw_reg get_element( struct brw_reg reg, GLuint elt )
    652 {
    653    return vec1(suboffset(reg, elt));
    654 }
    655 
    656 static INLINE struct brw_reg get_element_ud( struct brw_reg reg, GLuint elt )
    657 {
    658    return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
    659 }
    660 
    661 static INLINE struct brw_reg get_element_d( struct brw_reg reg, GLuint elt )
    662 {
    663    return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
    664 }
    665 
    666 
    667 static INLINE struct brw_reg brw_swizzle( struct brw_reg reg,
    668 					    GLuint x,
    669 					    GLuint y,
    670 					    GLuint z,
    671 					    GLuint w)
    672 {
    673    assert(reg.file != BRW_IMMEDIATE_VALUE);
    674 
    675    reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
    676 				       BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
    677 				       BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
    678 				       BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
    679    return reg;
    680 }
    681 
    682 
    683 static INLINE struct brw_reg brw_swizzle1( struct brw_reg reg,
    684 					     GLuint x )
    685 {
    686    return brw_swizzle(reg, x, x, x, x);
    687 }
    688 
    689 static INLINE struct brw_reg brw_writemask( struct brw_reg reg,
    690 					      GLuint mask )
    691 {
    692    assert(reg.file != BRW_IMMEDIATE_VALUE);
    693    reg.dw1.bits.writemask &= mask;
    694    return reg;
    695 }
    696 
    697 static INLINE struct brw_reg brw_set_writemask( struct brw_reg reg,
    698 						  GLuint mask )
    699 {
    700    assert(reg.file != BRW_IMMEDIATE_VALUE);
    701    reg.dw1.bits.writemask = mask;
    702    return reg;
    703 }
    704 
    705 static INLINE struct brw_reg negate( struct brw_reg reg )
    706 {
    707    reg.negate ^= 1;
    708    return reg;
    709 }
    710 
    711 static INLINE struct brw_reg brw_abs( struct brw_reg reg )
    712 {
    713    reg.abs = 1;
    714    reg.negate = 0;
    715    return reg;
    716 }
    717 
    718 /***********************************************************************
    719  */
    720 static INLINE struct brw_reg brw_vec4_indirect( GLuint subnr,
    721 						  GLint offset )
    722 {
    723    struct brw_reg reg =  brw_vec4_grf(0, 0);
    724    reg.subnr = subnr;
    725    reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
    726    reg.dw1.bits.indirect_offset = offset;
    727    return reg;
    728 }
    729 
    730 static INLINE struct brw_reg brw_vec1_indirect( GLuint subnr,
    731 						  GLint offset )
    732 {
    733    struct brw_reg reg =  brw_vec1_grf(0, 0);
    734    reg.subnr = subnr;
    735    reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
    736    reg.dw1.bits.indirect_offset = offset;
    737    return reg;
    738 }
    739 
    740 static INLINE struct brw_reg deref_4f(struct brw_indirect ptr, GLint offset)
    741 {
    742    return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
    743 }
    744 
    745 static INLINE struct brw_reg deref_1f(struct brw_indirect ptr, GLint offset)
    746 {
    747    return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
    748 }
    749 
    750 static INLINE struct brw_reg deref_4b(struct brw_indirect ptr, GLint offset)
    751 {
    752    return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
    753 }
    754 
    755 static INLINE struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
    756 {
    757    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
    758 }
    759 
    760 static INLINE struct brw_reg deref_1d(struct brw_indirect ptr, GLint offset)
    761 {
    762    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
    763 }
    764 
    765 static INLINE struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
    766 {
    767    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
    768 }
    769 
    770 static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr)
    771 {
    772    return brw_address_reg(ptr.addr_subnr);
    773 }
    774 
    775 static INLINE struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, GLint offset )
    776 {
    777    ptr.addr_offset += offset;
    778    return ptr;
    779 }
    780 
    781 static INLINE struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offset )
    782 {
    783    struct brw_indirect ptr;
    784    ptr.addr_subnr = addr_subnr;
    785    ptr.addr_offset = offset;
    786    ptr.pad = 0;
    787    return ptr;
    788 }
    789 
    790 /** Do two brw_regs refer to the same register? */
    791 static INLINE bool
    792 brw_same_reg(struct brw_reg r1, struct brw_reg r2)
    793 {
    794    return r1.file == r2.file && r1.nr == r2.nr;
    795 }
    796 
    797 static INLINE struct brw_instruction *current_insn( struct brw_compile *p)
    798 {
    799    return &p->store[p->nr_insn];
    800 }
    801 
    802 void brw_pop_insn_state( struct brw_compile *p );
    803 void brw_push_insn_state( struct brw_compile *p );
    804 void brw_set_mask_control( struct brw_compile *p, GLuint value );
    805 void brw_set_saturate( struct brw_compile *p, bool enable );
    806 void brw_set_access_mode( struct brw_compile *p, GLuint access_mode );
    807 void brw_set_compression_control(struct brw_compile *p, enum brw_compression c);
    808 void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value );
    809 void brw_set_predicate_control( struct brw_compile *p, GLuint pc );
    810 void brw_set_predicate_inverse(struct brw_compile *p, bool predicate_inverse);
    811 void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional );
    812 void brw_set_acc_write_control(struct brw_compile *p, GLuint value);
    813 
    814 void brw_init_compile(struct brw_context *, struct brw_compile *p,
    815 		      void *mem_ctx);
    816 const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz );
    817 
    818 struct brw_instruction *brw_next_insn(struct brw_compile *p, GLuint opcode);
    819 void brw_set_dest(struct brw_compile *p, struct brw_instruction *insn,
    820 		  struct brw_reg dest);
    821 void brw_set_src0(struct brw_compile *p, struct brw_instruction *insn,
    822 		  struct brw_reg reg);
    823 
    824 void gen6_resolve_implied_move(struct brw_compile *p,
    825 			       struct brw_reg *src,
    826 			       GLuint msg_reg_nr);
    827 
    828 /* Helpers for regular instructions:
    829  */
    830 #define ALU1(OP)					\
    831 struct brw_instruction *brw_##OP(struct brw_compile *p,	\
    832 	      struct brw_reg dest,			\
    833 	      struct brw_reg src0);
    834 
    835 #define ALU2(OP)					\
    836 struct brw_instruction *brw_##OP(struct brw_compile *p,	\
    837 	      struct brw_reg dest,			\
    838 	      struct brw_reg src0,			\
    839 	      struct brw_reg src1);
    840 
    841 #define ALU3(OP)					\
    842 struct brw_instruction *brw_##OP(struct brw_compile *p,	\
    843 	      struct brw_reg dest,			\
    844 	      struct brw_reg src0,			\
    845 	      struct brw_reg src1,			\
    846 	      struct brw_reg src2);
    847 
    848 #define ROUND(OP) \
    849 void brw_##OP(struct brw_compile *p, struct brw_reg dest, struct brw_reg src0);
    850 
    851 ALU1(MOV)
    852 ALU2(SEL)
    853 ALU1(NOT)
    854 ALU2(AND)
    855 ALU2(OR)
    856 ALU2(XOR)
    857 ALU2(SHR)
    858 ALU2(SHL)
    859 ALU2(RSR)
    860 ALU2(RSL)
    861 ALU2(ASR)
    862 ALU2(JMPI)
    863 ALU2(ADD)
    864 ALU2(AVG)
    865 ALU2(MUL)
    866 ALU1(FRC)
    867 ALU1(RNDD)
    868 ALU2(MAC)
    869 ALU2(MACH)
    870 ALU1(LZD)
    871 ALU2(DP4)
    872 ALU2(DPH)
    873 ALU2(DP3)
    874 ALU2(DP2)
    875 ALU2(LINE)
    876 ALU2(PLN)
    877 ALU3(MAD)
    878 
    879 ROUND(RNDZ)
    880 ROUND(RNDE)
    881 
    882 #undef ALU1
    883 #undef ALU2
    884 #undef ALU3
    885 #undef ROUND
    886 
    887 
    888 /* Helpers for SEND instruction:
    889  */
    890 void brw_set_sampler_message(struct brw_compile *p,
    891                              struct brw_instruction *insn,
    892                              GLuint binding_table_index,
    893                              GLuint sampler,
    894                              GLuint msg_type,
    895                              GLuint response_length,
    896                              GLuint msg_length,
    897                              GLuint header_present,
    898                              GLuint simd_mode,
    899                              GLuint return_format);
    900 
    901 void brw_set_dp_read_message(struct brw_compile *p,
    902 			     struct brw_instruction *insn,
    903 			     GLuint binding_table_index,
    904 			     GLuint msg_control,
    905 			     GLuint msg_type,
    906 			     GLuint target_cache,
    907 			     GLuint msg_length,
    908 			     GLuint response_length);
    909 
    910 void brw_set_dp_write_message(struct brw_compile *p,
    911 			      struct brw_instruction *insn,
    912 			      GLuint binding_table_index,
    913 			      GLuint msg_control,
    914 			      GLuint msg_type,
    915 			      GLuint msg_length,
    916 			      bool header_present,
    917 			      GLuint last_render_target,
    918 			      GLuint response_length,
    919 			      GLuint end_of_thread,
    920 			      GLuint send_commit_msg);
    921 
    922 void brw_urb_WRITE(struct brw_compile *p,
    923 		   struct brw_reg dest,
    924 		   GLuint msg_reg_nr,
    925 		   struct brw_reg src0,
    926 		   bool allocate,
    927 		   bool used,
    928 		   GLuint msg_length,
    929 		   GLuint response_length,
    930 		   bool eot,
    931 		   bool writes_complete,
    932 		   GLuint offset,
    933 		   GLuint swizzle);
    934 
    935 void brw_ff_sync(struct brw_compile *p,
    936 		   struct brw_reg dest,
    937 		   GLuint msg_reg_nr,
    938 		   struct brw_reg src0,
    939 		   bool allocate,
    940 		   GLuint response_length,
    941 		   bool eot);
    942 
    943 void brw_svb_write(struct brw_compile *p,
    944                    struct brw_reg dest,
    945                    GLuint msg_reg_nr,
    946                    struct brw_reg src0,
    947                    GLuint binding_table_index,
    948                    bool   send_commit_msg);
    949 
    950 void brw_fb_WRITE(struct brw_compile *p,
    951 		  int dispatch_width,
    952 		   GLuint msg_reg_nr,
    953 		   struct brw_reg src0,
    954 		   GLuint msg_control,
    955 		   GLuint binding_table_index,
    956 		   GLuint msg_length,
    957 		   GLuint response_length,
    958 		   bool eot,
    959 		   bool header_present);
    960 
    961 void brw_SAMPLE(struct brw_compile *p,
    962 		struct brw_reg dest,
    963 		GLuint msg_reg_nr,
    964 		struct brw_reg src0,
    965 		GLuint binding_table_index,
    966 		GLuint sampler,
    967 		GLuint writemask,
    968 		GLuint msg_type,
    969 		GLuint response_length,
    970 		GLuint msg_length,
    971 		GLuint header_present,
    972 		GLuint simd_mode,
    973 		GLuint return_format);
    974 
    975 void brw_math_16( struct brw_compile *p,
    976 		  struct brw_reg dest,
    977 		  GLuint function,
    978 		  GLuint msg_reg_nr,
    979 		  struct brw_reg src,
    980 		  GLuint precision );
    981 
    982 void brw_math( struct brw_compile *p,
    983 	       struct brw_reg dest,
    984 	       GLuint function,
    985 	       GLuint msg_reg_nr,
    986 	       struct brw_reg src,
    987 	       GLuint data_type,
    988 	       GLuint precision );
    989 
    990 void brw_math2(struct brw_compile *p,
    991 	       struct brw_reg dest,
    992 	       GLuint function,
    993 	       struct brw_reg src0,
    994 	       struct brw_reg src1);
    995 
    996 void brw_oword_block_read(struct brw_compile *p,
    997 			  struct brw_reg dest,
    998 			  struct brw_reg mrf,
    999 			  uint32_t offset,
   1000 			  uint32_t bind_table_index);
   1001 
   1002 void brw_oword_block_read_scratch(struct brw_compile *p,
   1003 				  struct brw_reg dest,
   1004 				  struct brw_reg mrf,
   1005 				  int num_regs,
   1006 				  GLuint offset);
   1007 
   1008 void brw_oword_block_write_scratch(struct brw_compile *p,
   1009 				   struct brw_reg mrf,
   1010 				   int num_regs,
   1011 				   GLuint offset);
   1012 
   1013 void brw_dword_scattered_read(struct brw_compile *p,
   1014 			      struct brw_reg dest,
   1015 			      struct brw_reg mrf,
   1016 			      uint32_t bind_table_index);
   1017 
   1018 void brw_dp_READ_4_vs( struct brw_compile *p,
   1019                        struct brw_reg dest,
   1020                        GLuint location,
   1021                        GLuint bind_table_index );
   1022 
   1023 void brw_dp_READ_4_vs_relative(struct brw_compile *p,
   1024 			       struct brw_reg dest,
   1025 			       struct brw_reg addrReg,
   1026 			       GLuint offset,
   1027 			       GLuint bind_table_index);
   1028 
   1029 /* If/else/endif.  Works by manipulating the execution flags on each
   1030  * channel.
   1031  */
   1032 struct brw_instruction *brw_IF(struct brw_compile *p,
   1033 			       GLuint execute_size);
   1034 struct brw_instruction *gen6_IF(struct brw_compile *p, uint32_t conditional,
   1035 				struct brw_reg src0, struct brw_reg src1);
   1036 
   1037 void brw_ELSE(struct brw_compile *p);
   1038 void brw_ENDIF(struct brw_compile *p);
   1039 
   1040 /* DO/WHILE loops:
   1041  */
   1042 struct brw_instruction *brw_DO(struct brw_compile *p,
   1043 			       GLuint execute_size);
   1044 
   1045 struct brw_instruction *brw_WHILE(struct brw_compile *p);
   1046 
   1047 struct brw_instruction *brw_BREAK(struct brw_compile *p);
   1048 struct brw_instruction *brw_CONT(struct brw_compile *p);
   1049 struct brw_instruction *gen6_CONT(struct brw_compile *p);
   1050 /* Forward jumps:
   1051  */
   1052 void brw_land_fwd_jump(struct brw_compile *p, int jmp_insn_idx);
   1053 
   1054 
   1055 
   1056 void brw_NOP(struct brw_compile *p);
   1057 
   1058 void brw_WAIT(struct brw_compile *p);
   1059 
   1060 /* Special case: there is never a destination, execution size will be
   1061  * taken from src0:
   1062  */
   1063 void brw_CMP(struct brw_compile *p,
   1064 	     struct brw_reg dest,
   1065 	     GLuint conditional,
   1066 	     struct brw_reg src0,
   1067 	     struct brw_reg src1);
   1068 
   1069 void brw_print_reg( struct brw_reg reg );
   1070 
   1071 
   1072 /***********************************************************************
   1073  * brw_eu_util.c:
   1074  */
   1075 
   1076 void brw_copy_indirect_to_indirect(struct brw_compile *p,
   1077 				   struct brw_indirect dst_ptr,
   1078 				   struct brw_indirect src_ptr,
   1079 				   GLuint count);
   1080 
   1081 void brw_copy_from_indirect(struct brw_compile *p,
   1082 			    struct brw_reg dst,
   1083 			    struct brw_indirect ptr,
   1084 			    GLuint count);
   1085 
   1086 void brw_copy4(struct brw_compile *p,
   1087 	       struct brw_reg dst,
   1088 	       struct brw_reg src,
   1089 	       GLuint count);
   1090 
   1091 void brw_copy8(struct brw_compile *p,
   1092 	       struct brw_reg dst,
   1093 	       struct brw_reg src,
   1094 	       GLuint count);
   1095 
   1096 void brw_math_invert( struct brw_compile *p,
   1097 		      struct brw_reg dst,
   1098 		      struct brw_reg src);
   1099 
   1100 void brw_set_src1(struct brw_compile *p,
   1101 		  struct brw_instruction *insn,
   1102 		  struct brw_reg reg);
   1103 
   1104 void brw_set_uip_jip(struct brw_compile *p);
   1105 
   1106 uint32_t brw_swap_cmod(uint32_t cmod);
   1107 
   1108 /* brw_optimize.c */
   1109 void brw_optimize(struct brw_compile *p);
   1110 void brw_remove_duplicate_mrf_moves(struct brw_compile *p);
   1111 void brw_remove_grf_to_mrf_moves(struct brw_compile *p);
   1112 
   1113 #ifdef __cplusplus
   1114 }
   1115 #endif
   1116 
   1117 #endif
   1118