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