a4bcfca0b1d8cdbd7ffff6b28d459c562970e88b
[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/compiler.h"
47 #include "main/macros.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_device_info;
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(gen) (gen == 6 ? 24 : 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_XZXZ BRW_SWIZZLE4(0,2,0,2)
85 #define BRW_SWIZZLE_YZXW BRW_SWIZZLE4(1,2,0,3)
86 #define BRW_SWIZZLE_YWYW BRW_SWIZZLE4(1,3,1,3)
87 #define BRW_SWIZZLE_ZXYW BRW_SWIZZLE4(2,0,1,3)
88 #define BRW_SWIZZLE_ZWZW BRW_SWIZZLE4(2,3,2,3)
89 #define BRW_SWIZZLE_WZYX BRW_SWIZZLE4(3,2,1,0)
90
91 static inline bool
92 brw_is_single_value_swizzle(unsigned swiz)
93 {
94 return (swiz == BRW_SWIZZLE_XXXX ||
95 swiz == BRW_SWIZZLE_YYYY ||
96 swiz == BRW_SWIZZLE_ZZZZ ||
97 swiz == BRW_SWIZZLE_WWWW);
98 }
99
100 /**
101 * Compute the swizzle obtained from the application of \p swz0 on the result
102 * of \p swz1. The argument ordering is expected to match function
103 * composition.
104 */
105 static inline unsigned
106 brw_compose_swizzle(unsigned swz0, unsigned swz1)
107 {
108 return BRW_SWIZZLE4(
109 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 0)),
110 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 1)),
111 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 2)),
112 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 3)));
113 }
114
115 /**
116 * Return the result of applying swizzle \p swz to shuffle the bits of \p mask
117 * (AKA image).
118 */
119 static inline unsigned
120 brw_apply_swizzle_to_mask(unsigned swz, unsigned mask)
121 {
122 unsigned result = 0;
123
124 for (unsigned i = 0; i < 4; i++) {
125 if (mask & (1 << BRW_GET_SWZ(swz, i)))
126 result |= 1 << i;
127 }
128
129 return result;
130 }
131
132 /**
133 * Return the result of applying the inverse of swizzle \p swz to shuffle the
134 * bits of \p mask (AKA preimage). Useful to find out which components are
135 * read from a swizzled source given the instruction writemask.
136 */
137 static inline unsigned
138 brw_apply_inv_swizzle_to_mask(unsigned swz, unsigned mask)
139 {
140 unsigned result = 0;
141
142 for (unsigned i = 0; i < 4; i++) {
143 if (mask & (1 << i))
144 result |= 1 << BRW_GET_SWZ(swz, i);
145 }
146
147 return result;
148 }
149
150 /**
151 * Construct an identity swizzle for the set of enabled channels given by \p
152 * mask. The result will only reference channels enabled in the provided \p
153 * mask, assuming that \p mask is non-zero. The constructed swizzle will
154 * satisfy the property that for any instruction OP and any mask:
155 *
156 * brw_OP(p, brw_writemask(dst, mask),
157 * brw_swizzle(src, brw_swizzle_for_mask(mask)));
158 *
159 * will be equivalent to the same instruction without swizzle:
160 *
161 * brw_OP(p, brw_writemask(dst, mask), src);
162 */
163 static inline unsigned
164 brw_swizzle_for_mask(unsigned mask)
165 {
166 unsigned last = (mask ? ffs(mask) - 1 : 0);
167 unsigned swz[4];
168
169 for (unsigned i = 0; i < 4; i++)
170 last = swz[i] = (mask & (1 << i) ? i : last);
171
172 return BRW_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
173 }
174
175 /**
176 * Construct an identity swizzle for the first \p n components of a vector.
177 * When only a subset of channels of a vec4 are used we don't want to
178 * reference the other channels, as that will tell optimization passes that
179 * those other channels are used.
180 */
181 static inline unsigned
182 brw_swizzle_for_size(unsigned n)
183 {
184 return brw_swizzle_for_mask((1 << n) - 1);
185 }
186
187 /**
188 * Converse of brw_swizzle_for_mask(). Returns the mask of components
189 * accessed by the specified swizzle \p swz.
190 */
191 static inline unsigned
192 brw_mask_for_swizzle(unsigned swz)
193 {
194 return brw_apply_inv_swizzle_to_mask(swz, ~0);
195 }
196
197 enum PACKED brw_reg_type {
198 BRW_REGISTER_TYPE_UD = 0,
199 BRW_REGISTER_TYPE_D,
200 BRW_REGISTER_TYPE_UW,
201 BRW_REGISTER_TYPE_W,
202 BRW_REGISTER_TYPE_F,
203
204 /** Non-immediates only: @{ */
205 BRW_REGISTER_TYPE_UB,
206 BRW_REGISTER_TYPE_B,
207 /** @} */
208
209 /** Immediates only: @{ */
210 BRW_REGISTER_TYPE_UV, /* Gen6+ */
211 BRW_REGISTER_TYPE_V,
212 BRW_REGISTER_TYPE_VF,
213 /** @} */
214
215 BRW_REGISTER_TYPE_DF, /* Gen7+ (no immediates until Gen8+) */
216
217 /* Gen8+ */
218 BRW_REGISTER_TYPE_HF,
219 BRW_REGISTER_TYPE_UQ,
220 BRW_REGISTER_TYPE_Q,
221 };
222
223 unsigned brw_reg_type_to_hw_type(const struct brw_device_info *devinfo,
224 enum brw_reg_type type, enum brw_reg_file file);
225 const char *brw_reg_type_letters(unsigned brw_reg_type);
226
227 #define REG_SIZE (8*4)
228
229 /* These aren't hardware structs, just something useful for us to pass around:
230 *
231 * Align1 operation has a lot of control over input ranges. Used in
232 * WM programs to implement shaders decomposed into "channel serial"
233 * or "structure of array" form:
234 */
235 struct brw_reg {
236 enum brw_reg_type type:4;
237 enum brw_reg_file file:3; /* :2 hardware format */
238 unsigned negate:1; /* source only */
239 unsigned abs:1; /* source only */
240 unsigned address_mode:1; /* relative addressing, hopefully! */
241 unsigned pad0:1;
242 unsigned subnr:5; /* :1 in align16 */
243 unsigned nr:16;
244
245 union {
246 struct {
247 unsigned swizzle:8; /* src only, align16 only */
248 unsigned writemask:4; /* dest only, align16 only */
249 int indirect_offset:10; /* relative addressing offset */
250 unsigned vstride:4; /* source only */
251 unsigned width:3; /* src only, align1 only */
252 unsigned hstride:2; /* align1 only */
253 unsigned pad1:1;
254 };
255
256 float f;
257 int d;
258 unsigned ud;
259 };
260 };
261
262
263 struct brw_indirect {
264 unsigned addr_subnr:4;
265 int addr_offset:10;
266 unsigned pad:18;
267 };
268
269
270 static inline unsigned
271 type_sz(unsigned type)
272 {
273 switch(type) {
274 case BRW_REGISTER_TYPE_UQ:
275 case BRW_REGISTER_TYPE_Q:
276 return 8;
277 case BRW_REGISTER_TYPE_UD:
278 case BRW_REGISTER_TYPE_D:
279 case BRW_REGISTER_TYPE_F:
280 return 4;
281 case BRW_REGISTER_TYPE_UW:
282 case BRW_REGISTER_TYPE_W:
283 return 2;
284 case BRW_REGISTER_TYPE_UB:
285 case BRW_REGISTER_TYPE_B:
286 return 1;
287 default:
288 return 0;
289 }
290 }
291
292 /**
293 * Construct a brw_reg.
294 * \param file one of the BRW_x_REGISTER_FILE values
295 * \param nr register number/index
296 * \param subnr register sub number
297 * \param negate register negate modifier
298 * \param abs register abs modifier
299 * \param type one of BRW_REGISTER_TYPE_x
300 * \param vstride one of BRW_VERTICAL_STRIDE_x
301 * \param width one of BRW_WIDTH_x
302 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
303 * \param swizzle one of BRW_SWIZZLE_x
304 * \param writemask WRITEMASK_X/Y/Z/W bitfield
305 */
306 static inline struct brw_reg
307 brw_reg(enum brw_reg_file file,
308 unsigned nr,
309 unsigned subnr,
310 unsigned negate,
311 unsigned abs,
312 enum brw_reg_type type,
313 unsigned vstride,
314 unsigned width,
315 unsigned hstride,
316 unsigned swizzle,
317 unsigned writemask)
318 {
319 struct brw_reg reg;
320 if (file == BRW_GENERAL_REGISTER_FILE)
321 assert(nr < BRW_MAX_GRF);
322 else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
323 assert(nr <= BRW_ARF_TIMESTAMP);
324 /* Asserting on the MRF register number requires to know the hardware gen
325 * (gen6 has 24 MRF registers), which we don't know here, so we assert
326 * for that in the generators and in brw_eu_emit.c
327 */
328
329 reg.type = type;
330 reg.file = file;
331 reg.negate = negate;
332 reg.abs = abs;
333 reg.address_mode = BRW_ADDRESS_DIRECT;
334 reg.pad0 = 0;
335 reg.subnr = subnr * type_sz(type);
336 reg.nr = nr;
337
338 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
339 * set swizzle and writemask to W, as the lower bits of subnr will
340 * be lost when converted to align16. This is probably too much to
341 * keep track of as you'd want it adjusted by suboffset(), etc.
342 * Perhaps fix up when converting to align16?
343 */
344 reg.swizzle = swizzle;
345 reg.writemask = writemask;
346 reg.indirect_offset = 0;
347 reg.vstride = vstride;
348 reg.width = width;
349 reg.hstride = hstride;
350 reg.pad1 = 0;
351 return reg;
352 }
353
354 /** Construct float[16] register */
355 static inline struct brw_reg
356 brw_vec16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
357 {
358 return brw_reg(file,
359 nr,
360 subnr,
361 0,
362 0,
363 BRW_REGISTER_TYPE_F,
364 BRW_VERTICAL_STRIDE_16,
365 BRW_WIDTH_16,
366 BRW_HORIZONTAL_STRIDE_1,
367 BRW_SWIZZLE_XYZW,
368 WRITEMASK_XYZW);
369 }
370
371 /** Construct float[8] register */
372 static inline struct brw_reg
373 brw_vec8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
374 {
375 return brw_reg(file,
376 nr,
377 subnr,
378 0,
379 0,
380 BRW_REGISTER_TYPE_F,
381 BRW_VERTICAL_STRIDE_8,
382 BRW_WIDTH_8,
383 BRW_HORIZONTAL_STRIDE_1,
384 BRW_SWIZZLE_XYZW,
385 WRITEMASK_XYZW);
386 }
387
388 /** Construct float[4] register */
389 static inline struct brw_reg
390 brw_vec4_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
391 {
392 return brw_reg(file,
393 nr,
394 subnr,
395 0,
396 0,
397 BRW_REGISTER_TYPE_F,
398 BRW_VERTICAL_STRIDE_4,
399 BRW_WIDTH_4,
400 BRW_HORIZONTAL_STRIDE_1,
401 BRW_SWIZZLE_XYZW,
402 WRITEMASK_XYZW);
403 }
404
405 /** Construct float[2] register */
406 static inline struct brw_reg
407 brw_vec2_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
408 {
409 return brw_reg(file,
410 nr,
411 subnr,
412 0,
413 0,
414 BRW_REGISTER_TYPE_F,
415 BRW_VERTICAL_STRIDE_2,
416 BRW_WIDTH_2,
417 BRW_HORIZONTAL_STRIDE_1,
418 BRW_SWIZZLE_XYXY,
419 WRITEMASK_XY);
420 }
421
422 /** Construct float[1] register */
423 static inline struct brw_reg
424 brw_vec1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
425 {
426 return brw_reg(file,
427 nr,
428 subnr,
429 0,
430 0,
431 BRW_REGISTER_TYPE_F,
432 BRW_VERTICAL_STRIDE_0,
433 BRW_WIDTH_1,
434 BRW_HORIZONTAL_STRIDE_0,
435 BRW_SWIZZLE_XXXX,
436 WRITEMASK_X);
437 }
438
439 static inline struct brw_reg
440 brw_vecn_reg(unsigned width, enum brw_reg_file file,
441 unsigned nr, unsigned subnr)
442 {
443 switch (width) {
444 case 1:
445 return brw_vec1_reg(file, nr, subnr);
446 case 2:
447 return brw_vec2_reg(file, nr, subnr);
448 case 4:
449 return brw_vec4_reg(file, nr, subnr);
450 case 8:
451 return brw_vec8_reg(file, nr, subnr);
452 case 16:
453 return brw_vec16_reg(file, nr, subnr);
454 default:
455 unreachable("Invalid register width");
456 }
457 }
458
459 static inline struct brw_reg
460 retype(struct brw_reg reg, enum brw_reg_type type)
461 {
462 reg.type = type;
463 return reg;
464 }
465
466 static inline struct brw_reg
467 firsthalf(struct brw_reg reg)
468 {
469 return reg;
470 }
471
472 static inline struct brw_reg
473 sechalf(struct brw_reg reg)
474 {
475 if (reg.vstride)
476 reg.nr++;
477 return reg;
478 }
479
480 static inline struct brw_reg
481 suboffset(struct brw_reg reg, unsigned delta)
482 {
483 reg.subnr += delta * type_sz(reg.type);
484 return reg;
485 }
486
487
488 static inline struct brw_reg
489 offset(struct brw_reg reg, unsigned delta)
490 {
491 reg.nr += delta;
492 return reg;
493 }
494
495
496 static inline struct brw_reg
497 byte_offset(struct brw_reg reg, unsigned bytes)
498 {
499 unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
500 reg.nr = newoffset / REG_SIZE;
501 reg.subnr = newoffset % REG_SIZE;
502 return reg;
503 }
504
505
506 /** Construct unsigned word[16] register */
507 static inline struct brw_reg
508 brw_uw16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
509 {
510 return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
511 }
512
513 /** Construct unsigned word[8] register */
514 static inline struct brw_reg
515 brw_uw8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
516 {
517 return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
518 }
519
520 /** Construct unsigned word[1] register */
521 static inline struct brw_reg
522 brw_uw1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
523 {
524 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
525 }
526
527 static inline struct brw_reg
528 brw_imm_reg(enum brw_reg_type type)
529 {
530 return brw_reg(BRW_IMMEDIATE_VALUE,
531 0,
532 0,
533 0,
534 0,
535 type,
536 BRW_VERTICAL_STRIDE_0,
537 BRW_WIDTH_1,
538 BRW_HORIZONTAL_STRIDE_0,
539 0,
540 0);
541 }
542
543 /** Construct float immediate register */
544 static inline struct brw_reg
545 brw_imm_f(float f)
546 {
547 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
548 imm.f = f;
549 return imm;
550 }
551
552 /** Construct integer immediate register */
553 static inline struct brw_reg
554 brw_imm_d(int d)
555 {
556 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
557 imm.d = d;
558 return imm;
559 }
560
561 /** Construct uint immediate register */
562 static inline struct brw_reg
563 brw_imm_ud(unsigned ud)
564 {
565 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
566 imm.ud = ud;
567 return imm;
568 }
569
570 /** Construct ushort immediate register */
571 static inline struct brw_reg
572 brw_imm_uw(uint16_t uw)
573 {
574 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
575 imm.ud = uw | (uw << 16);
576 return imm;
577 }
578
579 /** Construct short immediate register */
580 static inline struct brw_reg
581 brw_imm_w(int16_t w)
582 {
583 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
584 imm.d = w | (w << 16);
585 return imm;
586 }
587
588 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
589 * numbers alias with _V and _VF below:
590 */
591
592 /** Construct vector of eight signed half-byte values */
593 static inline struct brw_reg
594 brw_imm_v(unsigned v)
595 {
596 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
597 imm.ud = v;
598 return imm;
599 }
600
601 /** Construct vector of eight unsigned half-byte values */
602 static inline struct brw_reg
603 brw_imm_uv(unsigned uv)
604 {
605 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UV);
606 imm.ud = uv;
607 return imm;
608 }
609
610 /** Construct vector of four 8-bit float values */
611 static inline struct brw_reg
612 brw_imm_vf(unsigned v)
613 {
614 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
615 imm.ud = v;
616 return imm;
617 }
618
619 static inline struct brw_reg
620 brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
621 {
622 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
623 imm.vstride = BRW_VERTICAL_STRIDE_0;
624 imm.width = BRW_WIDTH_4;
625 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
626 imm.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24));
627 return imm;
628 }
629
630
631 static inline struct brw_reg
632 brw_address(struct brw_reg reg)
633 {
634 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
635 }
636
637 /** Construct float[1] general-purpose register */
638 static inline struct brw_reg
639 brw_vec1_grf(unsigned nr, unsigned subnr)
640 {
641 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
642 }
643
644 /** Construct float[2] general-purpose register */
645 static inline struct brw_reg
646 brw_vec2_grf(unsigned nr, unsigned subnr)
647 {
648 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
649 }
650
651 /** Construct float[4] general-purpose register */
652 static inline struct brw_reg
653 brw_vec4_grf(unsigned nr, unsigned subnr)
654 {
655 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
656 }
657
658 /** Construct float[8] general-purpose register */
659 static inline struct brw_reg
660 brw_vec8_grf(unsigned nr, unsigned subnr)
661 {
662 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
663 }
664
665 /** Construct float[16] general-purpose register */
666 static inline struct brw_reg
667 brw_vec16_grf(unsigned nr, unsigned subnr)
668 {
669 return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
670 }
671
672
673 static inline struct brw_reg
674 brw_uw8_grf(unsigned nr, unsigned subnr)
675 {
676 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
677 }
678
679 static inline struct brw_reg
680 brw_uw16_grf(unsigned nr, unsigned subnr)
681 {
682 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
683 }
684
685
686 /** Construct null register (usually used for setting condition codes) */
687 static inline struct brw_reg
688 brw_null_reg(void)
689 {
690 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
691 }
692
693 static inline struct brw_reg
694 brw_null_vec(unsigned width)
695 {
696 return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
697 }
698
699 static inline struct brw_reg
700 brw_address_reg(unsigned subnr)
701 {
702 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
703 }
704
705 /* If/else instructions break in align16 mode if writemask & swizzle
706 * aren't xyzw. This goes against the convention for other scalar
707 * regs:
708 */
709 static inline struct brw_reg
710 brw_ip_reg(void)
711 {
712 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
713 BRW_ARF_IP,
714 0,
715 0,
716 0,
717 BRW_REGISTER_TYPE_UD,
718 BRW_VERTICAL_STRIDE_4, /* ? */
719 BRW_WIDTH_1,
720 BRW_HORIZONTAL_STRIDE_0,
721 BRW_SWIZZLE_XYZW, /* NOTE! */
722 WRITEMASK_XYZW); /* NOTE! */
723 }
724
725 static inline struct brw_reg
726 brw_notification_reg(void)
727 {
728 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
729 BRW_ARF_NOTIFICATION_COUNT,
730 0,
731 0,
732 0,
733 BRW_REGISTER_TYPE_UD,
734 BRW_VERTICAL_STRIDE_0,
735 BRW_WIDTH_1,
736 BRW_HORIZONTAL_STRIDE_0,
737 BRW_SWIZZLE_XXXX,
738 WRITEMASK_X);
739 }
740
741 static inline struct brw_reg
742 brw_acc_reg(unsigned width)
743 {
744 return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE,
745 BRW_ARF_ACCUMULATOR, 0);
746 }
747
748 static inline struct brw_reg
749 brw_flag_reg(int reg, int subreg)
750 {
751 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
752 BRW_ARF_FLAG + reg, subreg);
753 }
754
755 /**
756 * Return the mask register present in Gen4-5, or the related register present
757 * in Gen7.5 and later hardware referred to as "channel enable" register in
758 * the documentation.
759 */
760 static inline struct brw_reg
761 brw_mask_reg(unsigned subnr)
762 {
763 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
764 }
765
766 static inline struct brw_reg
767 brw_message_reg(unsigned nr)
768 {
769 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
770 }
771
772 static inline struct brw_reg
773 brw_uvec_mrf(unsigned width, unsigned nr, unsigned subnr)
774 {
775 return retype(brw_vecn_reg(width, BRW_MESSAGE_REGISTER_FILE, nr, subnr),
776 BRW_REGISTER_TYPE_UD);
777 }
778
779 /* This is almost always called with a numeric constant argument, so
780 * make things easy to evaluate at compile time:
781 */
782 static inline unsigned cvt(unsigned val)
783 {
784 switch (val) {
785 case 0: return 0;
786 case 1: return 1;
787 case 2: return 2;
788 case 4: return 3;
789 case 8: return 4;
790 case 16: return 5;
791 case 32: return 6;
792 }
793 return 0;
794 }
795
796 static inline struct brw_reg
797 stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
798 {
799 reg.vstride = cvt(vstride);
800 reg.width = cvt(width) - 1;
801 reg.hstride = cvt(hstride);
802 return reg;
803 }
804
805 /**
806 * Multiply the vertical and horizontal stride of a register by the given
807 * factor \a s.
808 */
809 static inline struct brw_reg
810 spread(struct brw_reg reg, unsigned s)
811 {
812 if (s) {
813 assert(_mesa_is_pow_two(s));
814
815 if (reg.hstride)
816 reg.hstride += cvt(s) - 1;
817
818 if (reg.vstride)
819 reg.vstride += cvt(s) - 1;
820
821 return reg;
822 } else {
823 return stride(reg, 0, 1, 0);
824 }
825 }
826
827 static inline struct brw_reg
828 vec16(struct brw_reg reg)
829 {
830 return stride(reg, 16,16,1);
831 }
832
833 static inline struct brw_reg
834 vec8(struct brw_reg reg)
835 {
836 return stride(reg, 8,8,1);
837 }
838
839 static inline struct brw_reg
840 vec4(struct brw_reg reg)
841 {
842 return stride(reg, 4,4,1);
843 }
844
845 static inline struct brw_reg
846 vec2(struct brw_reg reg)
847 {
848 return stride(reg, 2,2,1);
849 }
850
851 static inline struct brw_reg
852 vec1(struct brw_reg reg)
853 {
854 return stride(reg, 0,1,0);
855 }
856
857
858 static inline struct brw_reg
859 get_element(struct brw_reg reg, unsigned elt)
860 {
861 return vec1(suboffset(reg, elt));
862 }
863
864 static inline struct brw_reg
865 get_element_ud(struct brw_reg reg, unsigned elt)
866 {
867 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
868 }
869
870 static inline struct brw_reg
871 get_element_d(struct brw_reg reg, unsigned elt)
872 {
873 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
874 }
875
876 static inline struct brw_reg
877 brw_swizzle(struct brw_reg reg, unsigned swz)
878 {
879 assert(reg.file != BRW_IMMEDIATE_VALUE);
880
881 reg.swizzle = brw_compose_swizzle(swz, reg.swizzle);
882 return reg;
883 }
884
885 static inline struct brw_reg
886 brw_writemask(struct brw_reg reg, unsigned mask)
887 {
888 assert(reg.file != BRW_IMMEDIATE_VALUE);
889 reg.writemask &= mask;
890 return reg;
891 }
892
893 static inline struct brw_reg
894 brw_set_writemask(struct brw_reg reg, unsigned mask)
895 {
896 assert(reg.file != BRW_IMMEDIATE_VALUE);
897 reg.writemask = mask;
898 return reg;
899 }
900
901 static inline unsigned
902 brw_writemask_for_size(unsigned n)
903 {
904 return (1 << n) - 1;
905 }
906
907 static inline struct brw_reg
908 negate(struct brw_reg reg)
909 {
910 reg.negate ^= 1;
911 return reg;
912 }
913
914 static inline struct brw_reg
915 brw_abs(struct brw_reg reg)
916 {
917 reg.abs = 1;
918 reg.negate = 0;
919 return reg;
920 }
921
922 /************************************************************************/
923
924 static inline struct brw_reg
925 brw_vec4_indirect(unsigned subnr, int offset)
926 {
927 struct brw_reg reg = brw_vec4_grf(0, 0);
928 reg.subnr = subnr;
929 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
930 reg.indirect_offset = offset;
931 return reg;
932 }
933
934 static inline struct brw_reg
935 brw_vec1_indirect(unsigned subnr, int offset)
936 {
937 struct brw_reg reg = brw_vec1_grf(0, 0);
938 reg.subnr = subnr;
939 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
940 reg.indirect_offset = offset;
941 return reg;
942 }
943
944 static inline struct brw_reg
945 brw_VxH_indirect(unsigned subnr, int offset)
946 {
947 struct brw_reg reg = brw_vec1_grf(0, 0);
948 reg.vstride = BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL;
949 reg.subnr = subnr;
950 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
951 reg.indirect_offset = offset;
952 return reg;
953 }
954
955 static inline struct brw_reg
956 deref_4f(struct brw_indirect ptr, int offset)
957 {
958 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
959 }
960
961 static inline struct brw_reg
962 deref_1f(struct brw_indirect ptr, int offset)
963 {
964 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
965 }
966
967 static inline struct brw_reg
968 deref_4b(struct brw_indirect ptr, int offset)
969 {
970 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
971 }
972
973 static inline struct brw_reg
974 deref_1uw(struct brw_indirect ptr, int offset)
975 {
976 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
977 }
978
979 static inline struct brw_reg
980 deref_1d(struct brw_indirect ptr, int offset)
981 {
982 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
983 }
984
985 static inline struct brw_reg
986 deref_1ud(struct brw_indirect ptr, int offset)
987 {
988 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
989 }
990
991 static inline struct brw_reg
992 get_addr_reg(struct brw_indirect ptr)
993 {
994 return brw_address_reg(ptr.addr_subnr);
995 }
996
997 static inline struct brw_indirect
998 brw_indirect_offset(struct brw_indirect ptr, int offset)
999 {
1000 ptr.addr_offset += offset;
1001 return ptr;
1002 }
1003
1004 static inline struct brw_indirect
1005 brw_indirect(unsigned addr_subnr, int offset)
1006 {
1007 struct brw_indirect ptr;
1008 ptr.addr_subnr = addr_subnr;
1009 ptr.addr_offset = offset;
1010 ptr.pad = 0;
1011 return ptr;
1012 }
1013
1014 static inline bool
1015 region_matches(struct brw_reg reg, enum brw_vertical_stride v,
1016 enum brw_width w, enum brw_horizontal_stride h)
1017 {
1018 return reg.vstride == v &&
1019 reg.width == w &&
1020 reg.hstride == h;
1021 }
1022
1023 #define has_scalar_region(reg) \
1024 region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
1025 BRW_HORIZONTAL_STRIDE_0)
1026
1027 /* brw_packed_float.c */
1028 int brw_float_to_vf(float f);
1029 float brw_vf_to_float(unsigned char vf);
1030
1031 #ifdef __cplusplus
1032 }
1033 #endif
1034
1035 #endif