i965/fs_nir: Get rid of get_alu_src
[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_UQ:
175 case BRW_REGISTER_TYPE_Q:
176 return 8;
177 case BRW_REGISTER_TYPE_UD:
178 case BRW_REGISTER_TYPE_D:
179 case BRW_REGISTER_TYPE_F:
180 return 4;
181 case BRW_REGISTER_TYPE_UW:
182 case BRW_REGISTER_TYPE_W:
183 return 2;
184 case BRW_REGISTER_TYPE_UB:
185 case BRW_REGISTER_TYPE_B:
186 return 1;
187 default:
188 return 0;
189 }
190 }
191
192 static inline bool
193 type_is_signed(unsigned type)
194 {
195 switch(type) {
196 case BRW_REGISTER_TYPE_D:
197 case BRW_REGISTER_TYPE_W:
198 case BRW_REGISTER_TYPE_F:
199 case BRW_REGISTER_TYPE_B:
200 case BRW_REGISTER_TYPE_V:
201 case BRW_REGISTER_TYPE_VF:
202 case BRW_REGISTER_TYPE_DF:
203 case BRW_REGISTER_TYPE_HF:
204 case BRW_REGISTER_TYPE_Q:
205 return true;
206
207 case BRW_REGISTER_TYPE_UD:
208 case BRW_REGISTER_TYPE_UW:
209 case BRW_REGISTER_TYPE_UB:
210 case BRW_REGISTER_TYPE_UV:
211 case BRW_REGISTER_TYPE_UQ:
212 return false;
213
214 default:
215 unreachable("not reached");
216 }
217 }
218
219 /**
220 * Construct a brw_reg.
221 * \param file one of the BRW_x_REGISTER_FILE values
222 * \param nr register number/index
223 * \param subnr register sub number
224 * \param negate register negate modifier
225 * \param abs register abs modifier
226 * \param type one of BRW_REGISTER_TYPE_x
227 * \param vstride one of BRW_VERTICAL_STRIDE_x
228 * \param width one of BRW_WIDTH_x
229 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
230 * \param swizzle one of BRW_SWIZZLE_x
231 * \param writemask WRITEMASK_X/Y/Z/W bitfield
232 */
233 static inline struct brw_reg
234 brw_reg(unsigned file,
235 unsigned nr,
236 unsigned subnr,
237 unsigned negate,
238 unsigned abs,
239 enum brw_reg_type type,
240 unsigned vstride,
241 unsigned width,
242 unsigned hstride,
243 unsigned swizzle,
244 unsigned writemask)
245 {
246 struct brw_reg reg;
247 if (file == BRW_GENERAL_REGISTER_FILE)
248 assert(nr < BRW_MAX_GRF);
249 else if (file == BRW_MESSAGE_REGISTER_FILE)
250 assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
251 else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
252 assert(nr <= BRW_ARF_TIMESTAMP);
253
254 reg.type = type;
255 reg.file = file;
256 reg.nr = nr;
257 reg.subnr = subnr * type_sz(type);
258 reg.negate = negate;
259 reg.abs = abs;
260 reg.vstride = vstride;
261 reg.width = width;
262 reg.hstride = hstride;
263 reg.address_mode = BRW_ADDRESS_DIRECT;
264 reg.pad0 = 0;
265
266 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
267 * set swizzle and writemask to W, as the lower bits of subnr will
268 * be lost when converted to align16. This is probably too much to
269 * keep track of as you'd want it adjusted by suboffset(), etc.
270 * Perhaps fix up when converting to align16?
271 */
272 reg.dw1.bits.swizzle = swizzle;
273 reg.dw1.bits.writemask = writemask;
274 reg.dw1.bits.indirect_offset = 0;
275 reg.dw1.bits.pad1 = 0;
276 return reg;
277 }
278
279 /** Construct float[16] register */
280 static inline struct brw_reg
281 brw_vec16_reg(unsigned file, unsigned nr, unsigned subnr)
282 {
283 return brw_reg(file,
284 nr,
285 subnr,
286 0,
287 0,
288 BRW_REGISTER_TYPE_F,
289 BRW_VERTICAL_STRIDE_16,
290 BRW_WIDTH_16,
291 BRW_HORIZONTAL_STRIDE_1,
292 BRW_SWIZZLE_XYZW,
293 WRITEMASK_XYZW);
294 }
295
296 /** Construct float[8] register */
297 static inline struct brw_reg
298 brw_vec8_reg(unsigned file, unsigned nr, unsigned subnr)
299 {
300 return brw_reg(file,
301 nr,
302 subnr,
303 0,
304 0,
305 BRW_REGISTER_TYPE_F,
306 BRW_VERTICAL_STRIDE_8,
307 BRW_WIDTH_8,
308 BRW_HORIZONTAL_STRIDE_1,
309 BRW_SWIZZLE_XYZW,
310 WRITEMASK_XYZW);
311 }
312
313 /** Construct float[4] register */
314 static inline struct brw_reg
315 brw_vec4_reg(unsigned file, unsigned nr, unsigned subnr)
316 {
317 return brw_reg(file,
318 nr,
319 subnr,
320 0,
321 0,
322 BRW_REGISTER_TYPE_F,
323 BRW_VERTICAL_STRIDE_4,
324 BRW_WIDTH_4,
325 BRW_HORIZONTAL_STRIDE_1,
326 BRW_SWIZZLE_XYZW,
327 WRITEMASK_XYZW);
328 }
329
330 /** Construct float[2] register */
331 static inline struct brw_reg
332 brw_vec2_reg(unsigned file, unsigned nr, unsigned subnr)
333 {
334 return brw_reg(file,
335 nr,
336 subnr,
337 0,
338 0,
339 BRW_REGISTER_TYPE_F,
340 BRW_VERTICAL_STRIDE_2,
341 BRW_WIDTH_2,
342 BRW_HORIZONTAL_STRIDE_1,
343 BRW_SWIZZLE_XYXY,
344 WRITEMASK_XY);
345 }
346
347 /** Construct float[1] register */
348 static inline struct brw_reg
349 brw_vec1_reg(unsigned file, unsigned nr, unsigned subnr)
350 {
351 return brw_reg(file,
352 nr,
353 subnr,
354 0,
355 0,
356 BRW_REGISTER_TYPE_F,
357 BRW_VERTICAL_STRIDE_0,
358 BRW_WIDTH_1,
359 BRW_HORIZONTAL_STRIDE_0,
360 BRW_SWIZZLE_XXXX,
361 WRITEMASK_X);
362 }
363
364 static inline struct brw_reg
365 brw_vecn_reg(unsigned width, unsigned file, unsigned nr, unsigned subnr)
366 {
367 switch (width) {
368 case 1:
369 return brw_vec1_reg(file, nr, subnr);
370 case 2:
371 return brw_vec2_reg(file, nr, subnr);
372 case 4:
373 return brw_vec4_reg(file, nr, subnr);
374 case 8:
375 return brw_vec8_reg(file, nr, subnr);
376 case 16:
377 return brw_vec16_reg(file, nr, subnr);
378 default:
379 unreachable("Invalid register width");
380 }
381 }
382
383 static inline struct brw_reg
384 retype(struct brw_reg reg, enum brw_reg_type type)
385 {
386 reg.type = type;
387 return reg;
388 }
389
390 static inline struct brw_reg
391 firsthalf(struct brw_reg reg)
392 {
393 return reg;
394 }
395
396 static inline struct brw_reg
397 sechalf(struct brw_reg reg)
398 {
399 if (reg.vstride)
400 reg.nr++;
401 return reg;
402 }
403
404 static inline struct brw_reg
405 suboffset(struct brw_reg reg, unsigned delta)
406 {
407 reg.subnr += delta * type_sz(reg.type);
408 return reg;
409 }
410
411
412 static inline struct brw_reg
413 offset(struct brw_reg reg, unsigned delta)
414 {
415 reg.nr += delta;
416 return reg;
417 }
418
419
420 static inline struct brw_reg
421 byte_offset(struct brw_reg reg, unsigned bytes)
422 {
423 unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
424 reg.nr = newoffset / REG_SIZE;
425 reg.subnr = newoffset % REG_SIZE;
426 return reg;
427 }
428
429
430 /** Construct unsigned word[16] register */
431 static inline struct brw_reg
432 brw_uw16_reg(unsigned file, unsigned nr, unsigned subnr)
433 {
434 return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
435 }
436
437 /** Construct unsigned word[8] register */
438 static inline struct brw_reg
439 brw_uw8_reg(unsigned file, unsigned nr, unsigned subnr)
440 {
441 return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
442 }
443
444 /** Construct unsigned word[1] register */
445 static inline struct brw_reg
446 brw_uw1_reg(unsigned file, unsigned nr, unsigned subnr)
447 {
448 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
449 }
450
451 static inline struct brw_reg
452 brw_imm_reg(enum brw_reg_type type)
453 {
454 return brw_reg(BRW_IMMEDIATE_VALUE,
455 0,
456 0,
457 0,
458 0,
459 type,
460 BRW_VERTICAL_STRIDE_0,
461 BRW_WIDTH_1,
462 BRW_HORIZONTAL_STRIDE_0,
463 0,
464 0);
465 }
466
467 /** Construct float immediate register */
468 static inline struct brw_reg
469 brw_imm_f(float f)
470 {
471 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
472 imm.dw1.f = f;
473 return imm;
474 }
475
476 /** Construct integer immediate register */
477 static inline struct brw_reg
478 brw_imm_d(int d)
479 {
480 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
481 imm.dw1.d = d;
482 return imm;
483 }
484
485 /** Construct uint immediate register */
486 static inline struct brw_reg
487 brw_imm_ud(unsigned ud)
488 {
489 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
490 imm.dw1.ud = ud;
491 return imm;
492 }
493
494 /** Construct ushort immediate register */
495 static inline struct brw_reg
496 brw_imm_uw(uint16_t uw)
497 {
498 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
499 imm.dw1.ud = uw | (uw << 16);
500 return imm;
501 }
502
503 /** Construct short immediate register */
504 static inline struct brw_reg
505 brw_imm_w(int16_t w)
506 {
507 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
508 imm.dw1.d = w | (w << 16);
509 return imm;
510 }
511
512 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
513 * numbers alias with _V and _VF below:
514 */
515
516 /** Construct vector of eight signed half-byte values */
517 static inline struct brw_reg
518 brw_imm_v(unsigned v)
519 {
520 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
521 imm.vstride = BRW_VERTICAL_STRIDE_0;
522 imm.width = BRW_WIDTH_8;
523 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
524 imm.dw1.ud = v;
525 return imm;
526 }
527
528 /** Construct vector of four 8-bit float values */
529 static inline struct brw_reg
530 brw_imm_vf(unsigned v)
531 {
532 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
533 imm.vstride = BRW_VERTICAL_STRIDE_0;
534 imm.width = BRW_WIDTH_4;
535 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
536 imm.dw1.ud = v;
537 return imm;
538 }
539
540 /**
541 * Convert an integer into a "restricted" 8-bit float, used in vector
542 * immediates. The 8-bit floating point format has a sign bit, an
543 * excess-3 3-bit exponent, and a 4-bit mantissa. All integer values
544 * from -31 to 31 can be represented exactly.
545 */
546 static inline uint8_t
547 int_to_float8(int x)
548 {
549 if (x == 0) {
550 return 0;
551 } else if (x < 0) {
552 return 1 << 7 | int_to_float8(-x);
553 } else {
554 const unsigned exponent = _mesa_logbase2(x);
555 const unsigned mantissa = (x - (1 << exponent)) << (4 - exponent);
556 assert(exponent <= 4);
557 return (exponent + 3) << 4 | mantissa;
558 }
559 }
560
561 /**
562 * Construct a floating-point packed vector immediate from its integer
563 * values. \sa int_to_float8()
564 */
565 static inline struct brw_reg
566 brw_imm_vf4(int v0, int v1, int v2, int v3)
567 {
568 return brw_imm_vf((int_to_float8(v0) << 0) |
569 (int_to_float8(v1) << 8) |
570 (int_to_float8(v2) << 16) |
571 (int_to_float8(v3) << 24));
572 }
573
574
575 static inline struct brw_reg
576 brw_address(struct brw_reg reg)
577 {
578 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
579 }
580
581 /** Construct float[1] general-purpose register */
582 static inline struct brw_reg
583 brw_vec1_grf(unsigned nr, unsigned subnr)
584 {
585 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
586 }
587
588 /** Construct float[2] general-purpose register */
589 static inline struct brw_reg
590 brw_vec2_grf(unsigned nr, unsigned subnr)
591 {
592 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
593 }
594
595 /** Construct float[4] general-purpose register */
596 static inline struct brw_reg
597 brw_vec4_grf(unsigned nr, unsigned subnr)
598 {
599 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
600 }
601
602 /** Construct float[8] general-purpose register */
603 static inline struct brw_reg
604 brw_vec8_grf(unsigned nr, unsigned subnr)
605 {
606 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
607 }
608
609
610 static inline struct brw_reg
611 brw_uw8_grf(unsigned nr, unsigned subnr)
612 {
613 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
614 }
615
616 static inline struct brw_reg
617 brw_uw16_grf(unsigned nr, unsigned subnr)
618 {
619 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
620 }
621
622
623 /** Construct null register (usually used for setting condition codes) */
624 static inline struct brw_reg
625 brw_null_reg(void)
626 {
627 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
628 }
629
630 static inline struct brw_reg
631 brw_null_vec(unsigned width)
632 {
633 return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
634 }
635
636 static inline struct brw_reg
637 brw_address_reg(unsigned subnr)
638 {
639 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
640 }
641
642 /* If/else instructions break in align16 mode if writemask & swizzle
643 * aren't xyzw. This goes against the convention for other scalar
644 * regs:
645 */
646 static inline struct brw_reg
647 brw_ip_reg(void)
648 {
649 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
650 BRW_ARF_IP,
651 0,
652 0,
653 0,
654 BRW_REGISTER_TYPE_UD,
655 BRW_VERTICAL_STRIDE_4, /* ? */
656 BRW_WIDTH_1,
657 BRW_HORIZONTAL_STRIDE_0,
658 BRW_SWIZZLE_XYZW, /* NOTE! */
659 WRITEMASK_XYZW); /* NOTE! */
660 }
661
662 static inline struct brw_reg
663 brw_acc_reg(unsigned width)
664 {
665 return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE,
666 BRW_ARF_ACCUMULATOR, 0);
667 }
668
669 static inline struct brw_reg
670 brw_flag_reg(int reg, int subreg)
671 {
672 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
673 BRW_ARF_FLAG + reg, subreg);
674 }
675
676
677 static inline struct brw_reg
678 brw_mask_reg(unsigned subnr)
679 {
680 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
681 }
682
683 static inline struct brw_reg
684 brw_message_reg(unsigned nr)
685 {
686 assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
687 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
688 }
689
690 static inline struct brw_reg
691 brw_uvec_mrf(unsigned width, unsigned nr, unsigned subnr)
692 {
693 return retype(brw_vecn_reg(width, BRW_MESSAGE_REGISTER_FILE, nr, subnr),
694 BRW_REGISTER_TYPE_UD);
695 }
696
697 /* This is almost always called with a numeric constant argument, so
698 * make things easy to evaluate at compile time:
699 */
700 static inline unsigned cvt(unsigned val)
701 {
702 switch (val) {
703 case 0: return 0;
704 case 1: return 1;
705 case 2: return 2;
706 case 4: return 3;
707 case 8: return 4;
708 case 16: return 5;
709 case 32: return 6;
710 }
711 return 0;
712 }
713
714 static inline struct brw_reg
715 stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
716 {
717 reg.vstride = cvt(vstride);
718 reg.width = cvt(width) - 1;
719 reg.hstride = cvt(hstride);
720 return reg;
721 }
722
723
724 static inline struct brw_reg
725 vec16(struct brw_reg reg)
726 {
727 return stride(reg, 16,16,1);
728 }
729
730 static inline struct brw_reg
731 vec8(struct brw_reg reg)
732 {
733 return stride(reg, 8,8,1);
734 }
735
736 static inline struct brw_reg
737 vec4(struct brw_reg reg)
738 {
739 return stride(reg, 4,4,1);
740 }
741
742 static inline struct brw_reg
743 vec2(struct brw_reg reg)
744 {
745 return stride(reg, 2,2,1);
746 }
747
748 static inline struct brw_reg
749 vec1(struct brw_reg reg)
750 {
751 return stride(reg, 0,1,0);
752 }
753
754
755 static inline struct brw_reg
756 get_element(struct brw_reg reg, unsigned elt)
757 {
758 return vec1(suboffset(reg, elt));
759 }
760
761 static inline struct brw_reg
762 get_element_ud(struct brw_reg reg, unsigned elt)
763 {
764 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
765 }
766
767 static inline struct brw_reg
768 get_element_d(struct brw_reg reg, unsigned elt)
769 {
770 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
771 }
772
773
774 static inline struct brw_reg
775 brw_swizzle(struct brw_reg reg, unsigned x, unsigned y, unsigned z, unsigned w)
776 {
777 assert(reg.file != BRW_IMMEDIATE_VALUE);
778
779 reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
780 BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
781 BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
782 BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
783 return reg;
784 }
785
786
787 static inline struct brw_reg
788 brw_swizzle1(struct brw_reg reg, unsigned x)
789 {
790 return brw_swizzle(reg, x, x, x, x);
791 }
792
793 static inline struct brw_reg
794 brw_writemask(struct brw_reg reg, unsigned mask)
795 {
796 assert(reg.file != BRW_IMMEDIATE_VALUE);
797 reg.dw1.bits.writemask &= mask;
798 return reg;
799 }
800
801 static inline struct brw_reg
802 brw_set_writemask(struct brw_reg reg, unsigned mask)
803 {
804 assert(reg.file != BRW_IMMEDIATE_VALUE);
805 reg.dw1.bits.writemask = mask;
806 return reg;
807 }
808
809 static inline struct brw_reg
810 negate(struct brw_reg reg)
811 {
812 reg.negate ^= 1;
813 return reg;
814 }
815
816 static inline struct brw_reg
817 brw_abs(struct brw_reg reg)
818 {
819 reg.abs = 1;
820 reg.negate = 0;
821 return reg;
822 }
823
824 /************************************************************************/
825
826 static inline struct brw_reg
827 brw_vec4_indirect(unsigned subnr, int offset)
828 {
829 struct brw_reg reg = brw_vec4_grf(0, 0);
830 reg.subnr = subnr;
831 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
832 reg.dw1.bits.indirect_offset = offset;
833 return reg;
834 }
835
836 static inline struct brw_reg
837 brw_vec1_indirect(unsigned subnr, int offset)
838 {
839 struct brw_reg reg = brw_vec1_grf(0, 0);
840 reg.subnr = subnr;
841 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
842 reg.dw1.bits.indirect_offset = offset;
843 return reg;
844 }
845
846 static inline struct brw_reg
847 deref_4f(struct brw_indirect ptr, int offset)
848 {
849 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
850 }
851
852 static inline struct brw_reg
853 deref_1f(struct brw_indirect ptr, int offset)
854 {
855 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
856 }
857
858 static inline struct brw_reg
859 deref_4b(struct brw_indirect ptr, int offset)
860 {
861 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
862 }
863
864 static inline struct brw_reg
865 deref_1uw(struct brw_indirect ptr, int offset)
866 {
867 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
868 }
869
870 static inline struct brw_reg
871 deref_1d(struct brw_indirect ptr, int offset)
872 {
873 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
874 }
875
876 static inline struct brw_reg
877 deref_1ud(struct brw_indirect ptr, int offset)
878 {
879 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
880 }
881
882 static inline struct brw_reg
883 get_addr_reg(struct brw_indirect ptr)
884 {
885 return brw_address_reg(ptr.addr_subnr);
886 }
887
888 static inline struct brw_indirect
889 brw_indirect_offset(struct brw_indirect ptr, int offset)
890 {
891 ptr.addr_offset += offset;
892 return ptr;
893 }
894
895 static inline struct brw_indirect
896 brw_indirect(unsigned addr_subnr, int offset)
897 {
898 struct brw_indirect ptr;
899 ptr.addr_subnr = addr_subnr;
900 ptr.addr_offset = offset;
901 ptr.pad = 0;
902 return ptr;
903 }
904
905 static inline bool
906 region_matches(struct brw_reg reg, enum brw_vertical_stride v,
907 enum brw_width w, enum brw_horizontal_stride h)
908 {
909 return reg.vstride == v &&
910 reg.width == w &&
911 reg.hstride == h;
912 }
913
914 #define has_scalar_region(reg) \
915 region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
916 BRW_HORIZONTAL_STRIDE_0)
917
918 /* brw_packed_float.c */
919 int brw_float_to_vf(float f);
920 float brw_vf_to_float(unsigned char vf);
921
922 #ifdef __cplusplus
923 }
924 #endif
925
926 #endif