494ce8c4fa57f0b85d8b247d147d68ade2a43b03
[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 "main/imports.h"
47 #include "main/compiler.h"
48 #include "program/prog_instruction.h"
49 #include "brw_defines.h"
50
51 #ifdef __cplusplus
52 extern "C" {
53 #endif
54
55 /** Number of general purpose registers (VS, WM, etc) */
56 #define BRW_MAX_GRF 128
57
58 /**
59 * First GRF used for the MRF hack.
60 *
61 * On gen7, MRFs are no longer used, and contiguous GRFs are used instead. We
62 * haven't converted our compiler to be aware of this, so it asks for MRFs and
63 * brw_eu_emit.c quietly converts them to be accesses of the top GRFs. The
64 * register allocators have to be careful of this to avoid corrupting the "MRF"s
65 * with actual GRF allocations.
66 */
67 #define GEN7_MRF_HACK_START 112
68
69 /** Number of message register file registers */
70 #define BRW_MAX_MRF 16
71
72 #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
73 #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
74
75 #define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3)
76 #define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3)
77 #define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0)
78 #define BRW_SWIZZLE_YYYY BRW_SWIZZLE4(1,1,1,1)
79 #define BRW_SWIZZLE_ZZZZ BRW_SWIZZLE4(2,2,2,2)
80 #define BRW_SWIZZLE_WWWW BRW_SWIZZLE4(3,3,3,3)
81 #define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1)
82 #define BRW_SWIZZLE_YZXW BRW_SWIZZLE4(1,2,0,3)
83 #define BRW_SWIZZLE_ZXYW BRW_SWIZZLE4(2,0,1,3)
84 #define BRW_SWIZZLE_ZWZW BRW_SWIZZLE4(2,3,2,3)
85
86 static inline bool
87 brw_is_single_value_swizzle(int swiz)
88 {
89 return (swiz == BRW_SWIZZLE_XXXX ||
90 swiz == BRW_SWIZZLE_YYYY ||
91 swiz == BRW_SWIZZLE_ZZZZ ||
92 swiz == BRW_SWIZZLE_WWWW);
93 }
94
95 enum PACKED brw_reg_type {
96 BRW_REGISTER_TYPE_UD = 0,
97 BRW_REGISTER_TYPE_D,
98 BRW_REGISTER_TYPE_UW,
99 BRW_REGISTER_TYPE_W,
100 BRW_REGISTER_TYPE_F,
101
102 /** Non-immediates only: @{ */
103 BRW_REGISTER_TYPE_UB,
104 BRW_REGISTER_TYPE_B,
105 /** @} */
106
107 /** Immediates only: @{ */
108 BRW_REGISTER_TYPE_UV,
109 BRW_REGISTER_TYPE_V,
110 BRW_REGISTER_TYPE_VF,
111 /** @} */
112
113 BRW_REGISTER_TYPE_DF, /* Gen7+ (no immediates until Gen8+) */
114
115 /* Gen8+ */
116 BRW_REGISTER_TYPE_HF,
117 BRW_REGISTER_TYPE_UQ,
118 BRW_REGISTER_TYPE_Q,
119 };
120
121 unsigned brw_reg_type_to_hw_type(const struct brw_context *brw,
122 enum brw_reg_type type, unsigned file);
123 const char *brw_reg_type_letters(unsigned brw_reg_type);
124
125 #define REG_SIZE (8*4)
126
127 /* These aren't hardware structs, just something useful for us to pass around:
128 *
129 * Align1 operation has a lot of control over input ranges. Used in
130 * WM programs to implement shaders decomposed into "channel serial"
131 * or "structure of array" form:
132 */
133 struct brw_reg {
134 enum brw_reg_type type:4;
135 unsigned file:2;
136 unsigned nr:8;
137 unsigned subnr:5; /* :1 in align16 */
138 unsigned negate:1; /* source only */
139 unsigned abs:1; /* source only */
140 unsigned vstride:4; /* source only */
141 unsigned width:3; /* src only, align1 only */
142 unsigned hstride:2; /* align1 only */
143 unsigned address_mode:1; /* relative addressing, hopefully! */
144 unsigned pad0:1;
145
146 union {
147 struct {
148 unsigned swizzle:8; /* src only, align16 only */
149 unsigned writemask:4; /* dest only, align16 only */
150 int indirect_offset:10; /* relative addressing offset */
151 unsigned pad1:10; /* two dwords total */
152 } bits;
153
154 float f;
155 int d;
156 unsigned ud;
157 } dw1;
158 };
159
160
161 struct brw_indirect {
162 unsigned addr_subnr:4;
163 int addr_offset:10;
164 unsigned pad:18;
165 };
166
167
168 static inline int
169 type_sz(unsigned type)
170 {
171 switch(type) {
172 case BRW_REGISTER_TYPE_UD:
173 case BRW_REGISTER_TYPE_D:
174 case BRW_REGISTER_TYPE_F:
175 return 4;
176 case BRW_REGISTER_TYPE_UW:
177 case BRW_REGISTER_TYPE_W:
178 return 2;
179 case BRW_REGISTER_TYPE_UB:
180 case BRW_REGISTER_TYPE_B:
181 return 1;
182 default:
183 return 0;
184 }
185 }
186
187 static inline bool
188 type_is_signed(unsigned type)
189 {
190 switch(type) {
191 case BRW_REGISTER_TYPE_D:
192 case BRW_REGISTER_TYPE_W:
193 case BRW_REGISTER_TYPE_F:
194 case BRW_REGISTER_TYPE_B:
195 case BRW_REGISTER_TYPE_V:
196 case BRW_REGISTER_TYPE_VF:
197 case BRW_REGISTER_TYPE_DF:
198 case BRW_REGISTER_TYPE_HF:
199 case BRW_REGISTER_TYPE_Q:
200 return true;
201
202 case BRW_REGISTER_TYPE_UD:
203 case BRW_REGISTER_TYPE_UW:
204 case BRW_REGISTER_TYPE_UB:
205 case BRW_REGISTER_TYPE_UV:
206 case BRW_REGISTER_TYPE_UQ:
207 return false;
208
209 default:
210 unreachable("not reached");
211 }
212 }
213
214 /**
215 * Construct a brw_reg.
216 * \param file one of the BRW_x_REGISTER_FILE values
217 * \param nr register number/index
218 * \param subnr register sub number
219 * \param type one of BRW_REGISTER_TYPE_x
220 * \param vstride one of BRW_VERTICAL_STRIDE_x
221 * \param width one of BRW_WIDTH_x
222 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
223 * \param swizzle one of BRW_SWIZZLE_x
224 * \param writemask WRITEMASK_X/Y/Z/W bitfield
225 */
226 static inline struct brw_reg
227 brw_reg(unsigned file,
228 unsigned nr,
229 unsigned subnr,
230 enum brw_reg_type type,
231 unsigned vstride,
232 unsigned width,
233 unsigned hstride,
234 unsigned swizzle,
235 unsigned writemask)
236 {
237 struct brw_reg reg;
238 if (file == BRW_GENERAL_REGISTER_FILE)
239 assert(nr < BRW_MAX_GRF);
240 else if (file == BRW_MESSAGE_REGISTER_FILE)
241 assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
242 else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
243 assert(nr <= BRW_ARF_TIMESTAMP);
244
245 reg.type = type;
246 reg.file = file;
247 reg.nr = nr;
248 reg.subnr = subnr * type_sz(type);
249 reg.negate = 0;
250 reg.abs = 0;
251 reg.vstride = vstride;
252 reg.width = width;
253 reg.hstride = hstride;
254 reg.address_mode = BRW_ADDRESS_DIRECT;
255 reg.pad0 = 0;
256
257 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
258 * set swizzle and writemask to W, as the lower bits of subnr will
259 * be lost when converted to align16. This is probably too much to
260 * keep track of as you'd want it adjusted by suboffset(), etc.
261 * Perhaps fix up when converting to align16?
262 */
263 reg.dw1.bits.swizzle = swizzle;
264 reg.dw1.bits.writemask = writemask;
265 reg.dw1.bits.indirect_offset = 0;
266 reg.dw1.bits.pad1 = 0;
267 return reg;
268 }
269
270 /** Construct float[16] register */
271 static inline struct brw_reg
272 brw_vec16_reg(unsigned file, unsigned nr, unsigned subnr)
273 {
274 return brw_reg(file,
275 nr,
276 subnr,
277 BRW_REGISTER_TYPE_F,
278 BRW_VERTICAL_STRIDE_16,
279 BRW_WIDTH_16,
280 BRW_HORIZONTAL_STRIDE_1,
281 BRW_SWIZZLE_XYZW,
282 WRITEMASK_XYZW);
283 }
284
285 /** Construct float[8] register */
286 static inline struct brw_reg
287 brw_vec8_reg(unsigned file, unsigned nr, unsigned subnr)
288 {
289 return brw_reg(file,
290 nr,
291 subnr,
292 BRW_REGISTER_TYPE_F,
293 BRW_VERTICAL_STRIDE_8,
294 BRW_WIDTH_8,
295 BRW_HORIZONTAL_STRIDE_1,
296 BRW_SWIZZLE_XYZW,
297 WRITEMASK_XYZW);
298 }
299
300 /** Construct float[4] register */
301 static inline struct brw_reg
302 brw_vec4_reg(unsigned file, unsigned nr, unsigned subnr)
303 {
304 return brw_reg(file,
305 nr,
306 subnr,
307 BRW_REGISTER_TYPE_F,
308 BRW_VERTICAL_STRIDE_4,
309 BRW_WIDTH_4,
310 BRW_HORIZONTAL_STRIDE_1,
311 BRW_SWIZZLE_XYZW,
312 WRITEMASK_XYZW);
313 }
314
315 /** Construct float[2] register */
316 static inline struct brw_reg
317 brw_vec2_reg(unsigned file, unsigned nr, unsigned subnr)
318 {
319 return brw_reg(file,
320 nr,
321 subnr,
322 BRW_REGISTER_TYPE_F,
323 BRW_VERTICAL_STRIDE_2,
324 BRW_WIDTH_2,
325 BRW_HORIZONTAL_STRIDE_1,
326 BRW_SWIZZLE_XYXY,
327 WRITEMASK_XY);
328 }
329
330 /** Construct float[1] register */
331 static inline struct brw_reg
332 brw_vec1_reg(unsigned file, unsigned nr, unsigned subnr)
333 {
334 return brw_reg(file,
335 nr,
336 subnr,
337 BRW_REGISTER_TYPE_F,
338 BRW_VERTICAL_STRIDE_0,
339 BRW_WIDTH_1,
340 BRW_HORIZONTAL_STRIDE_0,
341 BRW_SWIZZLE_XXXX,
342 WRITEMASK_X);
343 }
344
345 static inline struct brw_reg
346 brw_vecn_reg(unsigned width, unsigned file, unsigned nr, unsigned subnr)
347 {
348 switch (width) {
349 case 1:
350 return brw_vec1_reg(file, nr, subnr);
351 case 2:
352 return brw_vec2_reg(file, nr, subnr);
353 case 4:
354 return brw_vec4_reg(file, nr, subnr);
355 case 8:
356 return brw_vec8_reg(file, nr, subnr);
357 case 16:
358 return brw_vec16_reg(file, nr, subnr);
359 default:
360 unreachable("Invalid register width");
361 }
362 }
363
364 static inline struct brw_reg
365 retype(struct brw_reg reg, enum brw_reg_type 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(enum brw_reg_type 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 /**
514 * Convert an integer into a "restricted" 8-bit float, used in vector
515 * immediates. The 8-bit floating point format has a sign bit, an
516 * excess-3 3-bit exponent, and a 4-bit mantissa. All integer values
517 * from -31 to 31 can be represented exactly.
518 */
519 static inline uint8_t
520 int_to_float8(int x)
521 {
522 if (x == 0) {
523 return 0;
524 } else if (x < 0) {
525 return 1 << 7 | int_to_float8(-x);
526 } else {
527 const unsigned exponent = _mesa_logbase2(x);
528 const unsigned mantissa = (x - (1 << exponent)) << (4 - exponent);
529 assert(exponent <= 4);
530 return (exponent + 3) << 4 | mantissa;
531 }
532 }
533
534 /**
535 * Construct a floating-point packed vector immediate from its integer
536 * values. \sa int_to_float8()
537 */
538 static inline struct brw_reg
539 brw_imm_vf4(int v0, int v1, int v2, int v3)
540 {
541 return brw_imm_vf((int_to_float8(v0) << 0) |
542 (int_to_float8(v1) << 8) |
543 (int_to_float8(v2) << 16) |
544 (int_to_float8(v3) << 24));
545 }
546
547
548 static inline struct brw_reg
549 brw_address(struct brw_reg reg)
550 {
551 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
552 }
553
554 /** Construct float[1] general-purpose register */
555 static inline struct brw_reg
556 brw_vec1_grf(unsigned nr, unsigned subnr)
557 {
558 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
559 }
560
561 /** Construct float[2] general-purpose register */
562 static inline struct brw_reg
563 brw_vec2_grf(unsigned nr, unsigned subnr)
564 {
565 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
566 }
567
568 /** Construct float[4] general-purpose register */
569 static inline struct brw_reg
570 brw_vec4_grf(unsigned nr, unsigned subnr)
571 {
572 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
573 }
574
575 /** Construct float[8] general-purpose register */
576 static inline struct brw_reg
577 brw_vec8_grf(unsigned nr, unsigned subnr)
578 {
579 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
580 }
581
582
583 static inline struct brw_reg
584 brw_uw8_grf(unsigned nr, unsigned subnr)
585 {
586 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
587 }
588
589 static inline struct brw_reg
590 brw_uw16_grf(unsigned nr, unsigned subnr)
591 {
592 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
593 }
594
595
596 /** Construct null register (usually used for setting condition codes) */
597 static inline struct brw_reg
598 brw_null_reg(void)
599 {
600 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
601 }
602
603 static inline struct brw_reg
604 brw_address_reg(unsigned subnr)
605 {
606 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
607 }
608
609 /* If/else instructions break in align16 mode if writemask & swizzle
610 * aren't xyzw. This goes against the convention for other scalar
611 * regs:
612 */
613 static inline struct brw_reg
614 brw_ip_reg(void)
615 {
616 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
617 BRW_ARF_IP,
618 0,
619 BRW_REGISTER_TYPE_UD,
620 BRW_VERTICAL_STRIDE_4, /* ? */
621 BRW_WIDTH_1,
622 BRW_HORIZONTAL_STRIDE_0,
623 BRW_SWIZZLE_XYZW, /* NOTE! */
624 WRITEMASK_XYZW); /* NOTE! */
625 }
626
627 static inline struct brw_reg
628 brw_acc_reg(void)
629 {
630 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ACCUMULATOR, 0);
631 }
632
633 static inline struct brw_reg
634 brw_flag_reg(int reg, int subreg)
635 {
636 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
637 BRW_ARF_FLAG + reg, subreg);
638 }
639
640
641 static inline struct brw_reg
642 brw_mask_reg(unsigned subnr)
643 {
644 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
645 }
646
647 static inline struct brw_reg
648 brw_message_reg(unsigned nr)
649 {
650 assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
651 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
652 }
653
654 static inline struct brw_reg
655 brw_uvec_mrf(unsigned width, unsigned nr, unsigned subnr)
656 {
657 return retype(brw_vecn_reg(width, BRW_MESSAGE_REGISTER_FILE, nr, subnr),
658 BRW_REGISTER_TYPE_UD);
659 }
660
661 /* This is almost always called with a numeric constant argument, so
662 * make things easy to evaluate at compile time:
663 */
664 static inline unsigned cvt(unsigned val)
665 {
666 switch (val) {
667 case 0: return 0;
668 case 1: return 1;
669 case 2: return 2;
670 case 4: return 3;
671 case 8: return 4;
672 case 16: return 5;
673 case 32: return 6;
674 }
675 return 0;
676 }
677
678 static inline struct brw_reg
679 stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
680 {
681 reg.vstride = cvt(vstride);
682 reg.width = cvt(width) - 1;
683 reg.hstride = cvt(hstride);
684 return reg;
685 }
686
687
688 static inline struct brw_reg
689 vec16(struct brw_reg reg)
690 {
691 return stride(reg, 16,16,1);
692 }
693
694 static inline struct brw_reg
695 vec8(struct brw_reg reg)
696 {
697 return stride(reg, 8,8,1);
698 }
699
700 static inline struct brw_reg
701 vec4(struct brw_reg reg)
702 {
703 return stride(reg, 4,4,1);
704 }
705
706 static inline struct brw_reg
707 vec2(struct brw_reg reg)
708 {
709 return stride(reg, 2,2,1);
710 }
711
712 static inline struct brw_reg
713 vec1(struct brw_reg reg)
714 {
715 return stride(reg, 0,1,0);
716 }
717
718
719 static inline struct brw_reg
720 get_element(struct brw_reg reg, unsigned elt)
721 {
722 return vec1(suboffset(reg, elt));
723 }
724
725 static inline struct brw_reg
726 get_element_ud(struct brw_reg reg, unsigned elt)
727 {
728 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
729 }
730
731 static inline struct brw_reg
732 get_element_d(struct brw_reg reg, unsigned elt)
733 {
734 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
735 }
736
737
738 static inline struct brw_reg
739 brw_swizzle(struct brw_reg reg, unsigned x, unsigned y, unsigned z, unsigned w)
740 {
741 assert(reg.file != BRW_IMMEDIATE_VALUE);
742
743 reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
744 BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
745 BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
746 BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
747 return reg;
748 }
749
750
751 static inline struct brw_reg
752 brw_swizzle1(struct brw_reg reg, unsigned x)
753 {
754 return brw_swizzle(reg, x, x, x, x);
755 }
756
757 static inline struct brw_reg
758 brw_writemask(struct brw_reg reg, unsigned mask)
759 {
760 assert(reg.file != BRW_IMMEDIATE_VALUE);
761 reg.dw1.bits.writemask &= mask;
762 return reg;
763 }
764
765 static inline struct brw_reg
766 brw_set_writemask(struct brw_reg reg, unsigned mask)
767 {
768 assert(reg.file != BRW_IMMEDIATE_VALUE);
769 reg.dw1.bits.writemask = mask;
770 return reg;
771 }
772
773 static inline struct brw_reg
774 negate(struct brw_reg reg)
775 {
776 reg.negate ^= 1;
777 return reg;
778 }
779
780 static inline struct brw_reg
781 brw_abs(struct brw_reg reg)
782 {
783 reg.abs = 1;
784 reg.negate = 0;
785 return reg;
786 }
787
788 /************************************************************************/
789
790 static inline struct brw_reg
791 brw_vec4_indirect(unsigned subnr, int offset)
792 {
793 struct brw_reg reg = brw_vec4_grf(0, 0);
794 reg.subnr = subnr;
795 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
796 reg.dw1.bits.indirect_offset = offset;
797 return reg;
798 }
799
800 static inline struct brw_reg
801 brw_vec1_indirect(unsigned subnr, int offset)
802 {
803 struct brw_reg reg = brw_vec1_grf(0, 0);
804 reg.subnr = subnr;
805 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
806 reg.dw1.bits.indirect_offset = offset;
807 return reg;
808 }
809
810 static inline struct brw_reg
811 deref_4f(struct brw_indirect ptr, int offset)
812 {
813 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
814 }
815
816 static inline struct brw_reg
817 deref_1f(struct brw_indirect ptr, int offset)
818 {
819 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
820 }
821
822 static inline struct brw_reg
823 deref_4b(struct brw_indirect ptr, int offset)
824 {
825 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
826 }
827
828 static inline struct brw_reg
829 deref_1uw(struct brw_indirect ptr, int offset)
830 {
831 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
832 }
833
834 static inline struct brw_reg
835 deref_1d(struct brw_indirect ptr, int offset)
836 {
837 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
838 }
839
840 static inline struct brw_reg
841 deref_1ud(struct brw_indirect ptr, int offset)
842 {
843 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
844 }
845
846 static inline struct brw_reg
847 get_addr_reg(struct brw_indirect ptr)
848 {
849 return brw_address_reg(ptr.addr_subnr);
850 }
851
852 static inline struct brw_indirect
853 brw_indirect_offset(struct brw_indirect ptr, int offset)
854 {
855 ptr.addr_offset += offset;
856 return ptr;
857 }
858
859 static inline struct brw_indirect
860 brw_indirect(unsigned addr_subnr, int offset)
861 {
862 struct brw_indirect ptr;
863 ptr.addr_subnr = addr_subnr;
864 ptr.addr_offset = offset;
865 ptr.pad = 0;
866 return ptr;
867 }
868
869 #ifdef __cplusplus
870 }
871 #endif
872
873 #endif