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