Added few more stubs so that control reaches to DestroyDevice().
[mesa.git] / src / intel / compiler / 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 "util/compiler.h"
47 #include "main/macros.h"
48 #include "program/prog_instruction.h"
49 #include "brw_eu_defines.h"
50 #include "brw_reg_type.h"
51
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55
56 struct gen_device_info;
57
58 /** Number of general purpose registers (VS, WM, etc) */
59 #define BRW_MAX_GRF 128
60
61 /**
62 * First GRF used for the MRF hack.
63 *
64 * On gen7, MRFs are no longer used, and contiguous GRFs are used instead. We
65 * haven't converted our compiler to be aware of this, so it asks for MRFs and
66 * brw_eu_emit.c quietly converts them to be accesses of the top GRFs. The
67 * register allocators have to be careful of this to avoid corrupting the "MRF"s
68 * with actual GRF allocations.
69 */
70 #define GEN7_MRF_HACK_START 112
71
72 /** Number of message register file registers */
73 #define BRW_MAX_MRF(gen) (gen == 6 ? 24 : 16)
74
75 #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
76 #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
77
78 #define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3)
79 #define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3)
80 #define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0)
81 #define BRW_SWIZZLE_YYYY BRW_SWIZZLE4(1,1,1,1)
82 #define BRW_SWIZZLE_ZZZZ BRW_SWIZZLE4(2,2,2,2)
83 #define BRW_SWIZZLE_WWWW BRW_SWIZZLE4(3,3,3,3)
84 #define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1)
85 #define BRW_SWIZZLE_YXYX BRW_SWIZZLE4(1,0,1,0)
86 #define BRW_SWIZZLE_XZXZ BRW_SWIZZLE4(0,2,0,2)
87 #define BRW_SWIZZLE_YZXW BRW_SWIZZLE4(1,2,0,3)
88 #define BRW_SWIZZLE_YWYW BRW_SWIZZLE4(1,3,1,3)
89 #define BRW_SWIZZLE_ZXYW BRW_SWIZZLE4(2,0,1,3)
90 #define BRW_SWIZZLE_ZWZW BRW_SWIZZLE4(2,3,2,3)
91 #define BRW_SWIZZLE_WZWZ BRW_SWIZZLE4(3,2,3,2)
92 #define BRW_SWIZZLE_WZYX BRW_SWIZZLE4(3,2,1,0)
93 #define BRW_SWIZZLE_XXZZ BRW_SWIZZLE4(0,0,2,2)
94 #define BRW_SWIZZLE_YYWW BRW_SWIZZLE4(1,1,3,3)
95 #define BRW_SWIZZLE_YXWZ BRW_SWIZZLE4(1,0,3,2)
96
97 #define BRW_SWZ_COMP_INPUT(comp) (BRW_SWIZZLE_XYZW >> ((comp)*2))
98 #define BRW_SWZ_COMP_OUTPUT(comp) (BRW_SWIZZLE_XYZW << ((comp)*2))
99
100 static inline bool
101 brw_is_single_value_swizzle(unsigned swiz)
102 {
103 return (swiz == BRW_SWIZZLE_XXXX ||
104 swiz == BRW_SWIZZLE_YYYY ||
105 swiz == BRW_SWIZZLE_ZZZZ ||
106 swiz == BRW_SWIZZLE_WWWW);
107 }
108
109 /**
110 * Compute the swizzle obtained from the application of \p swz0 on the result
111 * of \p swz1. The argument ordering is expected to match function
112 * composition.
113 */
114 static inline unsigned
115 brw_compose_swizzle(unsigned swz0, unsigned swz1)
116 {
117 return BRW_SWIZZLE4(
118 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 0)),
119 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 1)),
120 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 2)),
121 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 3)));
122 }
123
124 /**
125 * Return the result of applying swizzle \p swz to shuffle the bits of \p mask
126 * (AKA image).
127 */
128 static inline unsigned
129 brw_apply_swizzle_to_mask(unsigned swz, unsigned mask)
130 {
131 unsigned result = 0;
132
133 for (unsigned i = 0; i < 4; i++) {
134 if (mask & (1 << BRW_GET_SWZ(swz, i)))
135 result |= 1 << i;
136 }
137
138 return result;
139 }
140
141 /**
142 * Return the result of applying the inverse of swizzle \p swz to shuffle the
143 * bits of \p mask (AKA preimage). Useful to find out which components are
144 * read from a swizzled source given the instruction writemask.
145 */
146 static inline unsigned
147 brw_apply_inv_swizzle_to_mask(unsigned swz, unsigned mask)
148 {
149 unsigned result = 0;
150
151 for (unsigned i = 0; i < 4; i++) {
152 if (mask & (1 << i))
153 result |= 1 << BRW_GET_SWZ(swz, i);
154 }
155
156 return result;
157 }
158
159 /**
160 * Construct an identity swizzle for the set of enabled channels given by \p
161 * mask. The result will only reference channels enabled in the provided \p
162 * mask, assuming that \p mask is non-zero. The constructed swizzle will
163 * satisfy the property that for any instruction OP and any mask:
164 *
165 * brw_OP(p, brw_writemask(dst, mask),
166 * brw_swizzle(src, brw_swizzle_for_mask(mask)));
167 *
168 * will be equivalent to the same instruction without swizzle:
169 *
170 * brw_OP(p, brw_writemask(dst, mask), src);
171 */
172 static inline unsigned
173 brw_swizzle_for_mask(unsigned mask)
174 {
175 unsigned last = (mask ? ffs(mask) - 1 : 0);
176 unsigned swz[4];
177
178 for (unsigned i = 0; i < 4; i++)
179 last = swz[i] = (mask & (1 << i) ? i : last);
180
181 return BRW_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
182 }
183
184 /**
185 * Construct an identity swizzle for the first \p n components of a vector.
186 * When only a subset of channels of a vec4 are used we don't want to
187 * reference the other channels, as that will tell optimization passes that
188 * those other channels are used.
189 */
190 static inline unsigned
191 brw_swizzle_for_size(unsigned n)
192 {
193 return brw_swizzle_for_mask((1 << n) - 1);
194 }
195
196 /**
197 * Converse of brw_swizzle_for_mask(). Returns the mask of components
198 * accessed by the specified swizzle \p swz.
199 */
200 static inline unsigned
201 brw_mask_for_swizzle(unsigned swz)
202 {
203 return brw_apply_inv_swizzle_to_mask(swz, ~0);
204 }
205
206 uint32_t brw_swizzle_immediate(enum brw_reg_type type, uint32_t x, unsigned swz);
207
208 #define REG_SIZE (8*4)
209
210 /* These aren't hardware structs, just something useful for us to pass around:
211 *
212 * Align1 operation has a lot of control over input ranges. Used in
213 * WM programs to implement shaders decomposed into "channel serial"
214 * or "structure of array" form:
215 */
216 struct brw_reg {
217 union {
218 struct {
219 enum brw_reg_type type:4;
220 enum brw_reg_file file:3; /* :2 hardware format */
221 unsigned negate:1; /* source only */
222 unsigned abs:1; /* source only */
223 unsigned address_mode:1; /* relative addressing, hopefully! */
224 unsigned pad0:17;
225 unsigned subnr:5; /* :1 in align16 */
226 };
227 uint32_t bits;
228 };
229
230 union {
231 struct {
232 unsigned nr;
233 unsigned swizzle:8; /* src only, align16 only */
234 unsigned writemask:4; /* dest only, align16 only */
235 int indirect_offset:10; /* relative addressing offset */
236 unsigned vstride:4; /* source only */
237 unsigned width:3; /* src only, align1 only */
238 unsigned hstride:2; /* align1 only */
239 unsigned pad1:1;
240 };
241
242 double df;
243 uint64_t u64;
244 int64_t d64;
245 float f;
246 int d;
247 unsigned ud;
248 };
249 };
250
251 static inline bool
252 brw_regs_equal(const struct brw_reg *a, const struct brw_reg *b)
253 {
254 return a->bits == b->bits && a->u64 == b->u64;
255 }
256
257 static inline bool
258 brw_regs_negative_equal(const struct brw_reg *a, const struct brw_reg *b)
259 {
260 if (a->file == IMM) {
261 if (a->bits != b->bits)
262 return false;
263
264 switch ((enum brw_reg_type) a->type) {
265 case BRW_REGISTER_TYPE_UQ:
266 case BRW_REGISTER_TYPE_Q:
267 return a->d64 == -b->d64;
268 case BRW_REGISTER_TYPE_DF:
269 return a->df == -b->df;
270 case BRW_REGISTER_TYPE_UD:
271 case BRW_REGISTER_TYPE_D:
272 return a->d == -b->d;
273 case BRW_REGISTER_TYPE_F:
274 return a->f == -b->f;
275 case BRW_REGISTER_TYPE_VF:
276 /* It is tempting to treat 0 as a negation of 0 (and -0 as a negation
277 * of -0). There are occasions where 0 or -0 is used and the exact
278 * bit pattern is desired. At the very least, changing this to allow
279 * 0 as a negation of 0 causes some fp64 tests to fail on IVB.
280 */
281 return a->ud == (b->ud ^ 0x80808080);
282 case BRW_REGISTER_TYPE_UW:
283 case BRW_REGISTER_TYPE_W:
284 case BRW_REGISTER_TYPE_UV:
285 case BRW_REGISTER_TYPE_V:
286 case BRW_REGISTER_TYPE_HF:
287 /* FINISHME: Implement support for these types once there is
288 * something in the compiler that can generate them. Until then,
289 * they cannot be tested.
290 */
291 return false;
292 case BRW_REGISTER_TYPE_UB:
293 case BRW_REGISTER_TYPE_B:
294 case BRW_REGISTER_TYPE_NF:
295 default:
296 unreachable("not reached");
297 }
298 } else {
299 struct brw_reg tmp = *a;
300
301 tmp.negate = !tmp.negate;
302
303 return brw_regs_equal(&tmp, b);
304 }
305 }
306
307 struct brw_indirect {
308 unsigned addr_subnr:4;
309 int addr_offset:10;
310 unsigned pad:18;
311 };
312
313
314 static inline unsigned
315 type_sz(unsigned type)
316 {
317 switch(type) {
318 case BRW_REGISTER_TYPE_UQ:
319 case BRW_REGISTER_TYPE_Q:
320 case BRW_REGISTER_TYPE_DF:
321 case BRW_REGISTER_TYPE_NF:
322 return 8;
323 case BRW_REGISTER_TYPE_UD:
324 case BRW_REGISTER_TYPE_D:
325 case BRW_REGISTER_TYPE_F:
326 case BRW_REGISTER_TYPE_VF:
327 return 4;
328 case BRW_REGISTER_TYPE_UW:
329 case BRW_REGISTER_TYPE_W:
330 case BRW_REGISTER_TYPE_UV:
331 case BRW_REGISTER_TYPE_V:
332 case BRW_REGISTER_TYPE_HF:
333 return 2;
334 case BRW_REGISTER_TYPE_UB:
335 case BRW_REGISTER_TYPE_B:
336 return 1;
337 default:
338 unreachable("not reached");
339 }
340 }
341
342 static inline enum brw_reg_type
343 get_exec_type(const enum brw_reg_type type)
344 {
345 switch (type) {
346 case BRW_REGISTER_TYPE_B:
347 case BRW_REGISTER_TYPE_V:
348 return BRW_REGISTER_TYPE_W;
349 case BRW_REGISTER_TYPE_UB:
350 case BRW_REGISTER_TYPE_UV:
351 return BRW_REGISTER_TYPE_UW;
352 case BRW_REGISTER_TYPE_VF:
353 return BRW_REGISTER_TYPE_F;
354 default:
355 return type;
356 }
357 }
358
359 /**
360 * Return an integer type of the requested size and signedness.
361 */
362 static inline enum brw_reg_type
363 brw_int_type(unsigned sz, bool is_signed)
364 {
365 switch (sz) {
366 case 1:
367 return (is_signed ? BRW_REGISTER_TYPE_B : BRW_REGISTER_TYPE_UB);
368 case 2:
369 return (is_signed ? BRW_REGISTER_TYPE_W : BRW_REGISTER_TYPE_UW);
370 case 4:
371 return (is_signed ? BRW_REGISTER_TYPE_D : BRW_REGISTER_TYPE_UD);
372 case 8:
373 return (is_signed ? BRW_REGISTER_TYPE_Q : BRW_REGISTER_TYPE_UQ);
374 default:
375 unreachable("Not reached.");
376 }
377 }
378
379 static inline bool
380 type_is_unsigned_int(enum brw_reg_type tp)
381 {
382 return tp == BRW_REGISTER_TYPE_UB ||
383 tp == BRW_REGISTER_TYPE_UW ||
384 tp == BRW_REGISTER_TYPE_UD ||
385 tp == BRW_REGISTER_TYPE_UQ;
386 }
387
388 /**
389 * Construct a brw_reg.
390 * \param file one of the BRW_x_REGISTER_FILE values
391 * \param nr register number/index
392 * \param subnr register sub number
393 * \param negate register negate modifier
394 * \param abs register abs modifier
395 * \param type one of BRW_REGISTER_TYPE_x
396 * \param vstride one of BRW_VERTICAL_STRIDE_x
397 * \param width one of BRW_WIDTH_x
398 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
399 * \param swizzle one of BRW_SWIZZLE_x
400 * \param writemask WRITEMASK_X/Y/Z/W bitfield
401 */
402 static inline struct brw_reg
403 brw_reg(enum brw_reg_file file,
404 unsigned nr,
405 unsigned subnr,
406 unsigned negate,
407 unsigned abs,
408 enum brw_reg_type type,
409 unsigned vstride,
410 unsigned width,
411 unsigned hstride,
412 unsigned swizzle,
413 unsigned writemask)
414 {
415 struct brw_reg reg;
416 if (file == BRW_GENERAL_REGISTER_FILE)
417 assert(nr < BRW_MAX_GRF);
418 else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
419 assert(nr <= BRW_ARF_TIMESTAMP);
420 /* Asserting on the MRF register number requires to know the hardware gen
421 * (gen6 has 24 MRF registers), which we don't know here, so we assert
422 * for that in the generators and in brw_eu_emit.c
423 */
424
425 reg.type = type;
426 reg.file = file;
427 reg.negate = negate;
428 reg.abs = abs;
429 reg.address_mode = BRW_ADDRESS_DIRECT;
430 reg.pad0 = 0;
431 reg.subnr = subnr * type_sz(type);
432 reg.nr = nr;
433
434 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
435 * set swizzle and writemask to W, as the lower bits of subnr will
436 * be lost when converted to align16. This is probably too much to
437 * keep track of as you'd want it adjusted by suboffset(), etc.
438 * Perhaps fix up when converting to align16?
439 */
440 reg.swizzle = swizzle;
441 reg.writemask = writemask;
442 reg.indirect_offset = 0;
443 reg.vstride = vstride;
444 reg.width = width;
445 reg.hstride = hstride;
446 reg.pad1 = 0;
447 return reg;
448 }
449
450 /** Construct float[16] register */
451 static inline struct brw_reg
452 brw_vec16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
453 {
454 return brw_reg(file,
455 nr,
456 subnr,
457 0,
458 0,
459 BRW_REGISTER_TYPE_F,
460 BRW_VERTICAL_STRIDE_16,
461 BRW_WIDTH_16,
462 BRW_HORIZONTAL_STRIDE_1,
463 BRW_SWIZZLE_XYZW,
464 WRITEMASK_XYZW);
465 }
466
467 /** Construct float[8] register */
468 static inline struct brw_reg
469 brw_vec8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
470 {
471 return brw_reg(file,
472 nr,
473 subnr,
474 0,
475 0,
476 BRW_REGISTER_TYPE_F,
477 BRW_VERTICAL_STRIDE_8,
478 BRW_WIDTH_8,
479 BRW_HORIZONTAL_STRIDE_1,
480 BRW_SWIZZLE_XYZW,
481 WRITEMASK_XYZW);
482 }
483
484 /** Construct float[4] register */
485 static inline struct brw_reg
486 brw_vec4_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
487 {
488 return brw_reg(file,
489 nr,
490 subnr,
491 0,
492 0,
493 BRW_REGISTER_TYPE_F,
494 BRW_VERTICAL_STRIDE_4,
495 BRW_WIDTH_4,
496 BRW_HORIZONTAL_STRIDE_1,
497 BRW_SWIZZLE_XYZW,
498 WRITEMASK_XYZW);
499 }
500
501 /** Construct float[2] register */
502 static inline struct brw_reg
503 brw_vec2_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
504 {
505 return brw_reg(file,
506 nr,
507 subnr,
508 0,
509 0,
510 BRW_REGISTER_TYPE_F,
511 BRW_VERTICAL_STRIDE_2,
512 BRW_WIDTH_2,
513 BRW_HORIZONTAL_STRIDE_1,
514 BRW_SWIZZLE_XYXY,
515 WRITEMASK_XY);
516 }
517
518 /** Construct float[1] register */
519 static inline struct brw_reg
520 brw_vec1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
521 {
522 return brw_reg(file,
523 nr,
524 subnr,
525 0,
526 0,
527 BRW_REGISTER_TYPE_F,
528 BRW_VERTICAL_STRIDE_0,
529 BRW_WIDTH_1,
530 BRW_HORIZONTAL_STRIDE_0,
531 BRW_SWIZZLE_XXXX,
532 WRITEMASK_X);
533 }
534
535 static inline struct brw_reg
536 brw_vecn_reg(unsigned width, enum brw_reg_file file,
537 unsigned nr, unsigned subnr)
538 {
539 switch (width) {
540 case 1:
541 return brw_vec1_reg(file, nr, subnr);
542 case 2:
543 return brw_vec2_reg(file, nr, subnr);
544 case 4:
545 return brw_vec4_reg(file, nr, subnr);
546 case 8:
547 return brw_vec8_reg(file, nr, subnr);
548 case 16:
549 return brw_vec16_reg(file, nr, subnr);
550 default:
551 unreachable("Invalid register width");
552 }
553 }
554
555 static inline struct brw_reg
556 retype(struct brw_reg reg, enum brw_reg_type type)
557 {
558 reg.type = type;
559 return reg;
560 }
561
562 static inline struct brw_reg
563 firsthalf(struct brw_reg reg)
564 {
565 return reg;
566 }
567
568 static inline struct brw_reg
569 sechalf(struct brw_reg reg)
570 {
571 if (reg.vstride)
572 reg.nr++;
573 return reg;
574 }
575
576 static inline struct brw_reg
577 offset(struct brw_reg reg, unsigned delta)
578 {
579 reg.nr += delta;
580 return reg;
581 }
582
583
584 static inline struct brw_reg
585 byte_offset(struct brw_reg reg, unsigned bytes)
586 {
587 unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
588 reg.nr = newoffset / REG_SIZE;
589 reg.subnr = newoffset % REG_SIZE;
590 return reg;
591 }
592
593 static inline struct brw_reg
594 suboffset(struct brw_reg reg, unsigned delta)
595 {
596 return byte_offset(reg, delta * type_sz(reg.type));
597 }
598
599 /** Construct unsigned word[16] register */
600 static inline struct brw_reg
601 brw_uw16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
602 {
603 return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
604 }
605
606 /** Construct unsigned word[8] register */
607 static inline struct brw_reg
608 brw_uw8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
609 {
610 return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
611 }
612
613 /** Construct unsigned word[1] register */
614 static inline struct brw_reg
615 brw_uw1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
616 {
617 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
618 }
619
620 static inline struct brw_reg
621 brw_ud1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
622 {
623 return retype(brw_vec1_reg(file, nr, subnr), BRW_REGISTER_TYPE_UD);
624 }
625
626 static inline struct brw_reg
627 brw_imm_reg(enum brw_reg_type type)
628 {
629 return brw_reg(BRW_IMMEDIATE_VALUE,
630 0,
631 0,
632 0,
633 0,
634 type,
635 BRW_VERTICAL_STRIDE_0,
636 BRW_WIDTH_1,
637 BRW_HORIZONTAL_STRIDE_0,
638 0,
639 0);
640 }
641
642 /** Construct float immediate register */
643 static inline struct brw_reg
644 brw_imm_df(double df)
645 {
646 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_DF);
647 imm.df = df;
648 return imm;
649 }
650
651 static inline struct brw_reg
652 brw_imm_u64(uint64_t u64)
653 {
654 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UQ);
655 imm.u64 = u64;
656 return imm;
657 }
658
659 static inline struct brw_reg
660 brw_imm_f(float f)
661 {
662 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
663 imm.f = f;
664 return imm;
665 }
666
667 /** Construct int64_t immediate register */
668 static inline struct brw_reg
669 brw_imm_q(int64_t q)
670 {
671 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_Q);
672 imm.d64 = q;
673 return imm;
674 }
675
676 /** Construct int64_t immediate register */
677 static inline struct brw_reg
678 brw_imm_uq(uint64_t uq)
679 {
680 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UQ);
681 imm.u64 = uq;
682 return imm;
683 }
684
685 /** Construct integer immediate register */
686 static inline struct brw_reg
687 brw_imm_d(int d)
688 {
689 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
690 imm.d = d;
691 return imm;
692 }
693
694 /** Construct uint immediate register */
695 static inline struct brw_reg
696 brw_imm_ud(unsigned ud)
697 {
698 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
699 imm.ud = ud;
700 return imm;
701 }
702
703 /** Construct ushort immediate register */
704 static inline struct brw_reg
705 brw_imm_uw(uint16_t uw)
706 {
707 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
708 imm.ud = uw | (uw << 16);
709 return imm;
710 }
711
712 /** Construct short immediate register */
713 static inline struct brw_reg
714 brw_imm_w(int16_t w)
715 {
716 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
717 imm.ud = (uint16_t)w | (uint32_t)(uint16_t)w << 16;
718 return imm;
719 }
720
721 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
722 * numbers alias with _V and _VF below:
723 */
724
725 /** Construct vector of eight signed half-byte values */
726 static inline struct brw_reg
727 brw_imm_v(unsigned v)
728 {
729 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
730 imm.ud = v;
731 return imm;
732 }
733
734 /** Construct vector of eight unsigned half-byte values */
735 static inline struct brw_reg
736 brw_imm_uv(unsigned uv)
737 {
738 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UV);
739 imm.ud = uv;
740 return imm;
741 }
742
743 /** Construct vector of four 8-bit float values */
744 static inline struct brw_reg
745 brw_imm_vf(unsigned v)
746 {
747 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
748 imm.ud = v;
749 return imm;
750 }
751
752 static inline struct brw_reg
753 brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
754 {
755 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
756 imm.vstride = BRW_VERTICAL_STRIDE_0;
757 imm.width = BRW_WIDTH_4;
758 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
759 imm.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24));
760 return imm;
761 }
762
763
764 static inline struct brw_reg
765 brw_address(struct brw_reg reg)
766 {
767 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
768 }
769
770 /** Construct float[1] general-purpose register */
771 static inline struct brw_reg
772 brw_vec1_grf(unsigned nr, unsigned subnr)
773 {
774 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
775 }
776
777 /** Construct float[2] general-purpose register */
778 static inline struct brw_reg
779 brw_vec2_grf(unsigned nr, unsigned subnr)
780 {
781 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
782 }
783
784 /** Construct float[4] general-purpose register */
785 static inline struct brw_reg
786 brw_vec4_grf(unsigned nr, unsigned subnr)
787 {
788 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
789 }
790
791 /** Construct float[8] general-purpose register */
792 static inline struct brw_reg
793 brw_vec8_grf(unsigned nr, unsigned subnr)
794 {
795 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
796 }
797
798 /** Construct float[16] general-purpose register */
799 static inline struct brw_reg
800 brw_vec16_grf(unsigned nr, unsigned subnr)
801 {
802 return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
803 }
804
805 static inline struct brw_reg
806 brw_vecn_grf(unsigned width, unsigned nr, unsigned subnr)
807 {
808 return brw_vecn_reg(width, BRW_GENERAL_REGISTER_FILE, nr, subnr);
809 }
810
811
812 static inline struct brw_reg
813 brw_uw8_grf(unsigned nr, unsigned subnr)
814 {
815 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
816 }
817
818 static inline struct brw_reg
819 brw_uw16_grf(unsigned nr, unsigned subnr)
820 {
821 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
822 }
823
824
825 /** Construct null register (usually used for setting condition codes) */
826 static inline struct brw_reg
827 brw_null_reg(void)
828 {
829 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
830 }
831
832 static inline struct brw_reg
833 brw_null_vec(unsigned width)
834 {
835 return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
836 }
837
838 static inline struct brw_reg
839 brw_address_reg(unsigned subnr)
840 {
841 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
842 }
843
844 static inline struct brw_reg
845 brw_tdr_reg(void)
846 {
847 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_TDR, 0);
848 }
849
850 /* If/else instructions break in align16 mode if writemask & swizzle
851 * aren't xyzw. This goes against the convention for other scalar
852 * regs:
853 */
854 static inline struct brw_reg
855 brw_ip_reg(void)
856 {
857 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
858 BRW_ARF_IP,
859 0,
860 0,
861 0,
862 BRW_REGISTER_TYPE_UD,
863 BRW_VERTICAL_STRIDE_4, /* ? */
864 BRW_WIDTH_1,
865 BRW_HORIZONTAL_STRIDE_0,
866 BRW_SWIZZLE_XYZW, /* NOTE! */
867 WRITEMASK_XYZW); /* NOTE! */
868 }
869
870 static inline struct brw_reg
871 brw_notification_reg(void)
872 {
873 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
874 BRW_ARF_NOTIFICATION_COUNT,
875 0,
876 0,
877 0,
878 BRW_REGISTER_TYPE_UD,
879 BRW_VERTICAL_STRIDE_0,
880 BRW_WIDTH_1,
881 BRW_HORIZONTAL_STRIDE_0,
882 BRW_SWIZZLE_XXXX,
883 WRITEMASK_X);
884 }
885
886 static inline struct brw_reg
887 brw_cr0_reg(unsigned subnr)
888 {
889 return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_CONTROL, subnr);
890 }
891
892 static inline struct brw_reg
893 brw_sr0_reg(unsigned subnr)
894 {
895 return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_STATE, subnr);
896 }
897
898 static inline struct brw_reg
899 brw_acc_reg(unsigned width)
900 {
901 return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE,
902 BRW_ARF_ACCUMULATOR, 0);
903 }
904
905 static inline struct brw_reg
906 brw_flag_reg(int reg, int subreg)
907 {
908 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
909 BRW_ARF_FLAG + reg, subreg);
910 }
911
912 static inline struct brw_reg
913 brw_flag_subreg(unsigned subreg)
914 {
915 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
916 BRW_ARF_FLAG + subreg / 2, subreg % 2);
917 }
918
919 /**
920 * Return the mask register present in Gen4-5, or the related register present
921 * in Gen7.5 and later hardware referred to as "channel enable" register in
922 * the documentation.
923 */
924 static inline struct brw_reg
925 brw_mask_reg(unsigned subnr)
926 {
927 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
928 }
929
930 static inline struct brw_reg
931 brw_vmask_reg()
932 {
933 return brw_sr0_reg(3);
934 }
935
936 static inline struct brw_reg
937 brw_dmask_reg()
938 {
939 return brw_sr0_reg(2);
940 }
941
942 static inline struct brw_reg
943 brw_mask_stack_reg(unsigned subnr)
944 {
945 return suboffset(retype(brw_vec16_reg(BRW_ARCHITECTURE_REGISTER_FILE,
946 BRW_ARF_MASK_STACK, 0),
947 BRW_REGISTER_TYPE_UB), subnr);
948 }
949
950 static inline struct brw_reg
951 brw_mask_stack_depth_reg(unsigned subnr)
952 {
953 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
954 BRW_ARF_MASK_STACK_DEPTH, subnr);
955 }
956
957 static inline struct brw_reg
958 brw_message_reg(unsigned nr)
959 {
960 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
961 }
962
963 static inline struct brw_reg
964 brw_uvec_mrf(unsigned width, unsigned nr, unsigned subnr)
965 {
966 return retype(brw_vecn_reg(width, BRW_MESSAGE_REGISTER_FILE, nr, subnr),
967 BRW_REGISTER_TYPE_UD);
968 }
969
970 /* This is almost always called with a numeric constant argument, so
971 * make things easy to evaluate at compile time:
972 */
973 static inline unsigned cvt(unsigned val)
974 {
975 switch (val) {
976 case 0: return 0;
977 case 1: return 1;
978 case 2: return 2;
979 case 4: return 3;
980 case 8: return 4;
981 case 16: return 5;
982 case 32: return 6;
983 }
984 return 0;
985 }
986
987 static inline struct brw_reg
988 stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
989 {
990 reg.vstride = cvt(vstride);
991 reg.width = cvt(width) - 1;
992 reg.hstride = cvt(hstride);
993 return reg;
994 }
995
996 /**
997 * Multiply the vertical and horizontal stride of a register by the given
998 * factor \a s.
999 */
1000 static inline struct brw_reg
1001 spread(struct brw_reg reg, unsigned s)
1002 {
1003 if (s) {
1004 assert(util_is_power_of_two_nonzero(s));
1005
1006 if (reg.hstride)
1007 reg.hstride += cvt(s) - 1;
1008
1009 if (reg.vstride)
1010 reg.vstride += cvt(s) - 1;
1011
1012 return reg;
1013 } else {
1014 return stride(reg, 0, 1, 0);
1015 }
1016 }
1017
1018 /**
1019 * Reinterpret each channel of register \p reg as a vector of values of the
1020 * given smaller type and take the i-th subcomponent from each.
1021 */
1022 static inline struct brw_reg
1023 subscript(struct brw_reg reg, enum brw_reg_type type, unsigned i)
1024 {
1025 if (reg.file == IMM)
1026 return reg;
1027
1028 unsigned scale = type_sz(reg.type) / type_sz(type);
1029 assert(scale >= 1 && i < scale);
1030
1031 return suboffset(retype(spread(reg, scale), type), i);
1032 }
1033
1034 static inline struct brw_reg
1035 vec16(struct brw_reg reg)
1036 {
1037 return stride(reg, 16,16,1);
1038 }
1039
1040 static inline struct brw_reg
1041 vec8(struct brw_reg reg)
1042 {
1043 return stride(reg, 8,8,1);
1044 }
1045
1046 static inline struct brw_reg
1047 vec4(struct brw_reg reg)
1048 {
1049 return stride(reg, 4,4,1);
1050 }
1051
1052 static inline struct brw_reg
1053 vec2(struct brw_reg reg)
1054 {
1055 return stride(reg, 2,2,1);
1056 }
1057
1058 static inline struct brw_reg
1059 vec1(struct brw_reg reg)
1060 {
1061 return stride(reg, 0,1,0);
1062 }
1063
1064
1065 static inline struct brw_reg
1066 get_element(struct brw_reg reg, unsigned elt)
1067 {
1068 return vec1(suboffset(reg, elt));
1069 }
1070
1071 static inline struct brw_reg
1072 get_element_ud(struct brw_reg reg, unsigned elt)
1073 {
1074 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
1075 }
1076
1077 static inline struct brw_reg
1078 get_element_d(struct brw_reg reg, unsigned elt)
1079 {
1080 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
1081 }
1082
1083 static inline struct brw_reg
1084 brw_swizzle(struct brw_reg reg, unsigned swz)
1085 {
1086 if (reg.file == BRW_IMMEDIATE_VALUE)
1087 reg.ud = brw_swizzle_immediate(reg.type, reg.ud, swz);
1088 else
1089 reg.swizzle = brw_compose_swizzle(swz, reg.swizzle);
1090
1091 return reg;
1092 }
1093
1094 static inline struct brw_reg
1095 brw_writemask(struct brw_reg reg, unsigned mask)
1096 {
1097 assert(reg.file != BRW_IMMEDIATE_VALUE);
1098 reg.writemask &= mask;
1099 return reg;
1100 }
1101
1102 static inline struct brw_reg
1103 brw_set_writemask(struct brw_reg reg, unsigned mask)
1104 {
1105 assert(reg.file != BRW_IMMEDIATE_VALUE);
1106 reg.writemask = mask;
1107 return reg;
1108 }
1109
1110 static inline unsigned
1111 brw_writemask_for_size(unsigned n)
1112 {
1113 return (1 << n) - 1;
1114 }
1115
1116 static inline unsigned
1117 brw_writemask_for_component_packing(unsigned n, unsigned first_component)
1118 {
1119 assert(first_component + n <= 4);
1120 return (((1 << n) - 1) << first_component);
1121 }
1122
1123 static inline struct brw_reg
1124 negate(struct brw_reg reg)
1125 {
1126 reg.negate ^= 1;
1127 return reg;
1128 }
1129
1130 static inline struct brw_reg
1131 brw_abs(struct brw_reg reg)
1132 {
1133 reg.abs = 1;
1134 reg.negate = 0;
1135 return reg;
1136 }
1137
1138 /************************************************************************/
1139
1140 static inline struct brw_reg
1141 brw_vec4_indirect(unsigned subnr, int offset)
1142 {
1143 struct brw_reg reg = brw_vec4_grf(0, 0);
1144 reg.subnr = subnr;
1145 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1146 reg.indirect_offset = offset;
1147 return reg;
1148 }
1149
1150 static inline struct brw_reg
1151 brw_vec1_indirect(unsigned subnr, int offset)
1152 {
1153 struct brw_reg reg = brw_vec1_grf(0, 0);
1154 reg.subnr = subnr;
1155 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1156 reg.indirect_offset = offset;
1157 return reg;
1158 }
1159
1160 static inline struct brw_reg
1161 brw_VxH_indirect(unsigned subnr, int offset)
1162 {
1163 struct brw_reg reg = brw_vec1_grf(0, 0);
1164 reg.vstride = BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL;
1165 reg.subnr = subnr;
1166 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1167 reg.indirect_offset = offset;
1168 return reg;
1169 }
1170
1171 static inline struct brw_reg
1172 deref_4f(struct brw_indirect ptr, int offset)
1173 {
1174 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
1175 }
1176
1177 static inline struct brw_reg
1178 deref_1f(struct brw_indirect ptr, int offset)
1179 {
1180 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
1181 }
1182
1183 static inline struct brw_reg
1184 deref_4b(struct brw_indirect ptr, int offset)
1185 {
1186 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
1187 }
1188
1189 static inline struct brw_reg
1190 deref_1uw(struct brw_indirect ptr, int offset)
1191 {
1192 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
1193 }
1194
1195 static inline struct brw_reg
1196 deref_1d(struct brw_indirect ptr, int offset)
1197 {
1198 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
1199 }
1200
1201 static inline struct brw_reg
1202 deref_1ud(struct brw_indirect ptr, int offset)
1203 {
1204 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
1205 }
1206
1207 static inline struct brw_reg
1208 get_addr_reg(struct brw_indirect ptr)
1209 {
1210 return brw_address_reg(ptr.addr_subnr);
1211 }
1212
1213 static inline struct brw_indirect
1214 brw_indirect_offset(struct brw_indirect ptr, int offset)
1215 {
1216 ptr.addr_offset += offset;
1217 return ptr;
1218 }
1219
1220 static inline struct brw_indirect
1221 brw_indirect(unsigned addr_subnr, int offset)
1222 {
1223 struct brw_indirect ptr;
1224 ptr.addr_subnr = addr_subnr;
1225 ptr.addr_offset = offset;
1226 ptr.pad = 0;
1227 return ptr;
1228 }
1229
1230 static inline bool
1231 region_matches(struct brw_reg reg, enum brw_vertical_stride v,
1232 enum brw_width w, enum brw_horizontal_stride h)
1233 {
1234 return reg.vstride == v &&
1235 reg.width == w &&
1236 reg.hstride == h;
1237 }
1238
1239 #define has_scalar_region(reg) \
1240 region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
1241 BRW_HORIZONTAL_STRIDE_0)
1242
1243 /* brw_packed_float.c */
1244 int brw_float_to_vf(float f);
1245 float brw_vf_to_float(unsigned char vf);
1246
1247 #ifdef __cplusplus
1248 }
1249 #endif
1250
1251 #endif