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