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@tungstengraphics.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 <assert.h>
47 #include "brw_defines.h"
48 
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52 
53 /** Number of general purpose registers (VS, WM, etc) */
54 #define BRW_MAX_GRF 128
55 
56 /**
57  * First GRF used for the MRF hack.
58  *
59  * On gen7, MRFs are no longer used, and contiguous GRFs are used instead.  We
60  * haven't converted our compiler to be aware of this, so it asks for MRFs and
61  * brw_eu_emit.c quietly converts them to be accesses of the top GRFs.  The
62  * register allocators have to be careful of this to avoid corrupting the "MRF"s
63  * with actual GRF allocations.
64  */
65 #define GEN7_MRF_HACK_START 112
66 
67 /** Number of message register file registers */
68 #define BRW_MAX_MRF 16
69 
70 #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
71 #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
72 
73 #define BRW_SWIZZLE_NOOP      BRW_SWIZZLE4(0,1,2,3)
74 #define BRW_SWIZZLE_XYZW      BRW_SWIZZLE4(0,1,2,3)
75 #define BRW_SWIZZLE_XXXX      BRW_SWIZZLE4(0,0,0,0)
76 #define BRW_SWIZZLE_YYYY      BRW_SWIZZLE4(1,1,1,1)
77 #define BRW_SWIZZLE_ZZZZ      BRW_SWIZZLE4(2,2,2,2)
78 #define BRW_SWIZZLE_WWWW      BRW_SWIZZLE4(3,3,3,3)
79 #define BRW_SWIZZLE_XYXY      BRW_SWIZZLE4(0,1,0,1)
80 
81 static inline bool
brw_is_single_value_swizzle(int swiz)82 brw_is_single_value_swizzle(int swiz)
83 {
84    return (swiz == BRW_SWIZZLE_XXXX ||
85            swiz == BRW_SWIZZLE_YYYY ||
86            swiz == BRW_SWIZZLE_ZZZZ ||
87            swiz == BRW_SWIZZLE_WWWW);
88 }
89 
90 #define BRW_WRITEMASK_X 0x1
91 #define BRW_WRITEMASK_Y 0x2
92 #define BRW_WRITEMASK_Z 0x4
93 #define BRW_WRITEMASK_W 0x8
94 
95 #define BRW_WRITEMASK_XY (BRW_WRITEMASK_X | BRW_WRITEMASK_Y)
96 #define BRW_WRITEMASK_XZ (BRW_WRITEMASK_X | BRW_WRITEMASK_Z)
97 #define BRW_WRITEMASK_XW (BRW_WRITEMASK_X | BRW_WRITEMASK_W)
98 #define BRW_WRITEMASK_YW (BRW_WRITEMASK_Y | BRW_WRITEMASK_W)
99 #define BRW_WRITEMASK_ZW (BRW_WRITEMASK_Z | BRW_WRITEMASK_W)
100 #define BRW_WRITEMASK_XYZ (BRW_WRITEMASK_X | BRW_WRITEMASK_Y | BRW_WRITEMASK_Z)
101 #define BRW_WRITEMASK_XYZW (BRW_WRITEMASK_X | BRW_WRITEMASK_Y | \
102                             BRW_WRITEMASK_Z | BRW_WRITEMASK_W)
103 
104 #define REG_SIZE (8*4)
105 
106 /* These aren't hardware structs, just something useful for us to pass around:
107  *
108  * Align1 operation has a lot of control over input ranges.  Used in
109  * WM programs to implement shaders decomposed into "channel serial"
110  * or "structure of array" form:
111  */
112 struct brw_reg {
113    unsigned type:4;
114    unsigned file:2;
115    unsigned nr:8;
116    unsigned subnr:5;              /* :1 in align16 */
117    unsigned negate:1;             /* source only */
118    unsigned abs:1;                /* source only */
119    unsigned vstride:4;            /* source only */
120    unsigned width:3;              /* src only, align1 only */
121    unsigned hstride:2;            /* align1 only */
122    unsigned address_mode:1;       /* relative addressing, hopefully! */
123    unsigned pad0:1;
124 
125    union {
126       struct {
127          unsigned swizzle:8;      /* src only, align16 only */
128          unsigned writemask:4;    /* dest only, align16 only */
129          int  indirect_offset:10; /* relative addressing offset */
130          unsigned pad1:10;        /* two dwords total */
131       } bits;
132 
133       float f;
134       int   d;
135       unsigned ud;
136    } dw1;
137 };
138 
139 
140 struct brw_indirect {
141    unsigned addr_subnr:4;
142    int addr_offset:10;
143    unsigned pad:18;
144 };
145 
146 
147 static inline int
type_sz(unsigned type)148 type_sz(unsigned type)
149 {
150    switch(type) {
151    case BRW_REGISTER_TYPE_UD:
152    case BRW_REGISTER_TYPE_D:
153    case BRW_REGISTER_TYPE_F:
154       return 4;
155    case BRW_REGISTER_TYPE_HF:
156    case BRW_REGISTER_TYPE_UW:
157    case BRW_REGISTER_TYPE_W:
158       return 2;
159    case BRW_REGISTER_TYPE_UB:
160    case BRW_REGISTER_TYPE_B:
161       return 1;
162    default:
163       return 0;
164    }
165 }
166 
167 /**
168  * Construct a brw_reg.
169  * \param file      one of the BRW_x_REGISTER_FILE values
170  * \param nr        register number/index
171  * \param subnr     register sub number
172  * \param type      one of BRW_REGISTER_TYPE_x
173  * \param vstride   one of BRW_VERTICAL_STRIDE_x
174  * \param width     one of BRW_WIDTH_x
175  * \param hstride   one of BRW_HORIZONTAL_STRIDE_x
176  * \param swizzle   one of BRW_SWIZZLE_x
177  * \param writemask BRW_WRITEMASK_X/Y/Z/W bitfield
178  */
179 static inline struct brw_reg
brw_reg(unsigned file,unsigned nr,unsigned subnr,unsigned type,unsigned vstride,unsigned width,unsigned hstride,unsigned swizzle,unsigned writemask)180 brw_reg(unsigned file,
181         unsigned nr,
182         unsigned subnr,
183         unsigned type,
184         unsigned vstride,
185         unsigned width,
186         unsigned hstride,
187         unsigned swizzle,
188         unsigned writemask)
189 {
190    struct brw_reg reg;
191    if (file == BRW_GENERAL_REGISTER_FILE)
192       assert(nr < BRW_MAX_GRF);
193    else if (file == BRW_MESSAGE_REGISTER_FILE)
194       assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
195    else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
196       assert(nr <= BRW_ARF_TIMESTAMP);
197 
198    reg.type = type;
199    reg.file = file;
200    reg.nr = nr;
201    reg.subnr = subnr * type_sz(type);
202    reg.negate = 0;
203    reg.abs = 0;
204    reg.vstride = vstride;
205    reg.width = width;
206    reg.hstride = hstride;
207    reg.address_mode = BRW_ADDRESS_DIRECT;
208    reg.pad0 = 0;
209 
210    /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
211     * set swizzle and writemask to W, as the lower bits of subnr will
212     * be lost when converted to align16.  This is probably too much to
213     * keep track of as you'd want it adjusted by suboffset(), etc.
214     * Perhaps fix up when converting to align16?
215     */
216    reg.dw1.bits.swizzle = swizzle;
217    reg.dw1.bits.writemask = writemask;
218    reg.dw1.bits.indirect_offset = 0;
219    reg.dw1.bits.pad1 = 0;
220    return reg;
221 }
222 
223 /** Construct float[16] register */
224 static inline struct brw_reg
brw_vec16_reg(unsigned file,unsigned nr,unsigned subnr)225 brw_vec16_reg(unsigned file, unsigned nr, unsigned subnr)
226 {
227    return brw_reg(file,
228                   nr,
229                   subnr,
230                   BRW_REGISTER_TYPE_F,
231                   BRW_VERTICAL_STRIDE_16,
232                   BRW_WIDTH_16,
233                   BRW_HORIZONTAL_STRIDE_1,
234                   BRW_SWIZZLE_XYZW,
235                   BRW_WRITEMASK_XYZW);
236 }
237 
238 /** Construct float[8] register */
239 static inline struct brw_reg
brw_vec8_reg(unsigned file,unsigned nr,unsigned subnr)240 brw_vec8_reg(unsigned file, unsigned nr, unsigned subnr)
241 {
242    return brw_reg(file,
243                   nr,
244                   subnr,
245                   BRW_REGISTER_TYPE_F,
246                   BRW_VERTICAL_STRIDE_8,
247                   BRW_WIDTH_8,
248                   BRW_HORIZONTAL_STRIDE_1,
249                   BRW_SWIZZLE_XYZW,
250                   BRW_WRITEMASK_XYZW);
251 }
252 
253 /** Construct float[4] register */
254 static inline struct brw_reg
brw_vec4_reg(unsigned file,unsigned nr,unsigned subnr)255 brw_vec4_reg(unsigned file, unsigned nr, unsigned subnr)
256 {
257    return brw_reg(file,
258                   nr,
259                   subnr,
260                   BRW_REGISTER_TYPE_F,
261                   BRW_VERTICAL_STRIDE_4,
262                   BRW_WIDTH_4,
263                   BRW_HORIZONTAL_STRIDE_1,
264                   BRW_SWIZZLE_XYZW,
265                   BRW_WRITEMASK_XYZW);
266 }
267 
268 /** Construct float[2] register */
269 static inline struct brw_reg
brw_vec2_reg(unsigned file,unsigned nr,unsigned subnr)270 brw_vec2_reg(unsigned file, unsigned nr, unsigned subnr)
271 {
272    return brw_reg(file,
273                   nr,
274                   subnr,
275                   BRW_REGISTER_TYPE_F,
276                   BRW_VERTICAL_STRIDE_2,
277                   BRW_WIDTH_2,
278                   BRW_HORIZONTAL_STRIDE_1,
279                   BRW_SWIZZLE_XYXY,
280                   BRW_WRITEMASK_XY);
281 }
282 
283 /** Construct float[1] register */
284 static inline struct brw_reg
brw_vec1_reg(unsigned file,unsigned nr,unsigned subnr)285 brw_vec1_reg(unsigned file, unsigned nr, unsigned subnr)
286 {
287    return brw_reg(file,
288                   nr,
289                   subnr,
290                   BRW_REGISTER_TYPE_F,
291                   BRW_VERTICAL_STRIDE_0,
292                   BRW_WIDTH_1,
293                   BRW_HORIZONTAL_STRIDE_0,
294                   BRW_SWIZZLE_XXXX,
295                   BRW_WRITEMASK_X);
296 }
297 
298 
299 static inline struct brw_reg
retype(struct brw_reg reg,unsigned type)300 retype(struct brw_reg reg, unsigned type)
301 {
302    reg.type = type;
303    return reg;
304 }
305 
306 static inline struct brw_reg
sechalf(struct brw_reg reg)307 sechalf(struct brw_reg reg)
308 {
309    if (reg.vstride)
310       reg.nr++;
311    return reg;
312 }
313 
314 static inline struct brw_reg
suboffset(struct brw_reg reg,unsigned delta)315 suboffset(struct brw_reg reg, unsigned delta)
316 {
317    reg.subnr += delta * type_sz(reg.type);
318    return reg;
319 }
320 
321 
322 static inline struct brw_reg
offset(struct brw_reg reg,unsigned delta)323 offset(struct brw_reg reg, unsigned delta)
324 {
325    reg.nr += delta;
326    return reg;
327 }
328 
329 
330 static inline struct brw_reg
byte_offset(struct brw_reg reg,unsigned bytes)331 byte_offset(struct brw_reg reg, unsigned bytes)
332 {
333    unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
334    reg.nr = newoffset / REG_SIZE;
335    reg.subnr = newoffset % REG_SIZE;
336    return reg;
337 }
338 
339 
340 /** Construct unsigned word[16] register */
341 static inline struct brw_reg
brw_uw16_reg(unsigned file,unsigned nr,unsigned subnr)342 brw_uw16_reg(unsigned file, unsigned nr, unsigned subnr)
343 {
344    return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
345 }
346 
347 /** Construct unsigned word[8] register */
348 static inline struct brw_reg
brw_uw8_reg(unsigned file,unsigned nr,unsigned subnr)349 brw_uw8_reg(unsigned file, unsigned nr, unsigned subnr)
350 {
351    return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
352 }
353 
354 /** Construct unsigned word[1] register */
355 static inline struct brw_reg
brw_uw1_reg(unsigned file,unsigned nr,unsigned subnr)356 brw_uw1_reg(unsigned file, unsigned nr, unsigned subnr)
357 {
358    return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
359 }
360 
361 static inline struct brw_reg
brw_imm_reg(unsigned type)362 brw_imm_reg(unsigned type)
363 {
364    return brw_reg(BRW_IMMEDIATE_VALUE,
365                   0,
366                   0,
367                   type,
368                   BRW_VERTICAL_STRIDE_0,
369                   BRW_WIDTH_1,
370                   BRW_HORIZONTAL_STRIDE_0,
371                   0,
372                   0);
373 }
374 
375 /** Construct float immediate register */
376 static inline struct brw_reg
brw_imm_f(float f)377 brw_imm_f(float f)
378 {
379    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
380    imm.dw1.f = f;
381    return imm;
382 }
383 
384 /** Construct integer immediate register */
385 static inline struct brw_reg
brw_imm_d(int d)386 brw_imm_d(int d)
387 {
388    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
389    imm.dw1.d = d;
390    return imm;
391 }
392 
393 /** Construct uint immediate register */
394 static inline struct brw_reg
brw_imm_ud(unsigned ud)395 brw_imm_ud(unsigned ud)
396 {
397    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
398    imm.dw1.ud = ud;
399    return imm;
400 }
401 
402 /** Construct ushort immediate register */
403 static inline struct brw_reg
brw_imm_uw(uint16_t uw)404 brw_imm_uw(uint16_t uw)
405 {
406    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
407    imm.dw1.ud = uw | (uw << 16);
408    return imm;
409 }
410 
411 /** Construct short immediate register */
412 static inline struct brw_reg
brw_imm_w(int16_t w)413 brw_imm_w(int16_t w)
414 {
415    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
416    imm.dw1.d = w | (w << 16);
417    return imm;
418 }
419 
420 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
421  * numbers alias with _V and _VF below:
422  */
423 
424 /** Construct vector of eight signed half-byte values */
425 static inline struct brw_reg
brw_imm_v(unsigned v)426 brw_imm_v(unsigned v)
427 {
428    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
429    imm.vstride = BRW_VERTICAL_STRIDE_0;
430    imm.width = BRW_WIDTH_8;
431    imm.hstride = BRW_HORIZONTAL_STRIDE_1;
432    imm.dw1.ud = v;
433    return imm;
434 }
435 
436 /** Construct vector of four 8-bit float values */
437 static inline struct brw_reg
brw_imm_vf(unsigned v)438 brw_imm_vf(unsigned v)
439 {
440    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
441    imm.vstride = BRW_VERTICAL_STRIDE_0;
442    imm.width = BRW_WIDTH_4;
443    imm.hstride = BRW_HORIZONTAL_STRIDE_1;
444    imm.dw1.ud = v;
445    return imm;
446 }
447 
448 #define VF_ZERO 0x0
449 #define VF_ONE  0x30
450 #define VF_NEG  (1<<7)
451 
452 static inline struct brw_reg
brw_imm_vf4(unsigned v0,unsigned v1,unsigned v2,unsigned v3)453 brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
454 {
455    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
456    imm.vstride = BRW_VERTICAL_STRIDE_0;
457    imm.width = BRW_WIDTH_4;
458    imm.hstride = BRW_HORIZONTAL_STRIDE_1;
459    imm.dw1.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24));
460    return imm;
461 }
462 
463 
464 static inline struct brw_reg
brw_address(struct brw_reg reg)465 brw_address(struct brw_reg reg)
466 {
467    return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
468 }
469 
470 /** Construct float[1] general-purpose register */
471 static inline struct brw_reg
brw_vec1_grf(unsigned nr,unsigned subnr)472 brw_vec1_grf(unsigned nr, unsigned subnr)
473 {
474    return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
475 }
476 
477 /** Construct float[2] general-purpose register */
478 static inline struct brw_reg
brw_vec2_grf(unsigned nr,unsigned subnr)479 brw_vec2_grf(unsigned nr, unsigned subnr)
480 {
481    return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
482 }
483 
484 /** Construct float[4] general-purpose register */
485 static inline struct brw_reg
brw_vec4_grf(unsigned nr,unsigned subnr)486 brw_vec4_grf(unsigned nr, unsigned subnr)
487 {
488    return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
489 }
490 
491 /** Construct float[8] general-purpose register */
492 static inline struct brw_reg
brw_vec8_grf(unsigned nr,unsigned subnr)493 brw_vec8_grf(unsigned nr, unsigned subnr)
494 {
495    return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
496 }
497 
498 
499 static inline struct brw_reg
brw_uw8_grf(unsigned nr,unsigned subnr)500 brw_uw8_grf(unsigned nr, unsigned subnr)
501 {
502    return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
503 }
504 
505 static inline struct brw_reg
brw_uw16_grf(unsigned nr,unsigned subnr)506 brw_uw16_grf(unsigned nr, unsigned subnr)
507 {
508    return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
509 }
510 
511 
512 /** Construct null register (usually used for setting condition codes) */
513 static inline struct brw_reg
brw_null_reg(void)514 brw_null_reg(void)
515 {
516    return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
517 }
518 
519 static inline struct brw_reg
brw_address_reg(unsigned subnr)520 brw_address_reg(unsigned subnr)
521 {
522    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
523 }
524 
525 /* If/else instructions break in align16 mode if writemask & swizzle
526  * aren't xyzw.  This goes against the convention for other scalar
527  * regs:
528  */
529 static inline struct brw_reg
brw_ip_reg(void)530 brw_ip_reg(void)
531 {
532    return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
533                   BRW_ARF_IP,
534                   0,
535                   BRW_REGISTER_TYPE_UD,
536                   BRW_VERTICAL_STRIDE_4, /* ? */
537                   BRW_WIDTH_1,
538                   BRW_HORIZONTAL_STRIDE_0,
539                   BRW_SWIZZLE_XYZW, /* NOTE! */
540                   BRW_WRITEMASK_XYZW); /* NOTE! */
541 }
542 
543 static inline struct brw_reg
brw_acc_reg(void)544 brw_acc_reg(void)
545 {
546    return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ACCUMULATOR, 0);
547 }
548 
549 static inline struct brw_reg
brw_notification_1_reg(void)550 brw_notification_1_reg(void)
551 {
552 
553    return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
554                   BRW_ARF_NOTIFICATION_COUNT,
555                   1,
556                   BRW_REGISTER_TYPE_UD,
557                   BRW_VERTICAL_STRIDE_0,
558                   BRW_WIDTH_1,
559                   BRW_HORIZONTAL_STRIDE_0,
560                   BRW_SWIZZLE_XXXX,
561                   BRW_WRITEMASK_X);
562 }
563 
564 
565 static inline struct brw_reg
brw_flag_reg(int reg,int subreg)566 brw_flag_reg(int reg, int subreg)
567 {
568    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
569                       BRW_ARF_FLAG + reg, subreg);
570 }
571 
572 
573 static inline struct brw_reg
brw_mask_reg(unsigned subnr)574 brw_mask_reg(unsigned subnr)
575 {
576    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
577 }
578 
579 static inline struct brw_reg
brw_message_reg(unsigned nr)580 brw_message_reg(unsigned nr)
581 {
582    assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
583    return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
584 }
585 
586 
587 /* This is almost always called with a numeric constant argument, so
588  * make things easy to evaluate at compile time:
589  */
cvt(unsigned val)590 static inline unsigned cvt(unsigned val)
591 {
592    switch (val) {
593    case 0: return 0;
594    case 1: return 1;
595    case 2: return 2;
596    case 4: return 3;
597    case 8: return 4;
598    case 16: return 5;
599    case 32: return 6;
600    }
601    return 0;
602 }
603 
604 static inline struct brw_reg
stride(struct brw_reg reg,unsigned vstride,unsigned width,unsigned hstride)605 stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
606 {
607    reg.vstride = cvt(vstride);
608    reg.width = cvt(width) - 1;
609    reg.hstride = cvt(hstride);
610    return reg;
611 }
612 
613 
614 static inline struct brw_reg
vec16(struct brw_reg reg)615 vec16(struct brw_reg reg)
616 {
617    return stride(reg, 16,16,1);
618 }
619 
620 static inline struct brw_reg
vec8(struct brw_reg reg)621 vec8(struct brw_reg reg)
622 {
623    return stride(reg, 8,8,1);
624 }
625 
626 static inline struct brw_reg
vec4(struct brw_reg reg)627 vec4(struct brw_reg reg)
628 {
629    return stride(reg, 4,4,1);
630 }
631 
632 static inline struct brw_reg
vec2(struct brw_reg reg)633 vec2(struct brw_reg reg)
634 {
635    return stride(reg, 2,2,1);
636 }
637 
638 static inline struct brw_reg
vec1(struct brw_reg reg)639 vec1(struct brw_reg reg)
640 {
641    return stride(reg, 0,1,0);
642 }
643 
644 
645 static inline struct brw_reg
get_element(struct brw_reg reg,unsigned elt)646 get_element(struct brw_reg reg, unsigned elt)
647 {
648    return vec1(suboffset(reg, elt));
649 }
650 
651 static inline struct brw_reg
get_element_ud(struct brw_reg reg,unsigned elt)652 get_element_ud(struct brw_reg reg, unsigned elt)
653 {
654    return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
655 }
656 
657 static inline struct brw_reg
get_element_d(struct brw_reg reg,unsigned elt)658 get_element_d(struct brw_reg reg, unsigned elt)
659 {
660    return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
661 }
662 
663 
664 static inline struct brw_reg
brw_swizzle(struct brw_reg reg,unsigned x,unsigned y,unsigned z,unsigned w)665 brw_swizzle(struct brw_reg reg, unsigned x, unsigned y, unsigned z, unsigned w)
666 {
667    assert(reg.file != BRW_IMMEDIATE_VALUE);
668 
669    reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
670                                        BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
671                                        BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
672                                        BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
673    return reg;
674 }
675 
676 
677 static inline struct brw_reg
brw_swizzle1(struct brw_reg reg,unsigned x)678 brw_swizzle1(struct brw_reg reg, unsigned x)
679 {
680    return brw_swizzle(reg, x, x, x, x);
681 }
682 
683 static inline struct brw_reg
brw_writemask(struct brw_reg reg,unsigned mask)684 brw_writemask(struct brw_reg reg, unsigned mask)
685 {
686    assert(reg.file != BRW_IMMEDIATE_VALUE);
687    reg.dw1.bits.writemask &= mask;
688    return reg;
689 }
690 
691 static inline struct brw_reg
brw_set_writemask(struct brw_reg reg,unsigned mask)692 brw_set_writemask(struct brw_reg reg, unsigned mask)
693 {
694    assert(reg.file != BRW_IMMEDIATE_VALUE);
695    reg.dw1.bits.writemask = mask;
696    return reg;
697 }
698 
699 static inline struct brw_reg
negate(struct brw_reg reg)700 negate(struct brw_reg reg)
701 {
702    reg.negate ^= 1;
703    return reg;
704 }
705 
706 static inline struct brw_reg
brw_abs(struct brw_reg reg)707 brw_abs(struct brw_reg reg)
708 {
709    reg.abs = 1;
710    reg.negate = 0;
711    return reg;
712 }
713 
714 /************************************************************************/
715 
716 static inline struct brw_reg
brw_vec4_indirect(unsigned subnr,int offset)717 brw_vec4_indirect(unsigned subnr, int offset)
718 {
719    struct brw_reg reg =  brw_vec4_grf(0, 0);
720    reg.subnr = subnr;
721    reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
722    reg.dw1.bits.indirect_offset = offset;
723    return reg;
724 }
725 
726 static inline struct brw_reg
brw_vec1_indirect(unsigned subnr,int offset)727 brw_vec1_indirect(unsigned subnr, int offset)
728 {
729    struct brw_reg reg =  brw_vec1_grf(0, 0);
730    reg.subnr = subnr;
731    reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
732    reg.dw1.bits.indirect_offset = offset;
733    return reg;
734 }
735 
736 static inline struct brw_reg
deref_4f(struct brw_indirect ptr,int offset)737 deref_4f(struct brw_indirect ptr, int offset)
738 {
739    return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
740 }
741 
742 static inline struct brw_reg
deref_1f(struct brw_indirect ptr,int offset)743 deref_1f(struct brw_indirect ptr, int offset)
744 {
745    return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
746 }
747 
748 static inline struct brw_reg
deref_4b(struct brw_indirect ptr,int offset)749 deref_4b(struct brw_indirect ptr, int offset)
750 {
751    return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
752 }
753 
754 static inline struct brw_reg
deref_1uw(struct brw_indirect ptr,int offset)755 deref_1uw(struct brw_indirect ptr, int 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,int offset)761 deref_1d(struct brw_indirect ptr, int offset)
762 {
763    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
764 }
765 
766 static inline struct brw_reg
deref_1ud(struct brw_indirect ptr,int offset)767 deref_1ud(struct brw_indirect ptr, int offset)
768 {
769    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
770 }
771 
772 static inline struct brw_reg
get_addr_reg(struct brw_indirect ptr)773 get_addr_reg(struct brw_indirect ptr)
774 {
775    return brw_address_reg(ptr.addr_subnr);
776 }
777 
778 static inline struct brw_indirect
brw_indirect_offset(struct brw_indirect ptr,int offset)779 brw_indirect_offset(struct brw_indirect ptr, int offset)
780 {
781    ptr.addr_offset += offset;
782    return ptr;
783 }
784 
785 static inline struct brw_indirect
brw_indirect(unsigned addr_subnr,int offset)786 brw_indirect(unsigned addr_subnr, int offset)
787 {
788    struct brw_indirect ptr;
789    ptr.addr_subnr = addr_subnr;
790    ptr.addr_offset = offset;
791    ptr.pad = 0;
792    return ptr;
793 }
794 
795 /** Do two brw_regs refer to the same register? */
796 static inline bool
brw_same_reg(struct brw_reg r1,struct brw_reg r2)797 brw_same_reg(struct brw_reg r1, struct brw_reg r2)
798 {
799    return r1.file == r2.file && r1.nr == r2.nr;
800 }
801 
802 void brw_print_reg(struct brw_reg reg);
803 
804 #ifdef __cplusplus
805 }
806 #endif
807 
808 #endif
809