Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
/*
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 2012-2013 LunarG, Inc.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included
14
 * in all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 * DEALINGS IN THE SOFTWARE.
23
 *
24
 * Authors:
25
 *    Chia-I Wu 
26
 */
27
 
28
#ifndef TOY_REG_H
29
#define TOY_REG_H
30
 
31
#include "pipe/p_compiler.h"
32
#include "util/u_debug.h" /* for assert() */
33
#include "util/u_math.h" /* for union fi */
34
 
35
/* a toy reg is 256-bit wide */
36
#define TOY_REG_WIDTH        32
37
 
38
/**
39
 * Register files.
40
 */
41
enum toy_file {
42
   /* virtual register file */
43
   TOY_FILE_VRF,
44
 
45
   TOY_FILE_ARF,
46
   TOY_FILE_GRF,
47
   TOY_FILE_MRF,
48
   TOY_FILE_IMM,
49
 
50
   TOY_FILE_COUNT,
51
};
52
 
53
/**
54
 * Register types.
55
 */
56
enum toy_type {
57
   TOY_TYPE_F,
58
   TOY_TYPE_D,
59
   TOY_TYPE_UD,
60
   TOY_TYPE_W,
61
   TOY_TYPE_UW,
62
   TOY_TYPE_V, /* only valid for immediates */
63
 
64
   TOY_TYPE_COUNT,
65
};
66
 
67
/**
68
 * Register rectangles.  The three numbers stand for vertical stride, width,
69
 * and horizontal stride respectively.
70
 */
71
enum toy_rect {
72
   TOY_RECT_LINEAR,
73
   TOY_RECT_041,
74
   TOY_RECT_010,
75
   TOY_RECT_220,
76
   TOY_RECT_440,
77
   TOY_RECT_240,
78
 
79
   TOY_RECT_COUNT,
80
};
81
 
82
/**
83
 * Source swizzles.  They are compatible with TGSI_SWIZZLE_x and hardware
84
 * values.
85
 */
86
enum toy_swizzle {
87
   TOY_SWIZZLE_X = 0,
88
   TOY_SWIZZLE_Y = 1,
89
   TOY_SWIZZLE_Z = 2,
90
   TOY_SWIZZLE_W = 3,
91
};
92
 
93
/**
94
 * Destination writemasks.  They are compatible with TGSI_WRITEMASK_x and
95
 * hardware values.
96
 */
97
enum toy_writemask {
98
   TOY_WRITEMASK_X    = (1 << TOY_SWIZZLE_X),
99
   TOY_WRITEMASK_Y    = (1 << TOY_SWIZZLE_Y),
100
   TOY_WRITEMASK_Z    = (1 << TOY_SWIZZLE_Z),
101
   TOY_WRITEMASK_W    = (1 << TOY_SWIZZLE_W),
102
   TOY_WRITEMASK_XY   = (TOY_WRITEMASK_X | TOY_WRITEMASK_Y),
103
   TOY_WRITEMASK_XZ   = (TOY_WRITEMASK_X | TOY_WRITEMASK_Z),
104
   TOY_WRITEMASK_XW   = (TOY_WRITEMASK_X | TOY_WRITEMASK_W),
105
   TOY_WRITEMASK_YZ   = (TOY_WRITEMASK_Y | TOY_WRITEMASK_Z),
106
   TOY_WRITEMASK_YW   = (TOY_WRITEMASK_Y | TOY_WRITEMASK_W),
107
   TOY_WRITEMASK_ZW   = (TOY_WRITEMASK_Z | TOY_WRITEMASK_W),
108
   TOY_WRITEMASK_XYZ  = (TOY_WRITEMASK_X | TOY_WRITEMASK_Y | TOY_WRITEMASK_Z),
109
   TOY_WRITEMASK_XYW  = (TOY_WRITEMASK_X | TOY_WRITEMASK_Y | TOY_WRITEMASK_W),
110
   TOY_WRITEMASK_XZW  = (TOY_WRITEMASK_X | TOY_WRITEMASK_Z | TOY_WRITEMASK_W),
111
   TOY_WRITEMASK_YZW  = (TOY_WRITEMASK_Y | TOY_WRITEMASK_Z | TOY_WRITEMASK_W),
112
   TOY_WRITEMASK_XYZW = (TOY_WRITEMASK_X | TOY_WRITEMASK_Y |
113
                         TOY_WRITEMASK_Z | TOY_WRITEMASK_W),
114
};
115
 
116
/**
117
 * Destination operand.
118
 */
119
struct toy_dst {
120
   unsigned file:3;              /* TOY_FILE_x */
121
   unsigned type:4;              /* TOY_TYPE_x */
122
   unsigned rect:3;              /* TOY_RECT_x */
123
   unsigned indirect:1;          /* true or false */
124
   unsigned indirect_subreg:6;   /* which subreg of a0? */
125
 
126
   unsigned writemask:4;         /* TOY_WRITEMASK_x */
127
   unsigned pad:11;
128
 
129
   uint32_t val32;
130
};
131
 
132
/**
133
 * Source operand.
134
 */
135
struct toy_src {
136
   unsigned file:3;              /* TOY_FILE_x */
137
   unsigned type:4;              /* TOY_TYPE_x */
138
   unsigned rect:3;              /* TOY_RECT_x */
139
   unsigned indirect:1;          /* true or false */
140
   unsigned indirect_subreg:6;   /* which subreg of a0? */
141
 
142
   unsigned swizzle_x:2;         /* TOY_SWIZZLE_x */
143
   unsigned swizzle_y:2;         /* TOY_SWIZZLE_x */
144
   unsigned swizzle_z:2;         /* TOY_SWIZZLE_x */
145
   unsigned swizzle_w:2;         /* TOY_SWIZZLE_x */
146
   unsigned absolute:1;          /* true or false */
147
   unsigned negate:1;            /* true or false */
148
   unsigned pad:5;
149
 
150
   uint32_t val32;
151
};
152
 
153
/**
154
 * Return true if the file is virtual.
155
 */
156
static inline bool
157
toy_file_is_virtual(enum toy_file file)
158
{
159
   return (file == TOY_FILE_VRF);
160
}
161
 
162
/**
163
 * Return true if the file is a hardware one.
164
 */
165
static inline bool
166
toy_file_is_hw(enum toy_file file)
167
{
168
   return !toy_file_is_virtual(file);
169
}
170
 
171
/**
172
 * Return the size of the file.
173
 */
174
static inline uint32_t
175
toy_file_size(enum toy_file file)
176
{
177
   switch (file) {
178
   case TOY_FILE_GRF:
179
      return 256 * TOY_REG_WIDTH;
180
   case TOY_FILE_MRF:
181
      /* there is no MRF on GEN7+ */
182
      return 256 * TOY_REG_WIDTH;
183
   default:
184
      assert(!"invalid toy file");
185
      return 0;
186
   }
187
}
188
 
189
/**
190
 * Return the size of the type.
191
 */
192
static inline int
193
toy_type_size(enum toy_type type)
194
{
195
   switch (type) {
196
   case TOY_TYPE_F:
197
   case TOY_TYPE_D:
198
   case TOY_TYPE_UD:
199
      return 4;
200
   case TOY_TYPE_W:
201
   case TOY_TYPE_UW:
202
      return 2;
203
   case TOY_TYPE_V:
204
   default:
205
      assert(!"invalid toy type");
206
      return 0;
207
   }
208
}
209
 
210
/**
211
 * Return true if the destination operand is null.
212
 */
213
static inline bool
214
tdst_is_null(struct toy_dst dst)
215
{
216
   /* GEN6_ARF_NULL happens to be 0 */
217
   return (dst.file == TOY_FILE_ARF && dst.val32 == 0);
218
}
219
 
220
/**
221
 * Validate the destination operand.
222
 */
223
static inline struct toy_dst
224
tdst_validate(struct toy_dst dst)
225
{
226
   switch (dst.file) {
227
   case TOY_FILE_VRF:
228
   case TOY_FILE_ARF:
229
   case TOY_FILE_MRF:
230
      assert(!dst.indirect);
231
      if (dst.file == TOY_FILE_MRF)
232
         assert(dst.val32 < toy_file_size(dst.file));
233
      break;
234
   case TOY_FILE_GRF:
235
      if (!dst.indirect)
236
         assert(dst.val32 < toy_file_size(dst.file));
237
      break;
238
   case TOY_FILE_IMM:
239
      /* yes, dst can be IMM of type W (for IF/ELSE/ENDIF/WHILE) */
240
      assert(!dst.indirect);
241
      assert(dst.type == TOY_TYPE_W);
242
      break;
243
   default:
244
      assert(!"invalid dst file");
245
      break;
246
   }
247
 
248
   switch (dst.type) {
249
   case TOY_TYPE_V:
250
      assert(!"invalid dst type");
251
      break;
252
   default:
253
      break;
254
   }
255
 
256
   assert(dst.rect == TOY_RECT_LINEAR);
257
   if (dst.file != TOY_FILE_IMM)
258
      assert(dst.val32 % toy_type_size(dst.type) == 0);
259
 
260
   assert(dst.writemask <= TOY_WRITEMASK_XYZW);
261
 
262
   return dst;
263
}
264
 
265
/**
266
 * Change the type of the destination operand.
267
 */
268
static inline struct toy_dst
269
tdst_type(struct toy_dst dst, enum toy_type type)
270
{
271
   dst.type = type;
272
   return tdst_validate(dst);
273
}
274
 
275
/**
276
 * Change the type of the destination operand to TOY_TYPE_D.
277
 */
278
static inline struct toy_dst
279
tdst_d(struct toy_dst dst)
280
{
281
   return tdst_type(dst, TOY_TYPE_D);
282
}
283
 
284
/**
285
 * Change the type of the destination operand to TOY_TYPE_UD.
286
 */
287
static inline struct toy_dst
288
tdst_ud(struct toy_dst dst)
289
{
290
   return tdst_type(dst, TOY_TYPE_UD);
291
}
292
 
293
/**
294
 * Change the type of the destination operand to TOY_TYPE_W.
295
 */
296
static inline struct toy_dst
297
tdst_w(struct toy_dst dst)
298
{
299
   return tdst_type(dst, TOY_TYPE_W);
300
}
301
 
302
/**
303
 * Change the type of the destination operand to TOY_TYPE_UW.
304
 */
305
static inline struct toy_dst
306
tdst_uw(struct toy_dst dst)
307
{
308
   return tdst_type(dst, TOY_TYPE_UW);
309
}
310
 
311
/**
312
 * Change the rectangle of the destination operand.
313
 */
314
static inline struct toy_dst
315
tdst_rect(struct toy_dst dst, enum toy_rect rect)
316
{
317
   dst.rect = rect;
318
   return tdst_validate(dst);
319
}
320
 
321
/**
322
 * Apply writemask to the destination operand.  Note that the current
323
 * writemask is honored.
324
 */
325
static inline struct toy_dst
326
tdst_writemask(struct toy_dst dst, enum toy_writemask writemask)
327
{
328
   dst.writemask &= writemask;
329
   return tdst_validate(dst);
330
}
331
 
332
/**
333
 * Offset the destination operand.
334
 */
335
static inline struct toy_dst
336
tdst_offset(struct toy_dst dst, int reg, int subreg)
337
{
338
   dst.val32 += reg * TOY_REG_WIDTH + subreg * toy_type_size(dst.type);
339
   return tdst_validate(dst);
340
}
341
 
342
/**
343
 * Construct a destination operand.
344
 */
345
static inline struct toy_dst
346
tdst_full(enum toy_file file, enum toy_type type, enum toy_rect rect,
347
          bool indirect, unsigned indirect_subreg,
348
          enum toy_writemask writemask, uint32_t val32)
349
{
350
   struct toy_dst dst;
351
 
352
   dst.file = file;
353
   dst.type = type;
354
   dst.rect = rect;
355
   dst.indirect = indirect;
356
   dst.indirect_subreg = indirect_subreg;
357
   dst.writemask = writemask;
358
   dst.pad = 0;
359
 
360
   dst.val32 = val32;
361
 
362
   return tdst_validate(dst);
363
}
364
 
365
/**
366
 * Construct a null destination operand.
367
 */
368
static inline struct toy_dst
369
tdst_null(void)
370
{
371
   static const struct toy_dst null_dst = {
372
      .file = TOY_FILE_ARF,
373
      .type = TOY_TYPE_F,
374
      .rect = TOY_RECT_LINEAR,
375
      .indirect = false,
376
      .indirect_subreg = 0,
377
      .writemask = TOY_WRITEMASK_XYZW,
378
      .pad = 0,
379
      .val32 = 0,
380
   };
381
 
382
   return null_dst;
383
}
384
 
385
/**
386
 * Construct a destination operand from a source operand.
387
 */
388
static inline struct toy_dst
389
tdst_from(struct toy_src src)
390
{
391
   const enum toy_writemask writemask =
392
      (1 << src.swizzle_x) |
393
      (1 << src.swizzle_y) |
394
      (1 << src.swizzle_z) |
395
      (1 << src.swizzle_w);
396
 
397
   return tdst_full(src.file, src.type, src.rect,
398
         src.indirect, src.indirect_subreg, writemask, src.val32);
399
}
400
 
401
/**
402
 * Construct a destination operand, assuming the type is TOY_TYPE_F, the
403
 * rectangle is TOY_RECT_LINEAR, and the writemask is TOY_WRITEMASK_XYZW.
404
 */
405
static inline struct toy_dst
406
tdst(enum toy_file file, unsigned reg, unsigned subreg_in_bytes)
407
{
408
   const enum toy_type type = TOY_TYPE_F;
409
   const enum toy_rect rect = TOY_RECT_LINEAR;
410
   const uint32_t val32 = reg * TOY_REG_WIDTH + subreg_in_bytes;
411
 
412
   return tdst_full(file, type, rect,
413
         false, 0, TOY_WRITEMASK_XYZW, val32);
414
}
415
 
416
/**
417
 * Construct an immediate destination operand of type TOY_TYPE_W.
418
 */
419
static inline struct toy_dst
420
tdst_imm_w(int16_t w)
421
{
422
   const union fi fi = { .i = w };
423
 
424
   return tdst_full(TOY_FILE_IMM, TOY_TYPE_W, TOY_RECT_LINEAR,
425
         false, 0, TOY_WRITEMASK_XYZW, fi.ui);
426
}
427
 
428
/**
429
 * Return true if the source operand is null.
430
 */
431
static inline bool
432
tsrc_is_null(struct toy_src src)
433
{
434
   /* GEN6_ARF_NULL happens to be 0 */
435
   return (src.file == TOY_FILE_ARF && src.val32 == 0);
436
}
437
 
438
/**
439
 * Return true if the source operand is swizzled.
440
 */
441
static inline bool
442
tsrc_is_swizzled(struct toy_src src)
443
{
444
   return (src.swizzle_x != TOY_SWIZZLE_X ||
445
           src.swizzle_y != TOY_SWIZZLE_Y ||
446
           src.swizzle_z != TOY_SWIZZLE_Z ||
447
           src.swizzle_w != TOY_SWIZZLE_W);
448
}
449
 
450
/**
451
 * Return true if the source operand is swizzled to the same channel.
452
 */
453
static inline bool
454
tsrc_is_swizzle1(struct toy_src src)
455
{
456
   return (src.swizzle_x == src.swizzle_y &&
457
           src.swizzle_x == src.swizzle_z &&
458
           src.swizzle_x == src.swizzle_w);
459
}
460
 
461
/**
462
 * Validate the source operand.
463
 */
464
static inline struct toy_src
465
tsrc_validate(struct toy_src src)
466
{
467
   switch (src.file) {
468
   case TOY_FILE_VRF:
469
   case TOY_FILE_ARF:
470
   case TOY_FILE_MRF:
471
      assert(!src.indirect);
472
      if (src.file == TOY_FILE_MRF)
473
         assert(src.val32 < toy_file_size(src.file));
474
      break;
475
   case TOY_FILE_GRF:
476
      if (!src.indirect)
477
         assert(src.val32 < toy_file_size(src.file));
478
      break;
479
   case TOY_FILE_IMM:
480
      assert(!src.indirect);
481
      break;
482
   default:
483
      assert(!"invalid src file");
484
      break;
485
   }
486
 
487
   switch (src.type) {
488
   case TOY_TYPE_V:
489
      assert(src.file == TOY_FILE_IMM);
490
      break;
491
   default:
492
      break;
493
   }
494
 
495
   if (src.file != TOY_FILE_IMM)
496
      assert(src.val32 % toy_type_size(src.type) == 0);
497
 
498
   assert(src.swizzle_x < 4 && src.swizzle_y < 4 &&
499
          src.swizzle_z < 4 && src.swizzle_w < 4);
500
 
501
   return src;
502
}
503
 
504
/**
505
 * Change the type of the source operand.
506
 */
507
static inline struct toy_src
508
tsrc_type(struct toy_src src, enum toy_type type)
509
{
510
   src.type = type;
511
   return tsrc_validate(src);
512
}
513
 
514
/**
515
 * Change the type of the source operand to TOY_TYPE_D.
516
 */
517
static inline struct toy_src
518
tsrc_d(struct toy_src src)
519
{
520
   return tsrc_type(src, TOY_TYPE_D);
521
}
522
 
523
/**
524
 * Change the type of the source operand to TOY_TYPE_UD.
525
 */
526
static inline struct toy_src
527
tsrc_ud(struct toy_src src)
528
{
529
   return tsrc_type(src, TOY_TYPE_UD);
530
}
531
 
532
/**
533
 * Change the type of the source operand to TOY_TYPE_W.
534
 */
535
static inline struct toy_src
536
tsrc_w(struct toy_src src)
537
{
538
   return tsrc_type(src, TOY_TYPE_W);
539
}
540
 
541
/**
542
 * Change the type of the source operand to TOY_TYPE_UW.
543
 */
544
static inline struct toy_src
545
tsrc_uw(struct toy_src src)
546
{
547
   return tsrc_type(src, TOY_TYPE_UW);
548
}
549
 
550
/**
551
 * Change the rectangle of the source operand.
552
 */
553
static inline struct toy_src
554
tsrc_rect(struct toy_src src, enum toy_rect rect)
555
{
556
   src.rect = rect;
557
   return tsrc_validate(src);
558
}
559
 
560
/**
561
 * Swizzle the source operand.  Note that the current swizzles are honored.
562
 */
563
static inline struct toy_src
564
tsrc_swizzle(struct toy_src src,
565
             enum toy_swizzle swizzle_x, enum toy_swizzle swizzle_y,
566
             enum toy_swizzle swizzle_z, enum toy_swizzle swizzle_w)
567
{
568
   const enum toy_swizzle current[4] = {
569
      src.swizzle_x, src.swizzle_y,
570
      src.swizzle_z, src.swizzle_w,
571
   };
572
 
573
   src.swizzle_x = current[swizzle_x];
574
   src.swizzle_y = current[swizzle_y];
575
   src.swizzle_z = current[swizzle_z];
576
   src.swizzle_w = current[swizzle_w];
577
 
578
   return tsrc_validate(src);
579
}
580
 
581
/**
582
 * Swizzle the source operand to the same channel.  Note that the current
583
 * swizzles are honored.
584
 */
585
static inline struct toy_src
586
tsrc_swizzle1(struct toy_src src, enum toy_swizzle swizzle)
587
{
588
   return tsrc_swizzle(src, swizzle, swizzle, swizzle, swizzle);
589
}
590
 
591
/**
592
 * Set absolute and unset negate of the source operand.
593
 */
594
static inline struct toy_src
595
tsrc_absolute(struct toy_src src)
596
{
597
   src.absolute = true;
598
   src.negate = false;
599
   return tsrc_validate(src);
600
}
601
 
602
/**
603
 * Negate the source operand.
604
 */
605
static inline struct toy_src
606
tsrc_negate(struct toy_src src)
607
{
608
   src.negate = !src.negate;
609
   return tsrc_validate(src);
610
}
611
 
612
/**
613
 * Offset the source operand.
614
 */
615
static inline struct toy_src
616
tsrc_offset(struct toy_src src, int reg, int subreg)
617
{
618
   src.val32 += reg * TOY_REG_WIDTH + subreg * toy_type_size(src.type);
619
   return tsrc_validate(src);
620
}
621
 
622
/**
623
 * Construct a source operand.
624
 */
625
static inline struct toy_src
626
tsrc_full(enum toy_file file, enum toy_type type,
627
          enum toy_rect rect, bool indirect, unsigned indirect_subreg,
628
          enum toy_swizzle swizzle_x, enum toy_swizzle swizzle_y,
629
          enum toy_swizzle swizzle_z, enum toy_swizzle swizzle_w,
630
          bool absolute, bool negate,
631
          uint32_t val32)
632
{
633
   struct toy_src src;
634
 
635
   src.file = file;
636
   src.type = type;
637
   src.rect = rect;
638
   src.indirect = indirect;
639
   src.indirect_subreg = indirect_subreg;
640
   src.swizzle_x = swizzle_x;
641
   src.swizzle_y = swizzle_y;
642
   src.swizzle_z = swizzle_z;
643
   src.swizzle_w = swizzle_w;
644
   src.absolute = absolute;
645
   src.negate = negate;
646
   src.pad = 0;
647
 
648
   src.val32 = val32;
649
 
650
   return tsrc_validate(src);
651
}
652
 
653
/**
654
 * Construct a null source operand.
655
 */
656
static inline struct toy_src
657
tsrc_null(void)
658
{
659
   static const struct toy_src null_src = {
660
      .file = TOY_FILE_ARF,
661
      .type = TOY_TYPE_F,
662
      .rect = TOY_RECT_LINEAR,
663
      .indirect = false,
664
      .indirect_subreg = 0,
665
      .swizzle_x = TOY_SWIZZLE_X,
666
      .swizzle_y = TOY_SWIZZLE_Y,
667
      .swizzle_z = TOY_SWIZZLE_Z,
668
      .swizzle_w = TOY_SWIZZLE_W,
669
      .absolute = false,
670
      .negate = false,
671
      .pad = 0,
672
      .val32 = 0,
673
   };
674
 
675
   return null_src;
676
}
677
 
678
/**
679
 * Construct a source operand from a destination operand.
680
 */
681
static inline struct toy_src
682
tsrc_from(struct toy_dst dst)
683
{
684
   enum toy_swizzle swizzle[4];
685
 
686
   if (dst.writemask == TOY_WRITEMASK_XYZW) {
687
      swizzle[0] = TOY_SWIZZLE_X;
688
      swizzle[1] = TOY_SWIZZLE_Y;
689
      swizzle[2] = TOY_SWIZZLE_Z;
690
      swizzle[3] = TOY_SWIZZLE_W;
691
   }
692
   else {
693
      const enum toy_swizzle first =
694
         (dst.writemask & TOY_WRITEMASK_X) ? TOY_SWIZZLE_X :
695
         (dst.writemask & TOY_WRITEMASK_Y) ? TOY_SWIZZLE_Y :
696
         (dst.writemask & TOY_WRITEMASK_Z) ? TOY_SWIZZLE_Z :
697
         (dst.writemask & TOY_WRITEMASK_W) ? TOY_SWIZZLE_W :
698
         TOY_SWIZZLE_X;
699
 
700
      swizzle[0] = (dst.writemask & TOY_WRITEMASK_X) ? TOY_SWIZZLE_X : first;
701
      swizzle[1] = (dst.writemask & TOY_WRITEMASK_Y) ? TOY_SWIZZLE_Y : first;
702
      swizzle[2] = (dst.writemask & TOY_WRITEMASK_Z) ? TOY_SWIZZLE_Z : first;
703
      swizzle[3] = (dst.writemask & TOY_WRITEMASK_W) ? TOY_SWIZZLE_W : first;
704
   }
705
 
706
   return tsrc_full(dst.file, dst.type, dst.rect,
707
                    dst.indirect, dst.indirect_subreg,
708
                    swizzle[0], swizzle[1], swizzle[2], swizzle[3],
709
                    false, false, dst.val32);
710
}
711
 
712
/**
713
 * Construct a source operand, assuming the type is TOY_TYPE_F, the
714
 * rectangle is TOY_RECT_LINEAR, and no swizzles/absolute/negate.
715
 */
716
static inline struct toy_src
717
tsrc(enum toy_file file, unsigned reg, unsigned subreg_in_bytes)
718
{
719
   const enum toy_type type = TOY_TYPE_F;
720
   const enum toy_rect rect = TOY_RECT_LINEAR;
721
   const uint32_t val32 = reg * TOY_REG_WIDTH + subreg_in_bytes;
722
 
723
   return tsrc_full(file, type, rect, false, 0,
724
                    TOY_SWIZZLE_X, TOY_SWIZZLE_Y,
725
                    TOY_SWIZZLE_Z, TOY_SWIZZLE_W,
726
                    false, false, val32);
727
}
728
 
729
/**
730
 * Construct an immediate source operand.
731
 */
732
static inline struct toy_src
733
tsrc_imm(enum toy_type type, uint32_t val32)
734
{
735
   return tsrc_full(TOY_FILE_IMM, type, TOY_RECT_LINEAR, false, 0,
736
                    TOY_SWIZZLE_X, TOY_SWIZZLE_Y,
737
                    TOY_SWIZZLE_Z, TOY_SWIZZLE_W,
738
                    false, false, val32);
739
}
740
 
741
/**
742
 * Construct an immediate source operand of type TOY_TYPE_F.
743
 */
744
static inline struct toy_src
745
tsrc_imm_f(float f)
746
{
747
   const union fi fi = { .f = f };
748
   return tsrc_imm(TOY_TYPE_F, fi.ui);
749
}
750
 
751
/**
752
 * Construct an immediate source operand of type TOY_TYPE_D.
753
 */
754
static inline struct toy_src
755
tsrc_imm_d(int32_t d)
756
{
757
   const union fi fi = { .i = d };
758
   return tsrc_imm(TOY_TYPE_D, fi.ui);
759
}
760
 
761
/**
762
 * Construct an immediate source operand of type TOY_TYPE_UD.
763
 */
764
static inline struct toy_src
765
tsrc_imm_ud(uint32_t ud)
766
{
767
   const union fi fi = { .ui = ud };
768
   return tsrc_imm(TOY_TYPE_UD, fi.ui);
769
}
770
 
771
/**
772
 * Construct an immediate source operand of type TOY_TYPE_W.
773
 */
774
static inline struct toy_src
775
tsrc_imm_w(int16_t w)
776
{
777
   const union fi fi = { .i = w };
778
   return tsrc_imm(TOY_TYPE_W, fi.ui);
779
}
780
 
781
/**
782
 * Construct an immediate source operand of type TOY_TYPE_UW.
783
 */
784
static inline struct toy_src
785
tsrc_imm_uw(uint16_t uw)
786
{
787
   const union fi fi = { .ui = uw };
788
   return tsrc_imm(TOY_TYPE_UW, fi.ui);
789
}
790
 
791
/**
792
 * Construct an immediate source operand of type TOY_TYPE_V.
793
 */
794
static inline struct toy_src
795
tsrc_imm_v(uint32_t v)
796
{
797
   return tsrc_imm(TOY_TYPE_V, v);
798
}
799
 
800
#endif /* TOY_REG_H */