~ubuntu-branches/ubuntu/trusty/mesa-lts-utopic/trusty-proposed

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/i965/brw_reg.h

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2015-01-06 10:38:32 UTC
  • Revision ID: package-import@ubuntu.com-20150106103832-u6rqp9wfmojb1gnu
Tags: upstream-10.3.2
ImportĀ upstreamĀ versionĀ 10.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
sechalf(struct brw_reg reg)
 
375
{
 
376
   if (reg.vstride)
 
377
      reg.nr++;
 
378
   return reg;
 
379
}
 
380
 
 
381
static inline struct brw_reg
 
382
suboffset(struct brw_reg reg, unsigned delta)
 
383
{
 
384
   reg.subnr += delta * type_sz(reg.type);
 
385
   return reg;
 
386
}
 
387
 
 
388
 
 
389
static inline struct brw_reg
 
390
offset(struct brw_reg reg, unsigned delta)
 
391
{
 
392
   reg.nr += delta;
 
393
   return reg;
 
394
}
 
395
 
 
396
 
 
397
static inline struct brw_reg
 
398
byte_offset(struct brw_reg reg, unsigned bytes)
 
399
{
 
400
   unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
 
401
   reg.nr = newoffset / REG_SIZE;
 
402
   reg.subnr = newoffset % REG_SIZE;
 
403
   return reg;
 
404
}
 
405
 
 
406
 
 
407
/** Construct unsigned word[16] register */
 
408
static inline struct brw_reg
 
409
brw_uw16_reg(unsigned file, unsigned nr, unsigned subnr)
 
410
{
 
411
   return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
 
412
}
 
413
 
 
414
/** Construct unsigned word[8] register */
 
415
static inline struct brw_reg
 
416
brw_uw8_reg(unsigned file, unsigned nr, unsigned subnr)
 
417
{
 
418
   return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
 
419
}
 
420
 
 
421
/** Construct unsigned word[1] register */
 
422
static inline struct brw_reg
 
423
brw_uw1_reg(unsigned file, unsigned nr, unsigned subnr)
 
424
{
 
425
   return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
 
426
}
 
427
 
 
428
static inline struct brw_reg
 
429
brw_imm_reg(enum brw_reg_type type)
 
430
{
 
431
   return brw_reg(BRW_IMMEDIATE_VALUE,
 
432
                  0,
 
433
                  0,
 
434
                  type,
 
435
                  BRW_VERTICAL_STRIDE_0,
 
436
                  BRW_WIDTH_1,
 
437
                  BRW_HORIZONTAL_STRIDE_0,
 
438
                  0,
 
439
                  0);
 
440
}
 
441
 
 
442
/** Construct float immediate register */
 
443
static inline struct brw_reg
 
444
brw_imm_f(float f)
 
445
{
 
446
   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
 
447
   imm.dw1.f = f;
 
448
   return imm;
 
449
}
 
450
 
 
451
/** Construct integer immediate register */
 
452
static inline struct brw_reg
 
453
brw_imm_d(int d)
 
454
{
 
455
   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
 
456
   imm.dw1.d = d;
 
457
   return imm;
 
458
}
 
459
 
 
460
/** Construct uint immediate register */
 
461
static inline struct brw_reg
 
462
brw_imm_ud(unsigned ud)
 
463
{
 
464
   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
 
465
   imm.dw1.ud = ud;
 
466
   return imm;
 
467
}
 
468
 
 
469
/** Construct ushort immediate register */
 
470
static inline struct brw_reg
 
471
brw_imm_uw(uint16_t uw)
 
472
{
 
473
   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
 
474
   imm.dw1.ud = uw | (uw << 16);
 
475
   return imm;
 
476
}
 
477
 
 
478
/** Construct short immediate register */
 
479
static inline struct brw_reg
 
480
brw_imm_w(int16_t w)
 
481
{
 
482
   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
 
483
   imm.dw1.d = w | (w << 16);
 
484
   return imm;
 
485
}
 
486
 
 
487
/* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
 
488
 * numbers alias with _V and _VF below:
 
489
 */
 
490
 
 
491
/** Construct vector of eight signed half-byte values */
 
492
static inline struct brw_reg
 
493
brw_imm_v(unsigned v)
 
494
{
 
495
   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
 
496
   imm.vstride = BRW_VERTICAL_STRIDE_0;
 
497
   imm.width = BRW_WIDTH_8;
 
498
   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
 
499
   imm.dw1.ud = v;
 
500
   return imm;
 
501
}
 
502
 
 
503
/** Construct vector of four 8-bit float values */
 
504
static inline struct brw_reg
 
505
brw_imm_vf(unsigned v)
 
506
{
 
507
   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
 
508
   imm.vstride = BRW_VERTICAL_STRIDE_0;
 
509
   imm.width = BRW_WIDTH_4;
 
510
   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
 
511
   imm.dw1.ud = v;
 
512
   return imm;
 
513
}
 
514
 
 
515
/**
 
516
 * Convert an integer into a "restricted" 8-bit float, used in vector
 
517
 * immediates.  The 8-bit floating point format has a sign bit, an
 
518
 * excess-3 3-bit exponent, and a 4-bit mantissa.  All integer values
 
519
 * from -31 to 31 can be represented exactly.
 
520
 */
 
521
static inline uint8_t
 
522
int_to_float8(int x)
 
523
{
 
524
   if (x == 0) {
 
525
      return 0;
 
526
   } else if (x < 0) {
 
527
      return 1 << 7 | int_to_float8(-x);
 
528
   } else {
 
529
      const unsigned exponent = _mesa_logbase2(x);
 
530
      const unsigned mantissa = (x - (1 << exponent)) << (4 - exponent);
 
531
      assert(exponent <= 4);
 
532
      return (exponent + 3) << 4 | mantissa;
 
533
   }
 
534
}
 
535
 
 
536
/**
 
537
 * Construct a floating-point packed vector immediate from its integer
 
538
 * values. \sa int_to_float8()
 
539
 */
 
540
static inline struct brw_reg
 
541
brw_imm_vf4(int v0, int v1, int v2, int v3)
 
542
{
 
543
   return brw_imm_vf((int_to_float8(v0) << 0) |
 
544
                     (int_to_float8(v1) << 8) |
 
545
                     (int_to_float8(v2) << 16) |
 
546
                     (int_to_float8(v3) << 24));
 
547
}
 
548
 
 
549
 
 
550
static inline struct brw_reg
 
551
brw_address(struct brw_reg reg)
 
552
{
 
553
   return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
 
554
}
 
555
 
 
556
/** Construct float[1] general-purpose register */
 
557
static inline struct brw_reg
 
558
brw_vec1_grf(unsigned nr, unsigned subnr)
 
559
{
 
560
   return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
 
561
}
 
562
 
 
563
/** Construct float[2] general-purpose register */
 
564
static inline struct brw_reg
 
565
brw_vec2_grf(unsigned nr, unsigned subnr)
 
566
{
 
567
   return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
 
568
}
 
569
 
 
570
/** Construct float[4] general-purpose register */
 
571
static inline struct brw_reg
 
572
brw_vec4_grf(unsigned nr, unsigned subnr)
 
573
{
 
574
   return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
 
575
}
 
576
 
 
577
/** Construct float[8] general-purpose register */
 
578
static inline struct brw_reg
 
579
brw_vec8_grf(unsigned nr, unsigned subnr)
 
580
{
 
581
   return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
 
582
}
 
583
 
 
584
 
 
585
static inline struct brw_reg
 
586
brw_uw8_grf(unsigned nr, unsigned subnr)
 
587
{
 
588
   return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
 
589
}
 
590
 
 
591
static inline struct brw_reg
 
592
brw_uw16_grf(unsigned nr, unsigned subnr)
 
593
{
 
594
   return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
 
595
}
 
596
 
 
597
 
 
598
/** Construct null register (usually used for setting condition codes) */
 
599
static inline struct brw_reg
 
600
brw_null_reg(void)
 
601
{
 
602
   return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
 
603
}
 
604
 
 
605
static inline struct brw_reg
 
606
brw_address_reg(unsigned subnr)
 
607
{
 
608
   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
 
609
}
 
610
 
 
611
/* If/else instructions break in align16 mode if writemask & swizzle
 
612
 * aren't xyzw.  This goes against the convention for other scalar
 
613
 * regs:
 
614
 */
 
615
static inline struct brw_reg
 
616
brw_ip_reg(void)
 
617
{
 
618
   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
 
619
                  BRW_ARF_IP,
 
620
                  0,
 
621
                  BRW_REGISTER_TYPE_UD,
 
622
                  BRW_VERTICAL_STRIDE_4, /* ? */
 
623
                  BRW_WIDTH_1,
 
624
                  BRW_HORIZONTAL_STRIDE_0,
 
625
                  BRW_SWIZZLE_XYZW, /* NOTE! */
 
626
                  WRITEMASK_XYZW); /* NOTE! */
 
627
}
 
628
 
 
629
static inline struct brw_reg
 
630
brw_acc_reg(void)
 
631
{
 
632
   return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ACCUMULATOR, 0);
 
633
}
 
634
 
 
635
static inline struct brw_reg
 
636
brw_flag_reg(int reg, int subreg)
 
637
{
 
638
   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
 
639
                      BRW_ARF_FLAG + reg, subreg);
 
640
}
 
641
 
 
642
 
 
643
static inline struct brw_reg
 
644
brw_mask_reg(unsigned subnr)
 
645
{
 
646
   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
 
647
}
 
648
 
 
649
static inline struct brw_reg
 
650
brw_message_reg(unsigned nr)
 
651
{
 
652
   assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
 
653
   return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
 
654
}
 
655
 
 
656
static inline struct brw_reg
 
657
brw_uvec_mrf(unsigned width, unsigned nr, unsigned subnr)
 
658
{
 
659
   return retype(brw_vecn_reg(width, BRW_MESSAGE_REGISTER_FILE, nr, subnr),
 
660
                 BRW_REGISTER_TYPE_UD);
 
661
}
 
662
 
 
663
/* This is almost always called with a numeric constant argument, so
 
664
 * make things easy to evaluate at compile time:
 
665
 */
 
666
static inline unsigned cvt(unsigned val)
 
667
{
 
668
   switch (val) {
 
669
   case 0: return 0;
 
670
   case 1: return 1;
 
671
   case 2: return 2;
 
672
   case 4: return 3;
 
673
   case 8: return 4;
 
674
   case 16: return 5;
 
675
   case 32: return 6;
 
676
   }
 
677
   return 0;
 
678
}
 
679
 
 
680
static inline struct brw_reg
 
681
stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
 
682
{
 
683
   reg.vstride = cvt(vstride);
 
684
   reg.width = cvt(width) - 1;
 
685
   reg.hstride = cvt(hstride);
 
686
   return reg;
 
687
}
 
688
 
 
689
 
 
690
static inline struct brw_reg
 
691
vec16(struct brw_reg reg)
 
692
{
 
693
   return stride(reg, 16,16,1);
 
694
}
 
695
 
 
696
static inline struct brw_reg
 
697
vec8(struct brw_reg reg)
 
698
{
 
699
   return stride(reg, 8,8,1);
 
700
}
 
701
 
 
702
static inline struct brw_reg
 
703
vec4(struct brw_reg reg)
 
704
{
 
705
   return stride(reg, 4,4,1);
 
706
}
 
707
 
 
708
static inline struct brw_reg
 
709
vec2(struct brw_reg reg)
 
710
{
 
711
   return stride(reg, 2,2,1);
 
712
}
 
713
 
 
714
static inline struct brw_reg
 
715
vec1(struct brw_reg reg)
 
716
{
 
717
   return stride(reg, 0,1,0);
 
718
}
 
719
 
 
720
 
 
721
static inline struct brw_reg
 
722
get_element(struct brw_reg reg, unsigned elt)
 
723
{
 
724
   return vec1(suboffset(reg, elt));
 
725
}
 
726
 
 
727
static inline struct brw_reg
 
728
get_element_ud(struct brw_reg reg, unsigned elt)
 
729
{
 
730
   return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
 
731
}
 
732
 
 
733
static inline struct brw_reg
 
734
get_element_d(struct brw_reg reg, unsigned elt)
 
735
{
 
736
   return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
 
737
}
 
738
 
 
739
 
 
740
static inline struct brw_reg
 
741
brw_swizzle(struct brw_reg reg, unsigned x, unsigned y, unsigned z, unsigned w)
 
742
{
 
743
   assert(reg.file != BRW_IMMEDIATE_VALUE);
 
744
 
 
745
   reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
 
746
                                       BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
 
747
                                       BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
 
748
                                       BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
 
749
   return reg;
 
750
}
 
751
 
 
752
 
 
753
static inline struct brw_reg
 
754
brw_swizzle1(struct brw_reg reg, unsigned x)
 
755
{
 
756
   return brw_swizzle(reg, x, x, x, x);
 
757
}
 
758
 
 
759
static inline struct brw_reg
 
760
brw_writemask(struct brw_reg reg, unsigned mask)
 
761
{
 
762
   assert(reg.file != BRW_IMMEDIATE_VALUE);
 
763
   reg.dw1.bits.writemask &= mask;
 
764
   return reg;
 
765
}
 
766
 
 
767
static inline struct brw_reg
 
768
brw_set_writemask(struct brw_reg reg, unsigned mask)
 
769
{
 
770
   assert(reg.file != BRW_IMMEDIATE_VALUE);
 
771
   reg.dw1.bits.writemask = mask;
 
772
   return reg;
 
773
}
 
774
 
 
775
static inline struct brw_reg
 
776
negate(struct brw_reg reg)
 
777
{
 
778
   reg.negate ^= 1;
 
779
   return reg;
 
780
}
 
781
 
 
782
static inline struct brw_reg
 
783
brw_abs(struct brw_reg reg)
 
784
{
 
785
   reg.abs = 1;
 
786
   reg.negate = 0;
 
787
   return reg;
 
788
}
 
789
 
 
790
/************************************************************************/
 
791
 
 
792
static inline struct brw_reg
 
793
brw_vec4_indirect(unsigned subnr, int offset)
 
794
{
 
795
   struct brw_reg reg =  brw_vec4_grf(0, 0);
 
796
   reg.subnr = subnr;
 
797
   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
 
798
   reg.dw1.bits.indirect_offset = offset;
 
799
   return reg;
 
800
}
 
801
 
 
802
static inline struct brw_reg
 
803
brw_vec1_indirect(unsigned subnr, int offset)
 
804
{
 
805
   struct brw_reg reg =  brw_vec1_grf(0, 0);
 
806
   reg.subnr = subnr;
 
807
   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
 
808
   reg.dw1.bits.indirect_offset = offset;
 
809
   return reg;
 
810
}
 
811
 
 
812
static inline struct brw_reg
 
813
deref_4f(struct brw_indirect ptr, int offset)
 
814
{
 
815
   return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
 
816
}
 
817
 
 
818
static inline struct brw_reg
 
819
deref_1f(struct brw_indirect ptr, int offset)
 
820
{
 
821
   return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
 
822
}
 
823
 
 
824
static inline struct brw_reg
 
825
deref_4b(struct brw_indirect ptr, int offset)
 
826
{
 
827
   return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
 
828
}
 
829
 
 
830
static inline struct brw_reg
 
831
deref_1uw(struct brw_indirect ptr, int offset)
 
832
{
 
833
   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
 
834
}
 
835
 
 
836
static inline struct brw_reg
 
837
deref_1d(struct brw_indirect ptr, int offset)
 
838
{
 
839
   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
 
840
}
 
841
 
 
842
static inline struct brw_reg
 
843
deref_1ud(struct brw_indirect ptr, int offset)
 
844
{
 
845
   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
 
846
}
 
847
 
 
848
static inline struct brw_reg
 
849
get_addr_reg(struct brw_indirect ptr)
 
850
{
 
851
   return brw_address_reg(ptr.addr_subnr);
 
852
}
 
853
 
 
854
static inline struct brw_indirect
 
855
brw_indirect_offset(struct brw_indirect ptr, int offset)
 
856
{
 
857
   ptr.addr_offset += offset;
 
858
   return ptr;
 
859
}
 
860
 
 
861
static inline struct brw_indirect
 
862
brw_indirect(unsigned addr_subnr, int offset)
 
863
{
 
864
   struct brw_indirect ptr;
 
865
   ptr.addr_subnr = addr_subnr;
 
866
   ptr.addr_offset = offset;
 
867
   ptr.pad = 0;
 
868
   return ptr;
 
869
}
 
870
 
 
871
#ifdef __cplusplus
 
872
}
 
873
#endif
 
874
 
 
875
#endif