Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5563 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
#include "tgsi/tgsi_parse.h"
29
#include "tgsi/tgsi_info.h"
30
#include "tgsi/tgsi_strings.h"
31
#include "util/u_hash_table.h"
32
#include "toy_helpers.h"
33
#include "toy_tgsi.h"
34
 
35
/* map TGSI opcode to GEN opcode 1-to-1 */
36
static const struct {
37
   int opcode;
38
   int num_dst;
39
   int num_src;
40
} aos_simple_opcode_map[TGSI_OPCODE_LAST] = {
41
   [TGSI_OPCODE_ARL]          = { BRW_OPCODE_RNDD,                1, 1 },
42
   [TGSI_OPCODE_MOV]          = { BRW_OPCODE_MOV,                 1, 1 },
43
   [TGSI_OPCODE_RCP]          = { TOY_OPCODE_INV,                 1, 1 },
44
   [TGSI_OPCODE_RSQ]          = { TOY_OPCODE_RSQ,                 1, 1 },
45
   [TGSI_OPCODE_MUL]          = { BRW_OPCODE_MUL,                 1, 2 },
46
   [TGSI_OPCODE_ADD]          = { BRW_OPCODE_ADD,                 1, 2 },
47
   [TGSI_OPCODE_DP3]          = { BRW_OPCODE_DP3,                 1, 2 },
48
   [TGSI_OPCODE_DP4]          = { BRW_OPCODE_DP4,                 1, 2 },
49
   [TGSI_OPCODE_MIN]          = { BRW_OPCODE_SEL,                 1, 2 },
50
   [TGSI_OPCODE_MAX]          = { BRW_OPCODE_SEL,                 1, 2 },
51
   /* a later pass will move src[2] to accumulator */
52
   [TGSI_OPCODE_MAD]          = { BRW_OPCODE_MAC,                 1, 3 },
53
   [TGSI_OPCODE_SUB]          = { BRW_OPCODE_ADD,                 1, 2 },
54
   [TGSI_OPCODE_SQRT]         = { TOY_OPCODE_SQRT,                1, 1 },
55
   [TGSI_OPCODE_FRC]          = { BRW_OPCODE_FRC,                 1, 1 },
56
   [TGSI_OPCODE_FLR]          = { BRW_OPCODE_RNDD,                1, 1 },
57
   [TGSI_OPCODE_ROUND]        = { BRW_OPCODE_RNDE,                1, 1 },
58
   [TGSI_OPCODE_EX2]          = { TOY_OPCODE_EXP,                 1, 1 },
59
   [TGSI_OPCODE_LG2]          = { TOY_OPCODE_LOG,                 1, 1 },
60
   [TGSI_OPCODE_POW]          = { TOY_OPCODE_POW,                 1, 2 },
61
   [TGSI_OPCODE_ABS]          = { BRW_OPCODE_MOV,                 1, 1 },
62
   [TGSI_OPCODE_DPH]          = { BRW_OPCODE_DPH,                 1, 2 },
63
   [TGSI_OPCODE_COS]          = { TOY_OPCODE_COS,                 1, 1 },
64
   [TGSI_OPCODE_KILL]         = { TOY_OPCODE_KIL,                 0, 0 },
65
   [TGSI_OPCODE_SIN]          = { TOY_OPCODE_SIN,                 1, 1 },
66
   [TGSI_OPCODE_ARR]          = { BRW_OPCODE_RNDZ,                1, 1 },
67
   [TGSI_OPCODE_DP2]          = { BRW_OPCODE_DP2,                 1, 2 },
68
   [TGSI_OPCODE_IF]           = { BRW_OPCODE_IF,                  0, 1 },
69
   [TGSI_OPCODE_UIF]          = { BRW_OPCODE_IF,                  0, 1 },
70
   [TGSI_OPCODE_ELSE]         = { BRW_OPCODE_ELSE,                0, 0 },
71
   [TGSI_OPCODE_ENDIF]        = { BRW_OPCODE_ENDIF,               0, 0 },
72
   [TGSI_OPCODE_I2F]          = { BRW_OPCODE_MOV,                 1, 1 },
73
   [TGSI_OPCODE_NOT]          = { BRW_OPCODE_NOT,                 1, 1 },
74
   [TGSI_OPCODE_TRUNC]        = { BRW_OPCODE_RNDZ,                1, 1 },
75
   [TGSI_OPCODE_SHL]          = { BRW_OPCODE_SHL,                 1, 2 },
76
   [TGSI_OPCODE_AND]          = { BRW_OPCODE_AND,                 1, 2 },
77
   [TGSI_OPCODE_OR]           = { BRW_OPCODE_OR,                  1, 2 },
78
   [TGSI_OPCODE_MOD]          = { TOY_OPCODE_INT_DIV_REMAINDER,   1, 2 },
79
   [TGSI_OPCODE_XOR]          = { BRW_OPCODE_XOR,                 1, 2 },
80
   [TGSI_OPCODE_EMIT]         = { TOY_OPCODE_EMIT,                0, 0 },
81
   [TGSI_OPCODE_ENDPRIM]      = { TOY_OPCODE_ENDPRIM,             0, 0 },
82
   [TGSI_OPCODE_NOP]          = { BRW_OPCODE_NOP,                 0, 0 },
83
   [TGSI_OPCODE_KILL_IF]      = { TOY_OPCODE_KIL,                 0, 1 },
84
   [TGSI_OPCODE_END]          = { BRW_OPCODE_NOP,                 0, 0 },
85
   [TGSI_OPCODE_F2I]          = { BRW_OPCODE_MOV,                 1, 1 },
86
   [TGSI_OPCODE_IDIV]         = { TOY_OPCODE_INT_DIV_QUOTIENT,    1, 2 },
87
   [TGSI_OPCODE_IMAX]         = { BRW_OPCODE_SEL,                 1, 2 },
88
   [TGSI_OPCODE_IMIN]         = { BRW_OPCODE_SEL,                 1, 2 },
89
   [TGSI_OPCODE_INEG]         = { BRW_OPCODE_MOV,                 1, 1 },
90
   [TGSI_OPCODE_ISHR]         = { BRW_OPCODE_ASR,                 1, 2 },
91
   [TGSI_OPCODE_F2U]          = { BRW_OPCODE_MOV,                 1, 1 },
92
   [TGSI_OPCODE_U2F]          = { BRW_OPCODE_MOV,                 1, 1 },
93
   [TGSI_OPCODE_UADD]         = { BRW_OPCODE_ADD,                 1, 2 },
94
   [TGSI_OPCODE_UDIV]         = { TOY_OPCODE_INT_DIV_QUOTIENT,    1, 2 },
95
   /* a later pass will move src[2] to accumulator */
96
   [TGSI_OPCODE_UMAD]         = { BRW_OPCODE_MAC,                 1, 3 },
97
   [TGSI_OPCODE_UMAX]         = { BRW_OPCODE_SEL,                 1, 2 },
98
   [TGSI_OPCODE_UMIN]         = { BRW_OPCODE_SEL,                 1, 2 },
99
   [TGSI_OPCODE_UMOD]         = { TOY_OPCODE_INT_DIV_REMAINDER,   1, 2 },
100
   [TGSI_OPCODE_UMUL]         = { BRW_OPCODE_MUL,                 1, 2 },
101
   [TGSI_OPCODE_USHR]         = { BRW_OPCODE_SHR,                 1, 2 },
102
   [TGSI_OPCODE_UARL]         = { BRW_OPCODE_MOV,                 1, 1 },
103
   [TGSI_OPCODE_IABS]         = { BRW_OPCODE_MOV,                 1, 1 },
104
};
105
 
106
static void
107
aos_simple(struct toy_compiler *tc,
108
           const struct tgsi_full_instruction *tgsi_inst,
109
           struct toy_dst *dst,
110
           struct toy_src *src)
111
{
112
   struct toy_inst *inst;
113
   int opcode;
114
   int cond_modifier = BRW_CONDITIONAL_NONE;
115
   int num_dst = tgsi_inst->Instruction.NumDstRegs;
116
   int num_src = tgsi_inst->Instruction.NumSrcRegs;
117
   int i;
118
 
119
   opcode = aos_simple_opcode_map[tgsi_inst->Instruction.Opcode].opcode;
120
   assert(num_dst == aos_simple_opcode_map[tgsi_inst->Instruction.Opcode].num_dst);
121
   assert(num_src == aos_simple_opcode_map[tgsi_inst->Instruction.Opcode].num_src);
122
   if (!opcode) {
123
      assert(!"invalid aos_simple() call");
124
      return;
125
   }
126
 
127
   /* no need to emit nop */
128
   if (opcode == BRW_OPCODE_NOP)
129
      return;
130
 
131
   inst = tc_add(tc);
132
   if (!inst)
133
      return;
134
 
135
   inst->opcode = opcode;
136
 
137
   switch (tgsi_inst->Instruction.Opcode) {
138
   case TGSI_OPCODE_MIN:
139
   case TGSI_OPCODE_IMIN:
140
   case TGSI_OPCODE_UMIN:
141
      cond_modifier = BRW_CONDITIONAL_L;
142
      break;
143
   case TGSI_OPCODE_MAX:
144
   case TGSI_OPCODE_IMAX:
145
   case TGSI_OPCODE_UMAX:
146
      cond_modifier = BRW_CONDITIONAL_GE;
147
      break;
148
   case TGSI_OPCODE_SUB:
149
      src[1] = tsrc_negate(src[1]);
150
      break;
151
   case TGSI_OPCODE_ABS:
152
   case TGSI_OPCODE_IABS:
153
      src[0] = tsrc_absolute(src[0]);
154
      break;
155
   case TGSI_OPCODE_IF:
156
      cond_modifier = BRW_CONDITIONAL_NEQ;
157
      num_src = 2;
158
      assert(src[0].type == TOY_TYPE_F);
159
      src[0] = tsrc_swizzle1(src[0], TOY_SWIZZLE_X);
160
      src[1] = tsrc_imm_f(0.0f);
161
      break;
162
   case TGSI_OPCODE_UIF:
163
      cond_modifier = BRW_CONDITIONAL_NEQ;
164
      num_src = 2;
165
      assert(src[0].type == TOY_TYPE_UD);
166
      src[0] = tsrc_swizzle1(src[0], TOY_SWIZZLE_X);
167
      src[1] = tsrc_imm_d(0);
168
      break;
169
   case TGSI_OPCODE_INEG:
170
      src[0] = tsrc_negate(src[0]);
171
      break;
172
   case TGSI_OPCODE_RCP:
173
   case TGSI_OPCODE_RSQ:
174
   case TGSI_OPCODE_EX2:
175
   case TGSI_OPCODE_LG2:
176
   case TGSI_OPCODE_COS:
177
   case TGSI_OPCODE_SIN:
178
      src[0] = tsrc_swizzle1(src[0], TOY_SWIZZLE_X);
179
      break;
180
   case TGSI_OPCODE_POW:
181
      src[0] = tsrc_swizzle1(src[0], TOY_SWIZZLE_X);
182
      src[1] = tsrc_swizzle1(src[1], TOY_SWIZZLE_X);
183
      break;
184
   }
185
 
186
   inst->cond_modifier = cond_modifier;
187
 
188
   if (num_dst) {
189
      assert(num_dst == 1);
190
      inst->dst = dst[0];
191
   }
192
 
193
   assert(num_src <= Elements(inst->src));
194
   for (i = 0; i < num_src; i++)
195
      inst->src[i] = src[i];
196
}
197
 
198
static void
199
aos_set_on_cond(struct toy_compiler *tc,
200
                const struct tgsi_full_instruction *tgsi_inst,
201
                struct toy_dst *dst,
202
                struct toy_src *src)
203
{
204
   struct toy_inst *inst;
205
   int cond;
206
   struct toy_src zero, one;
207
 
208
   switch (tgsi_inst->Instruction.Opcode) {
209
   case TGSI_OPCODE_SLT:
210
   case TGSI_OPCODE_ISLT:
211
   case TGSI_OPCODE_USLT:
212
      cond = BRW_CONDITIONAL_L;
213
      break;
214
   case TGSI_OPCODE_SGE:
215
   case TGSI_OPCODE_ISGE:
216
   case TGSI_OPCODE_USGE:
217
      cond = BRW_CONDITIONAL_GE;
218
      break;
219
   case TGSI_OPCODE_SEQ:
220
   case TGSI_OPCODE_USEQ:
221
      cond = BRW_CONDITIONAL_EQ;
222
      break;
223
   case TGSI_OPCODE_SGT:
224
      cond = BRW_CONDITIONAL_G;
225
      break;
226
   case TGSI_OPCODE_SLE:
227
      cond = BRW_CONDITIONAL_LE;
228
      break;
229
   case TGSI_OPCODE_SNE:
230
   case TGSI_OPCODE_USNE:
231
      cond = BRW_CONDITIONAL_NEQ;
232
      break;
233
   default:
234
      assert(!"invalid aos_set_on_cond() call");
235
      return;
236
   }
237
 
238
   /* note that for integer versions, all bits are set */
239
   switch (dst[0].type) {
240
   case TOY_TYPE_F:
241
   default:
242
      zero = tsrc_imm_f(0.0f);
243
      one = tsrc_imm_f(1.0f);
244
      break;
245
   case TOY_TYPE_D:
246
      zero = tsrc_imm_d(0);
247
      one = tsrc_imm_d(-1);
248
      break;
249
   case TOY_TYPE_UD:
250
      zero = tsrc_imm_ud(0);
251
      one = tsrc_imm_ud(~0);
252
      break;
253
   }
254
 
255
   tc_MOV(tc, dst[0], zero);
256
   tc_CMP(tc, tdst_null(), src[0], src[1], cond);
257
   inst = tc_MOV(tc, dst[0], one);
258
   inst->pred_ctrl = BRW_PREDICATE_NORMAL;
259
}
260
 
261
static void
262
aos_compare(struct toy_compiler *tc,
263
            const struct tgsi_full_instruction *tgsi_inst,
264
            struct toy_dst *dst,
265
            struct toy_src *src)
266
{
267
   struct toy_inst *inst;
268
   struct toy_src zero;
269
 
270
   switch (tgsi_inst->Instruction.Opcode) {
271
   case TGSI_OPCODE_CMP:
272
      zero = tsrc_imm_f(0.0f);
273
      break;
274
   case TGSI_OPCODE_UCMP:
275
      zero = tsrc_imm_ud(0);
276
      break;
277
   default:
278
      assert(!"invalid aos_compare() call");
279
      return;
280
   }
281
 
282
   tc_CMP(tc, tdst_null(), src[0], zero, BRW_CONDITIONAL_L);
283
   inst = tc_SEL(tc, dst[0], src[1], src[2], BRW_CONDITIONAL_NONE);
284
   inst->pred_ctrl = BRW_PREDICATE_NORMAL;
285
}
286
 
287
static void
288
aos_set_sign(struct toy_compiler *tc,
289
             const struct tgsi_full_instruction *tgsi_inst,
290
             struct toy_dst *dst,
291
             struct toy_src *src)
292
{
293
   struct toy_inst *inst;
294
   struct toy_src zero, one, neg_one;
295
 
296
   switch (tgsi_inst->Instruction.Opcode) {
297
   case TGSI_OPCODE_SSG:
298
      zero = tsrc_imm_f(0.0f);
299
      one = tsrc_imm_f(1.0f);
300
      neg_one = tsrc_imm_f(-1.0f);
301
      break;
302
   case TGSI_OPCODE_ISSG:
303
      zero = tsrc_imm_d(0);
304
      one = tsrc_imm_d(1);
305
      neg_one = tsrc_imm_d(-1);
306
      break;
307
   default:
308
      assert(!"invalid aos_set_sign() call");
309
      return;
310
   }
311
 
312
   tc_MOV(tc, dst[0], zero);
313
 
314
   tc_CMP(tc, tdst_null(), src[0], zero, BRW_CONDITIONAL_G);
315
   inst = tc_MOV(tc, dst[0], one);
316
   inst->pred_ctrl = BRW_PREDICATE_NORMAL;
317
 
318
   tc_CMP(tc, tdst_null(), src[0], zero, BRW_CONDITIONAL_L);
319
   inst = tc_MOV(tc, dst[0], neg_one);
320
   inst->pred_ctrl = BRW_PREDICATE_NORMAL;
321
}
322
 
323
static void
324
aos_tex(struct toy_compiler *tc,
325
        const struct tgsi_full_instruction *tgsi_inst,
326
        struct toy_dst *dst,
327
        struct toy_src *src)
328
{
329
   struct toy_inst *inst;
330
   enum toy_opcode opcode;
331
   int i;
332
 
333
   switch (tgsi_inst->Instruction.Opcode) {
334
   case TGSI_OPCODE_TEX:
335
      opcode = TOY_OPCODE_TGSI_TEX;
336
      break;
337
   case TGSI_OPCODE_TXD:
338
      opcode = TOY_OPCODE_TGSI_TXD;
339
      break;
340
   case TGSI_OPCODE_TXP:
341
      opcode = TOY_OPCODE_TGSI_TXP;
342
      break;
343
   case TGSI_OPCODE_TXB:
344
      opcode = TOY_OPCODE_TGSI_TXB;
345
      break;
346
   case TGSI_OPCODE_TXL:
347
      opcode = TOY_OPCODE_TGSI_TXL;
348
      break;
349
   case TGSI_OPCODE_TXF:
350
      opcode = TOY_OPCODE_TGSI_TXF;
351
      break;
352
   case TGSI_OPCODE_TXQ:
353
      opcode = TOY_OPCODE_TGSI_TXQ;
354
      break;
355
   case TGSI_OPCODE_TXQ_LZ:
356
      opcode = TOY_OPCODE_TGSI_TXQ_LZ;
357
      break;
358
   case TGSI_OPCODE_TEX2:
359
      opcode = TOY_OPCODE_TGSI_TEX2;
360
      break;
361
   case TGSI_OPCODE_TXB2:
362
      opcode = TOY_OPCODE_TGSI_TXB2;
363
      break;
364
   case TGSI_OPCODE_TXL2:
365
      opcode = TOY_OPCODE_TGSI_TXL2;
366
      break;
367
   default:
368
      assert(!"unsupported texturing opcode");
369
      return;
370
      break;
371
   }
372
 
373
   assert(tgsi_inst->Instruction.Texture);
374
 
375
   inst = tc_add(tc);
376
   inst->opcode = opcode;
377
   inst->tex.target = tgsi_inst->Texture.Texture;
378
 
379
   assert(tgsi_inst->Instruction.NumSrcRegs <= Elements(inst->src));
380
   assert(tgsi_inst->Instruction.NumDstRegs == 1);
381
 
382
   inst->dst = dst[0];
383
   for (i = 0; i < tgsi_inst->Instruction.NumSrcRegs; i++)
384
      inst->src[i] = src[i];
385
 
386
   for (i = 0; i < tgsi_inst->Texture.NumOffsets; i++)
387
      tc_fail(tc, "texelFetchOffset unsupported");
388
}
389
 
390
static void
391
aos_sample(struct toy_compiler *tc,
392
           const struct tgsi_full_instruction *tgsi_inst,
393
           struct toy_dst *dst,
394
           struct toy_src *src)
395
{
396
   struct toy_inst *inst;
397
   enum toy_opcode opcode;
398
   int i;
399
 
400
   assert(!"sampling untested");
401
 
402
   switch (tgsi_inst->Instruction.Opcode) {
403
   case TGSI_OPCODE_SAMPLE:
404
      opcode = TOY_OPCODE_TGSI_SAMPLE;
405
      break;
406
   case TGSI_OPCODE_SAMPLE_I:
407
      opcode = TOY_OPCODE_TGSI_SAMPLE_I;
408
      break;
409
   case TGSI_OPCODE_SAMPLE_I_MS:
410
      opcode = TOY_OPCODE_TGSI_SAMPLE_I_MS;
411
      break;
412
   case TGSI_OPCODE_SAMPLE_B:
413
      opcode = TOY_OPCODE_TGSI_SAMPLE_B;
414
      break;
415
   case TGSI_OPCODE_SAMPLE_C:
416
      opcode = TOY_OPCODE_TGSI_SAMPLE_C;
417
      break;
418
   case TGSI_OPCODE_SAMPLE_C_LZ:
419
      opcode = TOY_OPCODE_TGSI_SAMPLE_C_LZ;
420
      break;
421
   case TGSI_OPCODE_SAMPLE_D:
422
      opcode = TOY_OPCODE_TGSI_SAMPLE_D;
423
      break;
424
   case TGSI_OPCODE_SAMPLE_L:
425
      opcode = TOY_OPCODE_TGSI_SAMPLE_L;
426
      break;
427
   case TGSI_OPCODE_GATHER4:
428
      opcode = TOY_OPCODE_TGSI_GATHER4;
429
      break;
430
   case TGSI_OPCODE_SVIEWINFO:
431
      opcode = TOY_OPCODE_TGSI_SVIEWINFO;
432
      break;
433
   case TGSI_OPCODE_SAMPLE_POS:
434
      opcode = TOY_OPCODE_TGSI_SAMPLE_POS;
435
      break;
436
   case TGSI_OPCODE_SAMPLE_INFO:
437
      opcode = TOY_OPCODE_TGSI_SAMPLE_INFO;
438
      break;
439
   default:
440
      assert(!"unsupported sampling opcode");
441
      return;
442
      break;
443
   }
444
 
445
   inst = tc_add(tc);
446
   inst->opcode = opcode;
447
 
448
   assert(tgsi_inst->Instruction.NumSrcRegs <= Elements(inst->src));
449
   assert(tgsi_inst->Instruction.NumDstRegs == 1);
450
 
451
   inst->dst = dst[0];
452
   for (i = 0; i < tgsi_inst->Instruction.NumSrcRegs; i++)
453
      inst->src[i] = src[i];
454
}
455
 
456
static void
457
aos_LIT(struct toy_compiler *tc,
458
        const struct tgsi_full_instruction *tgsi_inst,
459
        struct toy_dst *dst,
460
        struct toy_src *src)
461
{
462
   struct toy_inst *inst;
463
 
464
   tc_MOV(tc, tdst_writemask(dst[0], TOY_WRITEMASK_XW), tsrc_imm_f(1.0f));
465
 
466
   if (!(dst[0].writemask & TOY_WRITEMASK_YZ))
467
      return;
468
 
469
   tc_MOV(tc, tdst_writemask(dst[0], TOY_WRITEMASK_YZ), tsrc_imm_f(0.0f));
470
 
471
   tc_CMP(tc, tdst_null(),
472
         tsrc_swizzle1(src[0], TOY_SWIZZLE_X),
473
         tsrc_imm_f(0.0f),
474
         BRW_CONDITIONAL_G);
475
 
476
   inst = tc_MOV(tc,
477
         tdst_writemask(dst[0], TOY_WRITEMASK_Y),
478
         tsrc_swizzle1(src[0], TOY_SWIZZLE_X));
479
   inst->pred_ctrl = BRW_PREDICATE_NORMAL;
480
 
481
   /* clamp W to (-128, 128)? */
482
   inst = tc_POW(tc,
483
         tdst_writemask(dst[0], TOY_WRITEMASK_Z),
484
         tsrc_swizzle1(src[0], TOY_SWIZZLE_Y),
485
         tsrc_swizzle1(src[0], TOY_SWIZZLE_W));
486
   inst->pred_ctrl = BRW_PREDICATE_NORMAL;
487
}
488
 
489
static void
490
aos_EXP(struct toy_compiler *tc,
491
        const struct tgsi_full_instruction *tgsi_inst,
492
        struct toy_dst *dst,
493
        struct toy_src *src)
494
{
495
   struct toy_src src0 = tsrc_swizzle1(src[0], TOY_SWIZZLE_X);
496
 
497
   if (dst[0].writemask & TOY_WRITEMASK_X) {
498
      struct toy_dst tmp =
499
         tdst_d(tdst_writemask(tc_alloc_tmp(tc), TOY_WRITEMASK_X));
500
 
501
      tc_RNDD(tc, tmp, src0);
502
 
503
      /* construct the floating point number manually */
504
      tc_ADD(tc, tmp, tsrc_from(tmp), tsrc_imm_d(127));
505
      tc_SHL(tc, tdst_d(tdst_writemask(dst[0], TOY_WRITEMASK_X)),
506
            tsrc_from(tmp), tsrc_imm_d(23));
507
   }
508
 
509
   tc_FRC(tc, tdst_writemask(dst[0], TOY_WRITEMASK_Y), src0);
510
   tc_EXP(tc, tdst_writemask(dst[0], TOY_WRITEMASK_Z), src0);
511
   tc_MOV(tc, tdst_writemask(dst[0], TOY_WRITEMASK_W), tsrc_imm_f(1.0f));
512
}
513
 
514
static void
515
aos_LOG(struct toy_compiler *tc,
516
        const struct tgsi_full_instruction *tgsi_inst,
517
        struct toy_dst *dst,
518
        struct toy_src *src)
519
{
520
   struct toy_src src0 = tsrc_swizzle1(src[0], TOY_SWIZZLE_X);
521
 
522
   if (dst[0].writemask & TOY_WRITEMASK_XY) {
523
      struct toy_dst tmp;
524
 
525
      tmp = tdst_d(tdst_writemask(tc_alloc_tmp(tc), TOY_WRITEMASK_X));
526
 
527
      /* exponent */
528
      tc_SHR(tc, tmp, tsrc_absolute(tsrc_d(src0)), tsrc_imm_d(23));
529
      tc_ADD(tc, tdst_writemask(dst[0], TOY_WRITEMASK_X),
530
            tsrc_from(tmp), tsrc_imm_d(-127));
531
 
532
      /* mantissa  */
533
      tc_AND(tc, tmp, tsrc_d(src0), tsrc_imm_d((1 << 23) - 1));
534
      tc_OR(tc, tdst_writemask(tdst_d(dst[0]), TOY_WRITEMASK_Y),
535
            tsrc_from(tmp), tsrc_imm_d(127 << 23));
536
   }
537
 
538
   tc_LOG(tc, tdst_writemask(dst[0], TOY_WRITEMASK_Z), src0);
539
   tc_MOV(tc, tdst_writemask(dst[0], TOY_WRITEMASK_W), tsrc_imm_f(1.0f));
540
}
541
 
542
static void
543
aos_DST(struct toy_compiler *tc,
544
        const struct tgsi_full_instruction *tgsi_inst,
545
        struct toy_dst *dst,
546
        struct toy_src *src)
547
{
548
   tc_MOV(tc, tdst_writemask(dst[0], TOY_WRITEMASK_X), tsrc_imm_f(1.0f));
549
   tc_MUL(tc, tdst_writemask(dst[0], TOY_WRITEMASK_Y), src[0], src[1]);
550
   tc_MOV(tc, tdst_writemask(dst[0], TOY_WRITEMASK_Z), src[0]);
551
   tc_MOV(tc, tdst_writemask(dst[0], TOY_WRITEMASK_W), src[1]);
552
}
553
 
554
static void
555
aos_LRP(struct toy_compiler *tc,
556
        const struct tgsi_full_instruction *tgsi_inst,
557
        struct toy_dst *dst,
558
        struct toy_src *src)
559
{
560
   struct toy_dst tmp = tc_alloc_tmp(tc);
561
 
562
   tc_ADD(tc, tmp, tsrc_negate(src[0]), tsrc_imm_f(1.0f));
563
   tc_MUL(tc, tmp, tsrc_from(tmp), src[2]);
564
   tc_MAC(tc, dst[0], src[0], src[1], tsrc_from(tmp));
565
}
566
 
567
static void
568
aos_CND(struct toy_compiler *tc,
569
        const struct tgsi_full_instruction *tgsi_inst,
570
        struct toy_dst *dst,
571
        struct toy_src *src)
572
{
573
   struct toy_inst *inst;
574
 
575
   assert(!"CND untested");
576
 
577
   tc_CMP(tc, tdst_null(), src[2], tsrc_imm_f(0.5f), BRW_CONDITIONAL_G);
578
   inst = tc_SEL(tc, dst[0], src[0], src[1], BRW_CONDITIONAL_NONE);
579
   inst->pred_ctrl = BRW_PREDICATE_NORMAL;
580
}
581
 
582
static void
583
aos_DP2A(struct toy_compiler *tc,
584
         const struct tgsi_full_instruction *tgsi_inst,
585
         struct toy_dst *dst,
586
         struct toy_src *src)
587
{
588
   struct toy_dst tmp = tc_alloc_tmp(tc);
589
 
590
   assert(!"DP2A untested");
591
 
592
   tc_DP2(tc, tmp, src[0], src[1]);
593
   tc_ADD(tc, dst[0], tsrc_swizzle1(tsrc_from(tmp), TOY_SWIZZLE_X), src[2]);
594
}
595
 
596
static void
597
aos_CLAMP(struct toy_compiler *tc,
598
          const struct tgsi_full_instruction *tgsi_inst,
599
          struct toy_dst *dst,
600
          struct toy_src *src)
601
{
602
   assert(!"CLAMP untested");
603
 
604
   tc_SEL(tc, dst[0], src[0], src[1], BRW_CONDITIONAL_GE);
605
   tc_SEL(tc, dst[0], src[2], tsrc_from(dst[0]), BRW_CONDITIONAL_L);
606
}
607
 
608
static void
609
aos_XPD(struct toy_compiler *tc,
610
        const struct tgsi_full_instruction *tgsi_inst,
611
        struct toy_dst *dst,
612
        struct toy_src *src)
613
{
614
   struct toy_dst tmp = tc_alloc_tmp(tc);
615
 
616
   tc_MUL(tc, tdst_writemask(tmp, TOY_WRITEMASK_XYZ),
617
         tsrc_swizzle(src[0], TOY_SWIZZLE_Z, TOY_SWIZZLE_X,
618
                              TOY_SWIZZLE_Y, TOY_SWIZZLE_W),
619
         tsrc_swizzle(src[1], TOY_SWIZZLE_Y, TOY_SWIZZLE_Z,
620
                              TOY_SWIZZLE_X, TOY_SWIZZLE_W));
621
 
622
   tc_MAC(tc, tdst_writemask(dst[0], TOY_WRITEMASK_XYZ),
623
         tsrc_swizzle(src[0], TOY_SWIZZLE_Y, TOY_SWIZZLE_Z,
624
                              TOY_SWIZZLE_X, TOY_SWIZZLE_W),
625
         tsrc_swizzle(src[1], TOY_SWIZZLE_Z, TOY_SWIZZLE_X,
626
                              TOY_SWIZZLE_Y, TOY_SWIZZLE_W),
627
         tsrc_negate(tsrc_from(tmp)));
628
 
629
   tc_MOV(tc, tdst_writemask(dst[0], TOY_WRITEMASK_W),
630
         tsrc_imm_f(1.0f));
631
}
632
 
633
static void
634
aos_PK2H(struct toy_compiler *tc,
635
         const struct tgsi_full_instruction *tgsi_inst,
636
         struct toy_dst *dst,
637
         struct toy_src *src)
638
{
639
   const struct toy_src h1 = tsrc_ud(tsrc_swizzle1(src[0], TOY_SWIZZLE_X));
640
   const struct toy_src h2 = tsrc_ud(tsrc_swizzle1(src[0], TOY_SWIZZLE_Y));
641
   struct toy_dst tmp = tdst_ud(tc_alloc_tmp(tc));
642
 
643
   assert(!"PK2H untested");
644
 
645
   tc_SHL(tc, tmp, h2, tsrc_imm_ud(16));
646
   tc_OR(tc, tdst_ud(dst[0]), h1, tsrc_from(tmp));
647
}
648
 
649
static void
650
aos_SFL(struct toy_compiler *tc,
651
        const struct tgsi_full_instruction *tgsi_inst,
652
        struct toy_dst *dst,
653
        struct toy_src *src)
654
{
655
   assert(!"SFL untested");
656
 
657
   tc_MOV(tc, dst[0], tsrc_imm_f(0.0f));
658
}
659
 
660
static void
661
aos_STR(struct toy_compiler *tc,
662
        const struct tgsi_full_instruction *tgsi_inst,
663
        struct toy_dst *dst,
664
        struct toy_src *src)
665
{
666
   assert(!"STR untested");
667
 
668
   tc_MOV(tc, dst[0], tsrc_imm_f(1.0f));
669
}
670
 
671
static void
672
aos_UP2H(struct toy_compiler *tc,
673
         const struct tgsi_full_instruction *tgsi_inst,
674
         struct toy_dst *dst,
675
         struct toy_src *src)
676
{
677
   assert(!"UP2H untested");
678
 
679
   tc_AND(tc, tdst_writemask(tdst_ud(dst[0]), TOY_WRITEMASK_XZ),
680
         tsrc_ud(src[0]), tsrc_imm_ud(0xffff));
681
   tc_SHR(tc, tdst_writemask(tdst_ud(dst[0]), TOY_WRITEMASK_YW),
682
         tsrc_ud(src[0]), tsrc_imm_ud(16));
683
}
684
 
685
static void
686
aos_SCS(struct toy_compiler *tc,
687
        const struct tgsi_full_instruction *tgsi_inst,
688
        struct toy_dst *dst,
689
        struct toy_src *src)
690
{
691
   assert(!"SCS untested");
692
 
693
   tc_add1(tc, TOY_OPCODE_COS,
694
         tdst_writemask(dst[0], TOY_WRITEMASK_X), src[0]);
695
 
696
   tc_add1(tc, TOY_OPCODE_SIN,
697
         tdst_writemask(dst[0], TOY_WRITEMASK_Y), src[0]);
698
 
699
   tc_MOV(tc, tdst_writemask(dst[0], TOY_WRITEMASK_Z), tsrc_imm_f(0.0f));
700
   tc_MOV(tc, tdst_writemask(dst[0], TOY_WRITEMASK_W), tsrc_imm_f(1.0f));
701
}
702
 
703
static void
704
aos_NRM(struct toy_compiler *tc,
705
        const struct tgsi_full_instruction *tgsi_inst,
706
        struct toy_dst *dst,
707
        struct toy_src *src)
708
{
709
   struct toy_dst tmp = tc_alloc_tmp(tc);
710
 
711
   assert(!"NRM untested");
712
 
713
   tc_DP3(tc, tmp, src[0], src[0]);
714
   tc_INV(tc, tmp, tsrc_from(tmp));
715
   tc_MUL(tc, tdst_writemask(dst[0], TOY_WRITEMASK_XYZ),
716
         src[0], tsrc_from(tmp));
717
 
718
   tc_MOV(tc, tdst_writemask(dst[0], TOY_WRITEMASK_W), tsrc_imm_f(1.0f));
719
}
720
 
721
static void
722
aos_DIV(struct toy_compiler *tc,
723
        const struct tgsi_full_instruction *tgsi_inst,
724
        struct toy_dst *dst,
725
        struct toy_src *src)
726
{
727
   struct toy_dst tmp = tc_alloc_tmp(tc);
728
 
729
   assert(!"DIV untested");
730
 
731
   tc_INV(tc, tmp, src[1]);
732
   tc_MUL(tc, dst[0], src[0], tsrc_from(tmp));
733
}
734
 
735
static void
736
aos_BRK(struct toy_compiler *tc,
737
        const struct tgsi_full_instruction *tgsi_inst,
738
        struct toy_dst *dst,
739
        struct toy_src *src)
740
{
741
   tc_add0(tc, BRW_OPCODE_BREAK);
742
}
743
 
744
static void
745
aos_CEIL(struct toy_compiler *tc,
746
         const struct tgsi_full_instruction *tgsi_inst,
747
         struct toy_dst *dst,
748
         struct toy_src *src)
749
{
750
   struct toy_dst tmp = tc_alloc_tmp(tc);
751
 
752
   tc_RNDD(tc, tmp, tsrc_negate(src[0]));
753
   tc_MOV(tc, dst[0], tsrc_negate(tsrc_from(tmp)));
754
}
755
 
756
static void
757
aos_SAD(struct toy_compiler *tc,
758
        const struct tgsi_full_instruction *tgsi_inst,
759
        struct toy_dst *dst,
760
        struct toy_src *src)
761
{
762
   struct toy_dst tmp = tc_alloc_tmp(tc);
763
 
764
   assert(!"SAD untested");
765
 
766
   tc_ADD(tc, tmp, src[0], tsrc_negate(src[1]));
767
   tc_ADD(tc, dst[0], tsrc_absolute(tsrc_from(tmp)), src[2]);
768
}
769
 
770
static void
771
aos_CONT(struct toy_compiler *tc,
772
         const struct tgsi_full_instruction *tgsi_inst,
773
         struct toy_dst *dst,
774
         struct toy_src *src)
775
{
776
   tc_add0(tc, BRW_OPCODE_CONTINUE);
777
}
778
 
779
static void
780
aos_BGNLOOP(struct toy_compiler *tc,
781
            const struct tgsi_full_instruction *tgsi_inst,
782
            struct toy_dst *dst,
783
            struct toy_src *src)
784
{
785
   struct toy_inst *inst;
786
 
787
   inst = tc_add0(tc, BRW_OPCODE_DO);
788
   /* this is just a marker */
789
   inst->marker = true;
790
}
791
 
792
static void
793
aos_ENDLOOP(struct toy_compiler *tc,
794
            const struct tgsi_full_instruction *tgsi_inst,
795
            struct toy_dst *dst,
796
            struct toy_src *src)
797
{
798
   tc_add0(tc, BRW_OPCODE_WHILE);
799
}
800
 
801
static void
802
aos_NRM4(struct toy_compiler *tc,
803
         const struct tgsi_full_instruction *tgsi_inst,
804
         struct toy_dst *dst,
805
         struct toy_src *src)
806
{
807
   struct toy_dst tmp = tc_alloc_tmp(tc);
808
 
809
   assert(!"NRM4 untested");
810
 
811
   tc_DP4(tc, tmp, src[0], src[0]);
812
   tc_INV(tc, tmp, tsrc_from(tmp));
813
   tc_MUL(tc, dst[0], tsrc_swizzle1(src[0], TOY_SWIZZLE_X), tsrc_from(tmp));
814
}
815
 
816
static void
817
aos_unsupported(struct toy_compiler *tc,
818
                const struct tgsi_full_instruction *tgsi_inst,
819
                struct toy_dst *dst,
820
                struct toy_src *src)
821
{
822
   const char *name = tgsi_get_opcode_name(tgsi_inst->Instruction.Opcode);
823
 
824
   ilo_warn("unsupported TGSI opcode: TGSI_OPCODE_%s\n", name);
825
 
826
   tc_fail(tc, "unsupported TGSI instruction");
827
}
828
 
829
static const toy_tgsi_translate aos_translate_table[TGSI_OPCODE_LAST] = {
830
   [TGSI_OPCODE_ARL]          = aos_simple,
831
   [TGSI_OPCODE_MOV]          = aos_simple,
832
   [TGSI_OPCODE_LIT]          = aos_LIT,
833
   [TGSI_OPCODE_RCP]          = aos_simple,
834
   [TGSI_OPCODE_RSQ]          = aos_simple,
835
   [TGSI_OPCODE_EXP]          = aos_EXP,
836
   [TGSI_OPCODE_LOG]          = aos_LOG,
837
   [TGSI_OPCODE_MUL]          = aos_simple,
838
   [TGSI_OPCODE_ADD]          = aos_simple,
839
   [TGSI_OPCODE_DP3]          = aos_simple,
840
   [TGSI_OPCODE_DP4]          = aos_simple,
841
   [TGSI_OPCODE_DST]          = aos_DST,
842
   [TGSI_OPCODE_MIN]          = aos_simple,
843
   [TGSI_OPCODE_MAX]          = aos_simple,
844
   [TGSI_OPCODE_SLT]          = aos_set_on_cond,
845
   [TGSI_OPCODE_SGE]          = aos_set_on_cond,
846
   [TGSI_OPCODE_MAD]          = aos_simple,
847
   [TGSI_OPCODE_SUB]          = aos_simple,
848
   [TGSI_OPCODE_LRP]          = aos_LRP,
849
   [TGSI_OPCODE_CND]          = aos_CND,
850
   [TGSI_OPCODE_SQRT]         = aos_simple,
851
   [TGSI_OPCODE_DP2A]         = aos_DP2A,
852
   [22]                       = aos_unsupported,
853
   [23]                       = aos_unsupported,
854
   [TGSI_OPCODE_FRC]          = aos_simple,
855
   [TGSI_OPCODE_CLAMP]        = aos_CLAMP,
856
   [TGSI_OPCODE_FLR]          = aos_simple,
857
   [TGSI_OPCODE_ROUND]        = aos_simple,
858
   [TGSI_OPCODE_EX2]          = aos_simple,
859
   [TGSI_OPCODE_LG2]          = aos_simple,
860
   [TGSI_OPCODE_POW]          = aos_simple,
861
   [TGSI_OPCODE_XPD]          = aos_XPD,
862
   [32]                       = aos_unsupported,
863
   [TGSI_OPCODE_ABS]          = aos_simple,
864
   [TGSI_OPCODE_RCC]          = aos_unsupported,
865
   [TGSI_OPCODE_DPH]          = aos_simple,
866
   [TGSI_OPCODE_COS]          = aos_simple,
867
   [TGSI_OPCODE_DDX]          = aos_unsupported,
868
   [TGSI_OPCODE_DDY]          = aos_unsupported,
869
   [TGSI_OPCODE_KILL]         = aos_simple,
870
   [TGSI_OPCODE_PK2H]         = aos_PK2H,
871
   [TGSI_OPCODE_PK2US]        = aos_unsupported,
872
   [TGSI_OPCODE_PK4B]         = aos_unsupported,
873
   [TGSI_OPCODE_PK4UB]        = aos_unsupported,
874
   [TGSI_OPCODE_RFL]          = aos_unsupported,
875
   [TGSI_OPCODE_SEQ]          = aos_set_on_cond,
876
   [TGSI_OPCODE_SFL]          = aos_SFL,
877
   [TGSI_OPCODE_SGT]          = aos_set_on_cond,
878
   [TGSI_OPCODE_SIN]          = aos_simple,
879
   [TGSI_OPCODE_SLE]          = aos_set_on_cond,
880
   [TGSI_OPCODE_SNE]          = aos_set_on_cond,
881
   [TGSI_OPCODE_STR]          = aos_STR,
882
   [TGSI_OPCODE_TEX]          = aos_tex,
883
   [TGSI_OPCODE_TXD]          = aos_tex,
884
   [TGSI_OPCODE_TXP]          = aos_tex,
885
   [TGSI_OPCODE_UP2H]         = aos_UP2H,
886
   [TGSI_OPCODE_UP2US]        = aos_unsupported,
887
   [TGSI_OPCODE_UP4B]         = aos_unsupported,
888
   [TGSI_OPCODE_UP4UB]        = aos_unsupported,
889
   [TGSI_OPCODE_X2D]          = aos_unsupported,
890
   [TGSI_OPCODE_ARA]          = aos_unsupported,
891
   [TGSI_OPCODE_ARR]          = aos_simple,
892
   [TGSI_OPCODE_BRA]          = aos_unsupported,
893
   [TGSI_OPCODE_CAL]          = aos_unsupported,
894
   [TGSI_OPCODE_RET]          = aos_unsupported,
895
   [TGSI_OPCODE_SSG]          = aos_set_sign,
896
   [TGSI_OPCODE_CMP]          = aos_compare,
897
   [TGSI_OPCODE_SCS]          = aos_SCS,
898
   [TGSI_OPCODE_TXB]          = aos_tex,
899
   [TGSI_OPCODE_NRM]          = aos_NRM,
900
   [TGSI_OPCODE_DIV]          = aos_DIV,
901
   [TGSI_OPCODE_DP2]          = aos_simple,
902
   [TGSI_OPCODE_TXL]          = aos_tex,
903
   [TGSI_OPCODE_BRK]          = aos_BRK,
904
   [TGSI_OPCODE_IF]           = aos_simple,
905
   [TGSI_OPCODE_UIF]          = aos_simple,
906
   [76]                       = aos_unsupported,
907
   [TGSI_OPCODE_ELSE]         = aos_simple,
908
   [TGSI_OPCODE_ENDIF]        = aos_simple,
909
   [79]                       = aos_unsupported,
910
   [80]                       = aos_unsupported,
911
   [TGSI_OPCODE_PUSHA]        = aos_unsupported,
912
   [TGSI_OPCODE_POPA]         = aos_unsupported,
913
   [TGSI_OPCODE_CEIL]         = aos_CEIL,
914
   [TGSI_OPCODE_I2F]          = aos_simple,
915
   [TGSI_OPCODE_NOT]          = aos_simple,
916
   [TGSI_OPCODE_TRUNC]        = aos_simple,
917
   [TGSI_OPCODE_SHL]          = aos_simple,
918
   [88]                       = aos_unsupported,
919
   [TGSI_OPCODE_AND]          = aos_simple,
920
   [TGSI_OPCODE_OR]           = aos_simple,
921
   [TGSI_OPCODE_MOD]          = aos_simple,
922
   [TGSI_OPCODE_XOR]          = aos_simple,
923
   [TGSI_OPCODE_SAD]          = aos_SAD,
924
   [TGSI_OPCODE_TXF]          = aos_tex,
925
   [TGSI_OPCODE_TXQ]          = aos_tex,
926
   [TGSI_OPCODE_CONT]         = aos_CONT,
927
   [TGSI_OPCODE_EMIT]         = aos_simple,
928
   [TGSI_OPCODE_ENDPRIM]      = aos_simple,
929
   [TGSI_OPCODE_BGNLOOP]      = aos_BGNLOOP,
930
   [TGSI_OPCODE_BGNSUB]       = aos_unsupported,
931
   [TGSI_OPCODE_ENDLOOP]      = aos_ENDLOOP,
932
   [TGSI_OPCODE_ENDSUB]       = aos_unsupported,
933
   [TGSI_OPCODE_TXQ_LZ]       = aos_tex,
934
   [104]                      = aos_unsupported,
935
   [105]                      = aos_unsupported,
936
   [106]                      = aos_unsupported,
937
   [TGSI_OPCODE_NOP]          = aos_simple,
938
   [108]                      = aos_unsupported,
939
   [109]                      = aos_unsupported,
940
   [110]                      = aos_unsupported,
941
   [111]                      = aos_unsupported,
942
   [TGSI_OPCODE_NRM4]         = aos_NRM4,
943
   [TGSI_OPCODE_CALLNZ]       = aos_unsupported,
944
   [TGSI_OPCODE_BREAKC]       = aos_unsupported,
945
   [TGSI_OPCODE_KILL_IF]      = aos_simple,
946
   [TGSI_OPCODE_END]          = aos_simple,
947
   [118]                      = aos_unsupported,
948
   [TGSI_OPCODE_F2I]          = aos_simple,
949
   [TGSI_OPCODE_IDIV]         = aos_simple,
950
   [TGSI_OPCODE_IMAX]         = aos_simple,
951
   [TGSI_OPCODE_IMIN]         = aos_simple,
952
   [TGSI_OPCODE_INEG]         = aos_simple,
953
   [TGSI_OPCODE_ISGE]         = aos_set_on_cond,
954
   [TGSI_OPCODE_ISHR]         = aos_simple,
955
   [TGSI_OPCODE_ISLT]         = aos_set_on_cond,
956
   [TGSI_OPCODE_F2U]          = aos_simple,
957
   [TGSI_OPCODE_U2F]          = aos_simple,
958
   [TGSI_OPCODE_UADD]         = aos_simple,
959
   [TGSI_OPCODE_UDIV]         = aos_simple,
960
   [TGSI_OPCODE_UMAD]         = aos_simple,
961
   [TGSI_OPCODE_UMAX]         = aos_simple,
962
   [TGSI_OPCODE_UMIN]         = aos_simple,
963
   [TGSI_OPCODE_UMOD]         = aos_simple,
964
   [TGSI_OPCODE_UMUL]         = aos_simple,
965
   [TGSI_OPCODE_USEQ]         = aos_set_on_cond,
966
   [TGSI_OPCODE_USGE]         = aos_set_on_cond,
967
   [TGSI_OPCODE_USHR]         = aos_simple,
968
   [TGSI_OPCODE_USLT]         = aos_set_on_cond,
969
   [TGSI_OPCODE_USNE]         = aos_set_on_cond,
970
   [TGSI_OPCODE_SWITCH]       = aos_unsupported,
971
   [TGSI_OPCODE_CASE]         = aos_unsupported,
972
   [TGSI_OPCODE_DEFAULT]      = aos_unsupported,
973
   [TGSI_OPCODE_ENDSWITCH]    = aos_unsupported,
974
   [TGSI_OPCODE_SAMPLE]       = aos_sample,
975
   [TGSI_OPCODE_SAMPLE_I]     = aos_sample,
976
   [TGSI_OPCODE_SAMPLE_I_MS]  = aos_sample,
977
   [TGSI_OPCODE_SAMPLE_B]     = aos_sample,
978
   [TGSI_OPCODE_SAMPLE_C]     = aos_sample,
979
   [TGSI_OPCODE_SAMPLE_C_LZ]  = aos_sample,
980
   [TGSI_OPCODE_SAMPLE_D]     = aos_sample,
981
   [TGSI_OPCODE_SAMPLE_L]     = aos_sample,
982
   [TGSI_OPCODE_GATHER4]      = aos_sample,
983
   [TGSI_OPCODE_SVIEWINFO]    = aos_sample,
984
   [TGSI_OPCODE_SAMPLE_POS]   = aos_sample,
985
   [TGSI_OPCODE_SAMPLE_INFO]  = aos_sample,
986
   [TGSI_OPCODE_UARL]         = aos_simple,
987
   [TGSI_OPCODE_UCMP]         = aos_compare,
988
   [TGSI_OPCODE_IABS]         = aos_simple,
989
   [TGSI_OPCODE_ISSG]         = aos_set_sign,
990
   [TGSI_OPCODE_LOAD]         = aos_unsupported,
991
   [TGSI_OPCODE_STORE]        = aos_unsupported,
992
   [TGSI_OPCODE_MFENCE]       = aos_unsupported,
993
   [TGSI_OPCODE_LFENCE]       = aos_unsupported,
994
   [TGSI_OPCODE_SFENCE]       = aos_unsupported,
995
   [TGSI_OPCODE_BARRIER]      = aos_unsupported,
996
   [TGSI_OPCODE_ATOMUADD]     = aos_unsupported,
997
   [TGSI_OPCODE_ATOMXCHG]     = aos_unsupported,
998
   [TGSI_OPCODE_ATOMCAS]      = aos_unsupported,
999
   [TGSI_OPCODE_ATOMAND]      = aos_unsupported,
1000
   [TGSI_OPCODE_ATOMOR]       = aos_unsupported,
1001
   [TGSI_OPCODE_ATOMXOR]      = aos_unsupported,
1002
   [TGSI_OPCODE_ATOMUMIN]     = aos_unsupported,
1003
   [TGSI_OPCODE_ATOMUMAX]     = aos_unsupported,
1004
   [TGSI_OPCODE_ATOMIMIN]     = aos_unsupported,
1005
   [TGSI_OPCODE_ATOMIMAX]     = aos_unsupported,
1006
   [TGSI_OPCODE_TEX2]         = aos_tex,
1007
   [TGSI_OPCODE_TXB2]         = aos_tex,
1008
   [TGSI_OPCODE_TXL2]         = aos_tex,
1009
};
1010
 
1011
static void
1012
soa_passthrough(struct toy_compiler *tc,
1013
                const struct tgsi_full_instruction *tgsi_inst,
1014
                struct toy_dst *dst_,
1015
                struct toy_src *src_)
1016
{
1017
   const toy_tgsi_translate translate =
1018
      aos_translate_table[tgsi_inst->Instruction.Opcode];
1019
 
1020
   translate(tc, tgsi_inst, dst_, src_);
1021
}
1022
 
1023
static void
1024
soa_per_channel(struct toy_compiler *tc,
1025
                const struct tgsi_full_instruction *tgsi_inst,
1026
                struct toy_dst *dst_,
1027
                struct toy_src *src_)
1028
{
1029
   struct toy_dst dst[TGSI_FULL_MAX_DST_REGISTERS][4];
1030
   struct toy_src src[TGSI_FULL_MAX_SRC_REGISTERS][4];
1031
   int i, ch;
1032
 
1033
   for (i = 0; i < tgsi_inst->Instruction.NumDstRegs; i++)
1034
      tdst_transpose(dst_[i], dst[i]);
1035
   for (i = 0; i < tgsi_inst->Instruction.NumSrcRegs; i++)
1036
      tsrc_transpose(src_[i], src[i]);
1037
 
1038
   /* emit the same instruction four times for the four channels */
1039
   for (ch = 0; ch < 4; ch++) {
1040
      struct toy_dst aos_dst[TGSI_FULL_MAX_DST_REGISTERS];
1041
      struct toy_src aos_src[TGSI_FULL_MAX_SRC_REGISTERS];
1042
 
1043
      for (i = 0; i < tgsi_inst->Instruction.NumDstRegs; i++)
1044
         aos_dst[i] = dst[i][ch];
1045
      for (i = 0; i < tgsi_inst->Instruction.NumSrcRegs; i++)
1046
         aos_src[i] = src[i][ch];
1047
 
1048
      aos_translate_table[tgsi_inst->Instruction.Opcode](tc,
1049
            tgsi_inst, aos_dst, aos_src);
1050
   }
1051
}
1052
 
1053
static void
1054
soa_scalar_replicate(struct toy_compiler *tc,
1055
                     const struct tgsi_full_instruction *tgsi_inst,
1056
                     struct toy_dst *dst_,
1057
                     struct toy_src *src_)
1058
{
1059
   struct toy_dst dst0[4], tmp;
1060
   struct toy_src srcx[TGSI_FULL_MAX_SRC_REGISTERS];
1061
   int opcode, i;
1062
 
1063
   assert(tgsi_inst->Instruction.NumDstRegs == 1);
1064
 
1065
   tdst_transpose(dst_[0], dst0);
1066
   for (i = 0; i < tgsi_inst->Instruction.NumSrcRegs; i++) {
1067
      struct toy_src tmp[4];
1068
 
1069
      tsrc_transpose(src_[i], tmp);
1070
      /* only the X channels */
1071
      srcx[i] = tmp[0];
1072
   }
1073
 
1074
   tmp = tc_alloc_tmp(tc);
1075
 
1076
   opcode = aos_simple_opcode_map[tgsi_inst->Instruction.Opcode].opcode;
1077
   assert(opcode);
1078
 
1079
   switch (tgsi_inst->Instruction.Opcode) {
1080
   case TGSI_OPCODE_RCP:
1081
   case TGSI_OPCODE_RSQ:
1082
   case TGSI_OPCODE_SQRT:
1083
   case TGSI_OPCODE_EX2:
1084
   case TGSI_OPCODE_LG2:
1085
   case TGSI_OPCODE_COS:
1086
   case TGSI_OPCODE_SIN:
1087
      tc_add1(tc, opcode, tmp, srcx[0]);
1088
      break;
1089
   case TGSI_OPCODE_POW:
1090
      tc_add2(tc, opcode, tmp, srcx[0], srcx[1]);
1091
      break;
1092
   default:
1093
      assert(!"invalid soa_scalar_replicate() call");
1094
      return;
1095
   }
1096
 
1097
   /* replicate the result */
1098
   for (i = 0; i < 4; i++)
1099
      tc_MOV(tc, dst0[i], tsrc_from(tmp));
1100
}
1101
 
1102
static void
1103
soa_dot_product(struct toy_compiler *tc,
1104
                const struct tgsi_full_instruction *tgsi_inst,
1105
                struct toy_dst *dst_,
1106
                struct toy_src *src_)
1107
{
1108
   struct toy_dst dst0[4], tmp;
1109
   struct toy_src src[TGSI_FULL_MAX_SRC_REGISTERS][4];
1110
   int i;
1111
 
1112
   tdst_transpose(dst_[0], dst0);
1113
   for (i = 0; i < tgsi_inst->Instruction.NumSrcRegs; i++)
1114
      tsrc_transpose(src_[i], src[i]);
1115
 
1116
   tmp = tc_alloc_tmp(tc);
1117
 
1118
   switch (tgsi_inst->Instruction.Opcode) {
1119
   case TGSI_OPCODE_DP2:
1120
      tc_MUL(tc, tmp, src[0][1], src[1][1]);
1121
      tc_MAC(tc, tmp, src[0][0], src[1][0], tsrc_from(tmp));
1122
      break;
1123
   case TGSI_OPCODE_DP2A:
1124
      tc_MAC(tc, tmp, src[0][1], src[1][1], src[2][0]);
1125
      tc_MAC(tc, tmp, src[0][0], src[1][0], tsrc_from(tmp));
1126
      break;
1127
   case TGSI_OPCODE_DP3:
1128
      tc_MUL(tc, tmp, src[0][2], src[1][2]);
1129
      tc_MAC(tc, tmp, src[0][1], src[1][1], tsrc_from(tmp));
1130
      tc_MAC(tc, tmp, src[0][0], src[1][0], tsrc_from(tmp));
1131
      break;
1132
   case TGSI_OPCODE_DPH:
1133
      tc_MAC(tc, tmp, src[0][2], src[1][2], src[1][3]);
1134
      tc_MAC(tc, tmp, src[0][1], src[1][1], tsrc_from(tmp));
1135
      tc_MAC(tc, tmp, src[0][0], src[1][0], tsrc_from(tmp));
1136
      break;
1137
   case TGSI_OPCODE_DP4:
1138
      tc_MUL(tc, tmp, src[0][3], src[1][3]);
1139
      tc_MAC(tc, tmp, src[0][2], src[1][2], tsrc_from(tmp));
1140
      tc_MAC(tc, tmp, src[0][1], src[1][1], tsrc_from(tmp));
1141
      tc_MAC(tc, tmp, src[0][0], src[1][0], tsrc_from(tmp));
1142
      break;
1143
   default:
1144
      assert(!"invalid soa_dot_product() call");
1145
      return;
1146
   }
1147
 
1148
   for (i = 0; i < 4; i++)
1149
      tc_MOV(tc, dst0[i], tsrc_from(tmp));
1150
}
1151
 
1152
static void
1153
soa_partial_derivative(struct toy_compiler *tc,
1154
                       const struct tgsi_full_instruction *tgsi_inst,
1155
                       struct toy_dst *dst_,
1156
                       struct toy_src *src_)
1157
{
1158
   if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_DDX)
1159
      tc_add1(tc, TOY_OPCODE_DDX, dst_[0], src_[0]);
1160
   else
1161
      tc_add1(tc, TOY_OPCODE_DDY, dst_[0], src_[0]);
1162
}
1163
 
1164
static void
1165
soa_if(struct toy_compiler *tc,
1166
       const struct tgsi_full_instruction *tgsi_inst,
1167
       struct toy_dst *dst_,
1168
       struct toy_src *src_)
1169
{
1170
   struct toy_src src0[4];
1171
 
1172
   assert(tsrc_is_swizzle1(src_[0]));
1173
   tsrc_transpose(src_[0], src0);
1174
 
1175
   if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_IF)
1176
      tc_IF(tc, tdst_null(), src0[0], tsrc_imm_f(0.0f), BRW_CONDITIONAL_NEQ);
1177
   else
1178
      tc_IF(tc, tdst_null(), src0[0], tsrc_imm_d(0), BRW_CONDITIONAL_NEQ);
1179
}
1180
 
1181
static void
1182
soa_LIT(struct toy_compiler *tc,
1183
        const struct tgsi_full_instruction *tgsi_inst,
1184
        struct toy_dst *dst_,
1185
        struct toy_src *src_)
1186
{
1187
   struct toy_inst *inst;
1188
   struct toy_dst dst0[4];
1189
   struct toy_src src0[4];
1190
 
1191
   tdst_transpose(dst_[0], dst0);
1192
   tsrc_transpose(src_[0], src0);
1193
 
1194
   tc_MOV(tc, dst0[0], tsrc_imm_f(1.0f));
1195
   tc_MOV(tc, dst0[1], src0[0]);
1196
   tc_POW(tc, dst0[2], src0[1], src0[3]);
1197
   tc_MOV(tc, dst0[3], tsrc_imm_f(1.0f));
1198
 
1199
   /*
1200
    * POW is calculated first because math with pred_ctrl is broken here.
1201
    * But, why?
1202
    */
1203
   tc_CMP(tc, tdst_null(), src0[0], tsrc_imm_f(0.0f), BRW_CONDITIONAL_L);
1204
   inst = tc_MOV(tc, dst0[1], tsrc_imm_f(0.0f));
1205
   inst->pred_ctrl = BRW_PREDICATE_NORMAL;
1206
   inst = tc_MOV(tc, dst0[2], tsrc_imm_f(0.0f));
1207
   inst->pred_ctrl = BRW_PREDICATE_NORMAL;
1208
}
1209
 
1210
static void
1211
soa_EXP(struct toy_compiler *tc,
1212
        const struct tgsi_full_instruction *tgsi_inst,
1213
        struct toy_dst *dst_,
1214
        struct toy_src *src_)
1215
{
1216
   struct toy_dst dst0[4];
1217
   struct toy_src src0[4];
1218
 
1219
   assert(!"SoA EXP untested");
1220
 
1221
   tdst_transpose(dst_[0], dst0);
1222
   tsrc_transpose(src_[0], src0);
1223
 
1224
   if (!tdst_is_null(dst0[0])) {
1225
      struct toy_dst tmp = tdst_d(tc_alloc_tmp(tc));
1226
 
1227
      tc_RNDD(tc, tmp, src0[0]);
1228
 
1229
      /* construct the floating point number manually */
1230
      tc_ADD(tc, tmp, tsrc_from(tmp), tsrc_imm_d(127));
1231
      tc_SHL(tc, tdst_d(dst0[0]), tsrc_from(tmp), tsrc_imm_d(23));
1232
   }
1233
 
1234
   tc_FRC(tc, dst0[1], src0[0]);
1235
   tc_EXP(tc, dst0[2], src0[0]);
1236
   tc_MOV(tc, dst0[3], tsrc_imm_f(1.0f));
1237
}
1238
 
1239
static void
1240
soa_LOG(struct toy_compiler *tc,
1241
        const struct tgsi_full_instruction *tgsi_inst,
1242
        struct toy_dst *dst_,
1243
        struct toy_src *src_)
1244
{
1245
   struct toy_dst dst0[4];
1246
   struct toy_src src0[4];
1247
 
1248
   assert(!"SoA LOG untested");
1249
 
1250
   tdst_transpose(dst_[0], dst0);
1251
   tsrc_transpose(src_[0], src0);
1252
 
1253
   if (dst_[0].writemask & TOY_WRITEMASK_XY) {
1254
      struct toy_dst tmp = tdst_d(tc_alloc_tmp(tc));
1255
 
1256
      /* exponent */
1257
      tc_SHR(tc, tmp, tsrc_absolute(tsrc_d(src0[0])), tsrc_imm_d(23));
1258
      tc_ADD(tc, dst0[0], tsrc_from(tmp), tsrc_imm_d(-127));
1259
 
1260
      /* mantissa  */
1261
      tc_AND(tc, tmp, tsrc_d(src0[0]), tsrc_imm_d((1 << 23) - 1));
1262
      tc_OR(tc, dst0[1], tsrc_from(tmp), tsrc_imm_d(127 << 23));
1263
   }
1264
 
1265
   tc_LOG(tc, dst0[2], src0[0]);
1266
   tc_MOV(tc, dst0[3], tsrc_imm_f(1.0f));
1267
}
1268
 
1269
static void
1270
soa_DST(struct toy_compiler *tc,
1271
        const struct tgsi_full_instruction *tgsi_inst,
1272
        struct toy_dst *dst_,
1273
        struct toy_src *src_)
1274
{
1275
   struct toy_dst dst0[4];
1276
   struct toy_src src[2][4];
1277
 
1278
   tdst_transpose(dst_[0], dst0);
1279
   tsrc_transpose(src_[0], src[0]);
1280
   tsrc_transpose(src_[1], src[1]);
1281
 
1282
   tc_MOV(tc, dst0[0], tsrc_imm_f(1.0f));
1283
   tc_MUL(tc, dst0[1], src[0][1], src[1][1]);
1284
   tc_MOV(tc, dst0[2], src[0][2]);
1285
   tc_MOV(tc, dst0[3], src[1][3]);
1286
}
1287
 
1288
static void
1289
soa_XPD(struct toy_compiler *tc,
1290
        const struct tgsi_full_instruction *tgsi_inst,
1291
        struct toy_dst *dst_,
1292
        struct toy_src *src_)
1293
{
1294
   struct toy_dst dst0[4];
1295
   struct toy_src src[2][4];
1296
 
1297
   tdst_transpose(dst_[0], dst0);
1298
   tsrc_transpose(src_[0], src[0]);
1299
   tsrc_transpose(src_[1], src[1]);
1300
 
1301
   /* dst.x = src0.y * src1.z - src1.y * src0.z */
1302
   tc_MUL(tc, dst0[0], src[0][2], src[1][1]);
1303
   tc_MAC(tc, dst0[0], src[0][1], src[1][2], tsrc_negate(tsrc_from(dst0[0])));
1304
 
1305
   /* dst.y = src0.z * src1.x - src1.z * src0.x */
1306
   tc_MUL(tc, dst0[1], src[0][0], src[1][2]);
1307
   tc_MAC(tc, dst0[1], src[0][2], src[1][0], tsrc_negate(tsrc_from(dst0[1])));
1308
 
1309
   /* dst.z = src0.x * src1.y - src1.x * src0.y */
1310
   tc_MUL(tc, dst0[2], src[0][1], src[1][0]);
1311
   tc_MAC(tc, dst0[2], src[0][0], src[1][1], tsrc_negate(tsrc_from(dst0[2])));
1312
 
1313
   tc_MOV(tc, dst0[3], tsrc_imm_f(1.0f));
1314
}
1315
 
1316
static void
1317
soa_PK2H(struct toy_compiler *tc,
1318
         const struct tgsi_full_instruction *tgsi_inst,
1319
         struct toy_dst *dst_,
1320
         struct toy_src *src_)
1321
{
1322
   struct toy_dst tmp = tdst_ud(tc_alloc_tmp(tc));
1323
   struct toy_dst dst0[4];
1324
   struct toy_src src0[4];
1325
   int i;
1326
 
1327
   assert(!"SoA PK2H untested");
1328
 
1329
   tdst_transpose(dst_[0], dst0);
1330
   tsrc_transpose(src_[0], src0);
1331
 
1332
   tc_SHL(tc, tmp, src0[1], tsrc_imm_ud(16));
1333
   tc_OR(tc, tmp, src0[0], tsrc_from(tmp));
1334
 
1335
   for (i = 0; i < 4; i++)
1336
      tc_MOV(tc, dst0[i], tsrc_from(tmp));
1337
}
1338
 
1339
static void
1340
soa_UP2H(struct toy_compiler *tc,
1341
         const struct tgsi_full_instruction *tgsi_inst,
1342
         struct toy_dst *dst_,
1343
         struct toy_src *src_)
1344
{
1345
   struct toy_dst dst0[4];
1346
   struct toy_src src0[4];
1347
 
1348
   assert(!"SoA UP2H untested");
1349
 
1350
   tdst_transpose(dst_[0], dst0);
1351
   tsrc_transpose(src_[0], src0);
1352
 
1353
   tc_AND(tc, tdst_ud(dst0[0]), tsrc_ud(src0[0]), tsrc_imm_ud(0xffff));
1354
   tc_SHR(tc, tdst_ud(dst0[1]), tsrc_ud(src0[1]), tsrc_imm_ud(16));
1355
   tc_AND(tc, tdst_ud(dst0[2]), tsrc_ud(src0[2]), tsrc_imm_ud(0xffff));
1356
   tc_SHR(tc, tdst_ud(dst0[3]), tsrc_ud(src0[3]), tsrc_imm_ud(16));
1357
 
1358
}
1359
 
1360
static void
1361
soa_SCS(struct toy_compiler *tc,
1362
        const struct tgsi_full_instruction *tgsi_inst,
1363
        struct toy_dst *dst_,
1364
        struct toy_src *src_)
1365
{
1366
   struct toy_dst dst0[4];
1367
   struct toy_src src0[4];
1368
 
1369
   tdst_transpose(dst_[0], dst0);
1370
   tsrc_transpose(src_[0], src0);
1371
 
1372
   tc_add1(tc, TOY_OPCODE_COS, dst0[0], src0[0]);
1373
   tc_add1(tc, TOY_OPCODE_SIN, dst0[1], src0[0]);
1374
   tc_MOV(tc, dst0[2], tsrc_imm_f(0.0f));
1375
   tc_MOV(tc, dst0[3], tsrc_imm_f(1.0f));
1376
}
1377
 
1378
static void
1379
soa_NRM(struct toy_compiler *tc,
1380
        const struct tgsi_full_instruction *tgsi_inst,
1381
        struct toy_dst *dst_,
1382
        struct toy_src *src_)
1383
{
1384
   const struct toy_dst tmp = tc_alloc_tmp(tc);
1385
   struct toy_dst dst0[4];
1386
   struct toy_src src0[4];
1387
 
1388
   assert(!"SoA NRM untested");
1389
 
1390
   tdst_transpose(dst_[0], dst0);
1391
   tsrc_transpose(src_[0], src0);
1392
 
1393
   tc_MUL(tc, tmp, src0[2], src0[2]);
1394
   tc_MAC(tc, tmp, src0[1], src0[1], tsrc_from(tmp));
1395
   tc_MAC(tc, tmp, src0[0], src0[0], tsrc_from(tmp));
1396
   tc_INV(tc, tmp, tsrc_from(tmp));
1397
 
1398
   tc_MUL(tc, dst0[0], src0[0], tsrc_from(tmp));
1399
   tc_MUL(tc, dst0[1], src0[1], tsrc_from(tmp));
1400
   tc_MUL(tc, dst0[2], src0[2], tsrc_from(tmp));
1401
   tc_MOV(tc, dst0[3], tsrc_imm_f(1.0f));
1402
}
1403
 
1404
static void
1405
soa_NRM4(struct toy_compiler *tc,
1406
         const struct tgsi_full_instruction *tgsi_inst,
1407
         struct toy_dst *dst_,
1408
         struct toy_src *src_)
1409
{
1410
   const struct toy_dst tmp = tc_alloc_tmp(tc);
1411
   struct toy_dst dst0[4];
1412
   struct toy_src src0[4];
1413
   int i;
1414
 
1415
   assert(!"SoA NRM4 untested");
1416
 
1417
   tdst_transpose(dst_[0], dst0);
1418
   tsrc_transpose(src_[0], src0);
1419
 
1420
   tc_MUL(tc, tmp, src0[3], src0[3]);
1421
   tc_MAC(tc, tmp, src0[2], src0[2], tsrc_from(tmp));
1422
   tc_MAC(tc, tmp, src0[1], src0[1], tsrc_from(tmp));
1423
   tc_MAC(tc, tmp, src0[0], src0[0], tsrc_from(tmp));
1424
   tc_INV(tc, tmp, tsrc_from(tmp));
1425
 
1426
   for (i = 0; i < 4; i++)
1427
      tc_MUL(tc, dst0[i], src0[0], tsrc_from(tmp));
1428
}
1429
 
1430
static void
1431
soa_unsupported(struct toy_compiler *tc,
1432
                const struct tgsi_full_instruction *tgsi_inst,
1433
                struct toy_dst *dst_,
1434
                struct toy_src *src_)
1435
{
1436
   const struct tgsi_opcode_info *info =
1437
      tgsi_get_opcode_info(tgsi_inst->Instruction.Opcode);
1438
 
1439
   ilo_warn("unsupported TGSI opcode in SoA form: TGSI_OPCODE_%s\n",
1440
         info->mnemonic);
1441
 
1442
   tc_fail(tc, "unsupported TGSI instruction in SoA form");
1443
}
1444
 
1445
static const toy_tgsi_translate soa_translate_table[TGSI_OPCODE_LAST] = {
1446
   [TGSI_OPCODE_ARL]          = soa_per_channel,
1447
   [TGSI_OPCODE_MOV]          = soa_per_channel,
1448
   [TGSI_OPCODE_LIT]          = soa_LIT,
1449
   [TGSI_OPCODE_RCP]          = soa_scalar_replicate,
1450
   [TGSI_OPCODE_RSQ]          = soa_scalar_replicate,
1451
   [TGSI_OPCODE_EXP]          = soa_EXP,
1452
   [TGSI_OPCODE_LOG]          = soa_LOG,
1453
   [TGSI_OPCODE_MUL]          = soa_per_channel,
1454
   [TGSI_OPCODE_ADD]          = soa_per_channel,
1455
   [TGSI_OPCODE_DP3]          = soa_dot_product,
1456
   [TGSI_OPCODE_DP4]          = soa_dot_product,
1457
   [TGSI_OPCODE_DST]          = soa_DST,
1458
   [TGSI_OPCODE_MIN]          = soa_per_channel,
1459
   [TGSI_OPCODE_MAX]          = soa_per_channel,
1460
   [TGSI_OPCODE_SLT]          = soa_per_channel,
1461
   [TGSI_OPCODE_SGE]          = soa_per_channel,
1462
   [TGSI_OPCODE_MAD]          = soa_per_channel,
1463
   [TGSI_OPCODE_SUB]          = soa_per_channel,
1464
   [TGSI_OPCODE_LRP]          = soa_per_channel,
1465
   [TGSI_OPCODE_CND]          = soa_per_channel,
1466
   [TGSI_OPCODE_SQRT]         = soa_scalar_replicate,
1467
   [TGSI_OPCODE_DP2A]         = soa_dot_product,
1468
   [22]                       = soa_unsupported,
1469
   [23]                       = soa_unsupported,
1470
   [TGSI_OPCODE_FRC]          = soa_per_channel,
1471
   [TGSI_OPCODE_CLAMP]        = soa_per_channel,
1472
   [TGSI_OPCODE_FLR]          = soa_per_channel,
1473
   [TGSI_OPCODE_ROUND]        = soa_per_channel,
1474
   [TGSI_OPCODE_EX2]          = soa_scalar_replicate,
1475
   [TGSI_OPCODE_LG2]          = soa_scalar_replicate,
1476
   [TGSI_OPCODE_POW]          = soa_scalar_replicate,
1477
   [TGSI_OPCODE_XPD]          = soa_XPD,
1478
   [32]                       = soa_unsupported,
1479
   [TGSI_OPCODE_ABS]          = soa_per_channel,
1480
   [TGSI_OPCODE_RCC]          = soa_unsupported,
1481
   [TGSI_OPCODE_DPH]          = soa_dot_product,
1482
   [TGSI_OPCODE_COS]          = soa_scalar_replicate,
1483
   [TGSI_OPCODE_DDX]          = soa_partial_derivative,
1484
   [TGSI_OPCODE_DDY]          = soa_partial_derivative,
1485
   [TGSI_OPCODE_KILL]         = soa_passthrough,
1486
   [TGSI_OPCODE_PK2H]         = soa_PK2H,
1487
   [TGSI_OPCODE_PK2US]        = soa_unsupported,
1488
   [TGSI_OPCODE_PK4B]         = soa_unsupported,
1489
   [TGSI_OPCODE_PK4UB]        = soa_unsupported,
1490
   [TGSI_OPCODE_RFL]          = soa_unsupported,
1491
   [TGSI_OPCODE_SEQ]          = soa_per_channel,
1492
   [TGSI_OPCODE_SFL]          = soa_per_channel,
1493
   [TGSI_OPCODE_SGT]          = soa_per_channel,
1494
   [TGSI_OPCODE_SIN]          = soa_scalar_replicate,
1495
   [TGSI_OPCODE_SLE]          = soa_per_channel,
1496
   [TGSI_OPCODE_SNE]          = soa_per_channel,
1497
   [TGSI_OPCODE_STR]          = soa_per_channel,
1498
   [TGSI_OPCODE_TEX]          = soa_passthrough,
1499
   [TGSI_OPCODE_TXD]          = soa_passthrough,
1500
   [TGSI_OPCODE_TXP]          = soa_passthrough,
1501
   [TGSI_OPCODE_UP2H]         = soa_UP2H,
1502
   [TGSI_OPCODE_UP2US]        = soa_unsupported,
1503
   [TGSI_OPCODE_UP4B]         = soa_unsupported,
1504
   [TGSI_OPCODE_UP4UB]        = soa_unsupported,
1505
   [TGSI_OPCODE_X2D]          = soa_unsupported,
1506
   [TGSI_OPCODE_ARA]          = soa_unsupported,
1507
   [TGSI_OPCODE_ARR]          = soa_per_channel,
1508
   [TGSI_OPCODE_BRA]          = soa_unsupported,
1509
   [TGSI_OPCODE_CAL]          = soa_unsupported,
1510
   [TGSI_OPCODE_RET]          = soa_unsupported,
1511
   [TGSI_OPCODE_SSG]          = soa_per_channel,
1512
   [TGSI_OPCODE_CMP]          = soa_per_channel,
1513
   [TGSI_OPCODE_SCS]          = soa_SCS,
1514
   [TGSI_OPCODE_TXB]          = soa_passthrough,
1515
   [TGSI_OPCODE_NRM]          = soa_NRM,
1516
   [TGSI_OPCODE_DIV]          = soa_per_channel,
1517
   [TGSI_OPCODE_DP2]          = soa_dot_product,
1518
   [TGSI_OPCODE_TXL]          = soa_passthrough,
1519
   [TGSI_OPCODE_BRK]          = soa_passthrough,
1520
   [TGSI_OPCODE_IF]           = soa_if,
1521
   [TGSI_OPCODE_UIF]          = soa_if,
1522
   [76]                       = soa_unsupported,
1523
   [TGSI_OPCODE_ELSE]         = soa_passthrough,
1524
   [TGSI_OPCODE_ENDIF]        = soa_passthrough,
1525
   [79]                       = soa_unsupported,
1526
   [80]                       = soa_unsupported,
1527
   [TGSI_OPCODE_PUSHA]        = soa_unsupported,
1528
   [TGSI_OPCODE_POPA]         = soa_unsupported,
1529
   [TGSI_OPCODE_CEIL]         = soa_per_channel,
1530
   [TGSI_OPCODE_I2F]          = soa_per_channel,
1531
   [TGSI_OPCODE_NOT]          = soa_per_channel,
1532
   [TGSI_OPCODE_TRUNC]        = soa_per_channel,
1533
   [TGSI_OPCODE_SHL]          = soa_per_channel,
1534
   [88]                       = soa_unsupported,
1535
   [TGSI_OPCODE_AND]          = soa_per_channel,
1536
   [TGSI_OPCODE_OR]           = soa_per_channel,
1537
   [TGSI_OPCODE_MOD]          = soa_per_channel,
1538
   [TGSI_OPCODE_XOR]          = soa_per_channel,
1539
   [TGSI_OPCODE_SAD]          = soa_per_channel,
1540
   [TGSI_OPCODE_TXF]          = soa_passthrough,
1541
   [TGSI_OPCODE_TXQ]          = soa_passthrough,
1542
   [TGSI_OPCODE_CONT]         = soa_passthrough,
1543
   [TGSI_OPCODE_EMIT]         = soa_unsupported,
1544
   [TGSI_OPCODE_ENDPRIM]      = soa_unsupported,
1545
   [TGSI_OPCODE_BGNLOOP]      = soa_passthrough,
1546
   [TGSI_OPCODE_BGNSUB]       = soa_unsupported,
1547
   [TGSI_OPCODE_ENDLOOP]      = soa_passthrough,
1548
   [TGSI_OPCODE_ENDSUB]       = soa_unsupported,
1549
   [TGSI_OPCODE_TXQ_LZ]       = soa_passthrough,
1550
   [104]                      = soa_unsupported,
1551
   [105]                      = soa_unsupported,
1552
   [106]                      = soa_unsupported,
1553
   [TGSI_OPCODE_NOP]          = soa_passthrough,
1554
   [108]                      = soa_unsupported,
1555
   [109]                      = soa_unsupported,
1556
   [110]                      = soa_unsupported,
1557
   [111]                      = soa_unsupported,
1558
   [TGSI_OPCODE_NRM4]         = soa_NRM4,
1559
   [TGSI_OPCODE_CALLNZ]       = soa_unsupported,
1560
   [TGSI_OPCODE_BREAKC]       = soa_unsupported,
1561
   [TGSI_OPCODE_KILL_IF]          = soa_passthrough,
1562
   [TGSI_OPCODE_END]          = soa_passthrough,
1563
   [118]                      = soa_unsupported,
1564
   [TGSI_OPCODE_F2I]          = soa_per_channel,
1565
   [TGSI_OPCODE_IDIV]         = soa_per_channel,
1566
   [TGSI_OPCODE_IMAX]         = soa_per_channel,
1567
   [TGSI_OPCODE_IMIN]         = soa_per_channel,
1568
   [TGSI_OPCODE_INEG]         = soa_per_channel,
1569
   [TGSI_OPCODE_ISGE]         = soa_per_channel,
1570
   [TGSI_OPCODE_ISHR]         = soa_per_channel,
1571
   [TGSI_OPCODE_ISLT]         = soa_per_channel,
1572
   [TGSI_OPCODE_F2U]          = soa_per_channel,
1573
   [TGSI_OPCODE_U2F]          = soa_per_channel,
1574
   [TGSI_OPCODE_UADD]         = soa_per_channel,
1575
   [TGSI_OPCODE_UDIV]         = soa_per_channel,
1576
   [TGSI_OPCODE_UMAD]         = soa_per_channel,
1577
   [TGSI_OPCODE_UMAX]         = soa_per_channel,
1578
   [TGSI_OPCODE_UMIN]         = soa_per_channel,
1579
   [TGSI_OPCODE_UMOD]         = soa_per_channel,
1580
   [TGSI_OPCODE_UMUL]         = soa_per_channel,
1581
   [TGSI_OPCODE_USEQ]         = soa_per_channel,
1582
   [TGSI_OPCODE_USGE]         = soa_per_channel,
1583
   [TGSI_OPCODE_USHR]         = soa_per_channel,
1584
   [TGSI_OPCODE_USLT]         = soa_per_channel,
1585
   [TGSI_OPCODE_USNE]         = soa_per_channel,
1586
   [TGSI_OPCODE_SWITCH]       = soa_unsupported,
1587
   [TGSI_OPCODE_CASE]         = soa_unsupported,
1588
   [TGSI_OPCODE_DEFAULT]      = soa_unsupported,
1589
   [TGSI_OPCODE_ENDSWITCH]    = soa_unsupported,
1590
   [TGSI_OPCODE_SAMPLE]       = soa_passthrough,
1591
   [TGSI_OPCODE_SAMPLE_I]     = soa_passthrough,
1592
   [TGSI_OPCODE_SAMPLE_I_MS]  = soa_passthrough,
1593
   [TGSI_OPCODE_SAMPLE_B]     = soa_passthrough,
1594
   [TGSI_OPCODE_SAMPLE_C]     = soa_passthrough,
1595
   [TGSI_OPCODE_SAMPLE_C_LZ]  = soa_passthrough,
1596
   [TGSI_OPCODE_SAMPLE_D]     = soa_passthrough,
1597
   [TGSI_OPCODE_SAMPLE_L]     = soa_passthrough,
1598
   [TGSI_OPCODE_GATHER4]      = soa_passthrough,
1599
   [TGSI_OPCODE_SVIEWINFO]    = soa_passthrough,
1600
   [TGSI_OPCODE_SAMPLE_POS]   = soa_passthrough,
1601
   [TGSI_OPCODE_SAMPLE_INFO]  = soa_passthrough,
1602
   [TGSI_OPCODE_UARL]         = soa_per_channel,
1603
   [TGSI_OPCODE_UCMP]         = soa_per_channel,
1604
   [TGSI_OPCODE_IABS]         = soa_per_channel,
1605
   [TGSI_OPCODE_ISSG]         = soa_per_channel,
1606
   [TGSI_OPCODE_LOAD]         = soa_unsupported,
1607
   [TGSI_OPCODE_STORE]        = soa_unsupported,
1608
   [TGSI_OPCODE_MFENCE]       = soa_unsupported,
1609
   [TGSI_OPCODE_LFENCE]       = soa_unsupported,
1610
   [TGSI_OPCODE_SFENCE]       = soa_unsupported,
1611
   [TGSI_OPCODE_BARRIER]      = soa_unsupported,
1612
   [TGSI_OPCODE_ATOMUADD]     = soa_unsupported,
1613
   [TGSI_OPCODE_ATOMXCHG]     = soa_unsupported,
1614
   [TGSI_OPCODE_ATOMCAS]      = soa_unsupported,
1615
   [TGSI_OPCODE_ATOMAND]      = soa_unsupported,
1616
   [TGSI_OPCODE_ATOMOR]       = soa_unsupported,
1617
   [TGSI_OPCODE_ATOMXOR]      = soa_unsupported,
1618
   [TGSI_OPCODE_ATOMUMIN]     = soa_unsupported,
1619
   [TGSI_OPCODE_ATOMUMAX]     = soa_unsupported,
1620
   [TGSI_OPCODE_ATOMIMIN]     = soa_unsupported,
1621
   [TGSI_OPCODE_ATOMIMAX]     = soa_unsupported,
1622
   [TGSI_OPCODE_TEX2]         = soa_passthrough,
1623
   [TGSI_OPCODE_TXB2]         = soa_passthrough,
1624
   [TGSI_OPCODE_TXL2]         = soa_passthrough,
1625
};
1626
 
1627
static bool
1628
ra_dst_is_indirect(const struct tgsi_full_dst_register *d)
1629
{
1630
   return (d->Register.Indirect ||
1631
         (d->Register.Dimension && d->Dimension.Indirect));
1632
}
1633
 
1634
static int
1635
ra_dst_index(const struct tgsi_full_dst_register *d)
1636
{
1637
   assert(!d->Register.Indirect);
1638
   return d->Register.Index;
1639
}
1640
 
1641
static int
1642
ra_dst_dimension(const struct tgsi_full_dst_register *d)
1643
{
1644
   if (d->Register.Dimension) {
1645
      assert(!d->Dimension.Indirect);
1646
      return d->Dimension.Index;
1647
   }
1648
   else {
1649
      return 0;
1650
   }
1651
}
1652
 
1653
static bool
1654
ra_is_src_indirect(const struct tgsi_full_src_register *s)
1655
{
1656
   return (s->Register.Indirect ||
1657
         (s->Register.Dimension && s->Dimension.Indirect));
1658
}
1659
 
1660
static int
1661
ra_src_index(const struct tgsi_full_src_register *s)
1662
{
1663
   assert(!s->Register.Indirect);
1664
   return s->Register.Index;
1665
}
1666
 
1667
static int
1668
ra_src_dimension(const struct tgsi_full_src_register *s)
1669
{
1670
   if (s->Register.Dimension) {
1671
      assert(!s->Dimension.Indirect);
1672
      return s->Dimension.Index;
1673
   }
1674
   else {
1675
      return 0;
1676
   }
1677
}
1678
 
1679
/**
1680
 * Infer the type of either the sources or the destination.
1681
 */
1682
static enum toy_type
1683
ra_infer_opcode_type(int tgsi_opcode, bool is_dst)
1684
{
1685
   enum tgsi_opcode_type type;
1686
 
1687
   if (is_dst)
1688
      type = tgsi_opcode_infer_dst_type(tgsi_opcode);
1689
   else
1690
      type = tgsi_opcode_infer_src_type(tgsi_opcode);
1691
 
1692
   switch (type) {
1693
   case TGSI_TYPE_UNSIGNED:
1694
      return TOY_TYPE_UD;
1695
   case TGSI_TYPE_SIGNED:
1696
      return TOY_TYPE_D;
1697
   case TGSI_TYPE_FLOAT:
1698
      return TOY_TYPE_F;
1699
   case TGSI_TYPE_UNTYPED:
1700
   case TGSI_TYPE_VOID:
1701
   case TGSI_TYPE_DOUBLE:
1702
   default:
1703
      assert(!"unsupported TGSI type");
1704
      return TOY_TYPE_UD;
1705
   }
1706
}
1707
 
1708
/**
1709
 * Return the type of an operand of the specified instruction.
1710
 */
1711
static enum toy_type
1712
ra_get_type(struct toy_tgsi *tgsi, const struct tgsi_full_instruction *tgsi_inst,
1713
            int operand, bool is_dst)
1714
{
1715
   enum toy_type type;
1716
   enum tgsi_file_type file;
1717
 
1718
   /* we need to look at both src and dst for MOV */
1719
   /* XXX it should not be this complex */
1720
   if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_MOV) {
1721
      const enum tgsi_file_type dst_file = tgsi_inst->Dst[0].Register.File;
1722
      const enum tgsi_file_type src_file = tgsi_inst->Src[0].Register.File;
1723
 
1724
      if (dst_file == TGSI_FILE_ADDRESS || src_file == TGSI_FILE_ADDRESS) {
1725
         type = TOY_TYPE_D;
1726
      }
1727
      else if (src_file == TGSI_FILE_IMMEDIATE &&
1728
               !tgsi_inst->Src[0].Register.Indirect) {
1729
         const int src_idx = tgsi_inst->Src[0].Register.Index;
1730
         type = tgsi->imm_data.types[src_idx];
1731
      }
1732
      else {
1733
         /* this is the best we can do */
1734
         type = TOY_TYPE_F;
1735
      }
1736
 
1737
      return type;
1738
   }
1739
   else if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_UCMP) {
1740
      if (!is_dst && operand == 0)
1741
         type = TOY_TYPE_UD;
1742
      else
1743
         type = TOY_TYPE_F;
1744
 
1745
      return type;
1746
   }
1747
 
1748
   type = ra_infer_opcode_type(tgsi_inst->Instruction.Opcode, is_dst);
1749
 
1750
   /* fix the type */
1751
   file = (is_dst) ?
1752
      tgsi_inst->Dst[operand].Register.File :
1753
      tgsi_inst->Src[operand].Register.File;
1754
   switch (file) {
1755
   case TGSI_FILE_SAMPLER:
1756
   case TGSI_FILE_RESOURCE:
1757
   case TGSI_FILE_SAMPLER_VIEW:
1758
      type = TOY_TYPE_D;
1759
      break;
1760
   case TGSI_FILE_ADDRESS:
1761
      assert(type == TOY_TYPE_D);
1762
      break;
1763
   default:
1764
      break;
1765
   }
1766
 
1767
   return type;
1768
}
1769
 
1770
/**
1771
 * Allocate a VRF register.
1772
 */
1773
static int
1774
ra_alloc_reg(struct toy_tgsi *tgsi, enum tgsi_file_type file)
1775
{
1776
   const int count = (tgsi->aos) ? 1 : 4;
1777
   return tc_alloc_vrf(tgsi->tc, count);
1778
}
1779
 
1780
/**
1781
 * Construct the key for VRF mapping look-up.
1782
 */
1783
static void *
1784
ra_get_map_key(enum tgsi_file_type file, unsigned dim, unsigned index)
1785
{
1786
   intptr_t key;
1787
 
1788
   /* this is ugly... */
1789
   assert(file  < 1 << 4);
1790
   assert(dim   < 1 << 12);
1791
   assert(index < 1 << 16);
1792
   key = (file << 28) | (dim << 16) | index;
1793
 
1794
   return intptr_to_pointer(key);
1795
}
1796
 
1797
/**
1798
 * Map a TGSI register to a VRF register.
1799
 */
1800
static int
1801
ra_map_reg(struct toy_tgsi *tgsi, enum tgsi_file_type file,
1802
           int dim, int index, bool *is_new)
1803
{
1804
   void *key, *val;
1805
   intptr_t vrf;
1806
 
1807
   key = ra_get_map_key(file, dim, index);
1808
 
1809
   /*
1810
    * because we allocate vrf from 1 and on, val is never NULL as long as the
1811
    * key exists
1812
    */
1813
   val = util_hash_table_get(tgsi->reg_mapping, key);
1814
   if (val) {
1815
      vrf = pointer_to_intptr(val);
1816
 
1817
      if (is_new)
1818
         *is_new = false;
1819
   }
1820
   else {
1821
      vrf = (intptr_t) ra_alloc_reg(tgsi, file);
1822
 
1823
      /* add to the mapping */
1824
      val = intptr_to_pointer(vrf);
1825
      util_hash_table_set(tgsi->reg_mapping, key, val);
1826
 
1827
      if (is_new)
1828
         *is_new = true;
1829
   }
1830
 
1831
   return (int) vrf;
1832
}
1833
 
1834
/**
1835
 * Return true if the destination aliases any of the sources.
1836
 */
1837
static bool
1838
ra_dst_is_aliasing(const struct tgsi_full_instruction *tgsi_inst, int dst_index)
1839
{
1840
   const struct tgsi_full_dst_register *d = &tgsi_inst->Dst[dst_index];
1841
   int i;
1842
 
1843
   /* we need a scratch register for indirect dst anyway */
1844
   if (ra_dst_is_indirect(d))
1845
      return true;
1846
 
1847
   for (i = 0; i < tgsi_inst->Instruction.NumSrcRegs; i++) {
1848
      const struct tgsi_full_src_register *s = &tgsi_inst->Src[i];
1849
 
1850
      if (s->Register.File != d->Register.File)
1851
         continue;
1852
 
1853
      /*
1854
       * we can go on to check dimension and index respectively, but
1855
       * keep it simple for now
1856
       */
1857
      if (ra_is_src_indirect(s))
1858
         return true;
1859
      if (ra_src_dimension(s) == ra_dst_dimension(d) &&
1860
          ra_src_index(s) == ra_dst_index(d))
1861
         return true;
1862
   }
1863
 
1864
   return false;
1865
}
1866
 
1867
/**
1868
 * Return the toy register for a TGSI destination operand.
1869
 */
1870
static struct toy_dst
1871
ra_get_dst(struct toy_tgsi *tgsi,
1872
           const struct tgsi_full_instruction *tgsi_inst, int dst_index,
1873
           bool *is_scratch)
1874
{
1875
   const struct tgsi_full_dst_register *d = &tgsi_inst->Dst[dst_index];
1876
   bool need_vrf = false;
1877
   struct toy_dst dst;
1878
 
1879
   switch (d->Register.File) {
1880
   case TGSI_FILE_NULL:
1881
      dst = tdst_null();
1882
      break;
1883
   case TGSI_FILE_OUTPUT:
1884
   case TGSI_FILE_TEMPORARY:
1885
   case TGSI_FILE_ADDRESS:
1886
   case TGSI_FILE_PREDICATE:
1887
      need_vrf = true;
1888
      break;
1889
   default:
1890
      assert(!"unhandled dst file");
1891
      dst = tdst_null();
1892
      break;
1893
   }
1894
 
1895
   if (need_vrf) {
1896
      /* XXX we do not always need a scratch given the conditions... */
1897
      const bool need_scratch =
1898
         (ra_dst_is_indirect(d) || ra_dst_is_aliasing(tgsi_inst, dst_index) ||
1899
          tgsi_inst->Instruction.Saturate);
1900
      const enum toy_type type = ra_get_type(tgsi, tgsi_inst, dst_index, true);
1901
      int vrf;
1902
 
1903
      if (need_scratch) {
1904
         vrf = ra_alloc_reg(tgsi, d->Register.File);
1905
      }
1906
      else {
1907
         vrf = ra_map_reg(tgsi, d->Register.File,
1908
               ra_dst_dimension(d), ra_dst_index(d), NULL);
1909
      }
1910
 
1911
      if (is_scratch)
1912
         *is_scratch = need_scratch;
1913
 
1914
      dst = tdst_full(TOY_FILE_VRF, type, TOY_RECT_LINEAR,
1915
            false, 0, d->Register.WriteMask, vrf * TOY_REG_WIDTH);
1916
   }
1917
 
1918
   return dst;
1919
}
1920
 
1921
static struct toy_src
1922
ra_get_src_for_vrf(const struct tgsi_full_src_register *s,
1923
                   enum toy_type type, int vrf)
1924
{
1925
   return tsrc_full(TOY_FILE_VRF, type, TOY_RECT_LINEAR,
1926
                    false, 0,
1927
                    s->Register.SwizzleX, s->Register.SwizzleY,
1928
                    s->Register.SwizzleZ, s->Register.SwizzleW,
1929
                    s->Register.Absolute, s->Register.Negate,
1930
                    vrf * TOY_REG_WIDTH);
1931
}
1932
 
1933
static int
1934
init_tgsi_reg(struct toy_tgsi *tgsi, struct toy_inst *inst,
1935
              enum tgsi_file_type file, int index,
1936
              const struct tgsi_ind_register *indirect,
1937
              const struct tgsi_dimension *dimension,
1938
              const struct tgsi_ind_register *dim_indirect)
1939
{
1940
   struct toy_src src;
1941
   int num_src = 0;
1942
 
1943
   /* src[0]: TGSI file */
1944
   inst->src[num_src++] = tsrc_imm_d(file);
1945
 
1946
   /* src[1]: TGSI dimension */
1947
   inst->src[num_src++] = tsrc_imm_d((dimension) ? dimension->Index : 0);
1948
 
1949
   /* src[2]: TGSI dimension indirection */
1950
   if (dim_indirect) {
1951
      const int vrf = ra_map_reg(tgsi, dim_indirect->File, 0,
1952
            dim_indirect->Index, NULL);
1953
 
1954
      src = tsrc(TOY_FILE_VRF, vrf, 0);
1955
      src = tsrc_swizzle1(tsrc_d(src), indirect->Swizzle);
1956
   }
1957
   else {
1958
      src = tsrc_imm_d(0);
1959
   }
1960
 
1961
   inst->src[num_src++] = src;
1962
 
1963
   /* src[3]: TGSI index */
1964
   inst->src[num_src++] = tsrc_imm_d(index);
1965
 
1966
   /* src[4]: TGSI index indirection */
1967
   if (indirect) {
1968
      const int vrf = ra_map_reg(tgsi, indirect->File, 0,
1969
            indirect->Index, NULL);
1970
 
1971
      src = tsrc(TOY_FILE_VRF, vrf, 0);
1972
      src = tsrc_swizzle1(tsrc_d(src), indirect->Swizzle);
1973
   }
1974
   else {
1975
      src = tsrc_imm_d(0);
1976
   }
1977
 
1978
   inst->src[num_src++] = src;
1979
 
1980
   return num_src;
1981
}
1982
 
1983
static struct toy_src
1984
ra_get_src_indirect(struct toy_tgsi *tgsi,
1985
                    const struct tgsi_full_instruction *tgsi_inst,
1986
                    int src_index)
1987
{
1988
   const struct tgsi_full_src_register *s = &tgsi_inst->Src[src_index];
1989
   bool need_vrf = false, is_resource = false;
1990
   struct toy_src src;
1991
 
1992
   switch (s->Register.File) {
1993
   case TGSI_FILE_NULL:
1994
      src = tsrc_null();
1995
      break;
1996
   case TGSI_FILE_SAMPLER:
1997
   case TGSI_FILE_RESOURCE:
1998
   case TGSI_FILE_SAMPLER_VIEW:
1999
      is_resource = true;
2000
      /* fall through */
2001
   case TGSI_FILE_CONSTANT:
2002
   case TGSI_FILE_INPUT:
2003
   case TGSI_FILE_SYSTEM_VALUE:
2004
   case TGSI_FILE_TEMPORARY:
2005
   case TGSI_FILE_ADDRESS:
2006
   case TGSI_FILE_IMMEDIATE:
2007
   case TGSI_FILE_PREDICATE:
2008
      need_vrf = true;
2009
      break;
2010
   default:
2011
      assert(!"unhandled src file");
2012
      src = tsrc_null();
2013
      break;
2014
   }
2015
 
2016
   if (need_vrf) {
2017
      const enum toy_type type = ra_get_type(tgsi, tgsi_inst, src_index, false);
2018
      int vrf;
2019
 
2020
      if (is_resource) {
2021
         assert(!s->Register.Dimension);
2022
         assert(s->Register.Indirect);
2023
 
2024
         vrf = ra_map_reg(tgsi, s->Indirect.File, 0, s->Indirect.Index, NULL);
2025
      }
2026
      else {
2027
         vrf = ra_alloc_reg(tgsi, s->Register.File);
2028
      }
2029
 
2030
      src = ra_get_src_for_vrf(s, type, vrf);
2031
 
2032
      /* emit indirect fetch */
2033
      if (!is_resource) {
2034
         struct toy_inst *inst;
2035
 
2036
         inst = tc_add(tgsi->tc);
2037
         inst->opcode = TOY_OPCODE_TGSI_INDIRECT_FETCH;
2038
         inst->dst = tdst_from(src);
2039
         inst->dst.writemask = TOY_WRITEMASK_XYZW;
2040
 
2041
         init_tgsi_reg(tgsi, inst, s->Register.File, s->Register.Index,
2042
               (s->Register.Indirect) ? &s->Indirect : NULL,
2043
               (s->Register.Dimension) ? &s->Dimension : NULL,
2044
               (s->Dimension.Indirect) ? &s->DimIndirect : NULL);
2045
      }
2046
   }
2047
 
2048
   return src;
2049
}
2050
 
2051
/**
2052
 * Return the toy register for a TGSI source operand.
2053
 */
2054
static struct toy_src
2055
ra_get_src(struct toy_tgsi *tgsi,
2056
           const struct tgsi_full_instruction *tgsi_inst,
2057
           int src_index)
2058
{
2059
   const struct tgsi_full_src_register *s = &tgsi_inst->Src[src_index];
2060
   bool need_vrf = false;
2061
   struct toy_src src;
2062
 
2063
   if (ra_is_src_indirect(s))
2064
      return ra_get_src_indirect(tgsi, tgsi_inst, src_index);
2065
 
2066
   switch (s->Register.File) {
2067
   case TGSI_FILE_NULL:
2068
      src = tsrc_null();
2069
      break;
2070
   case TGSI_FILE_CONSTANT:
2071
   case TGSI_FILE_INPUT:
2072
   case TGSI_FILE_SYSTEM_VALUE:
2073
      need_vrf = true;
2074
      break;
2075
   case TGSI_FILE_TEMPORARY:
2076
   case TGSI_FILE_ADDRESS:
2077
   case TGSI_FILE_PREDICATE:
2078
      need_vrf = true;
2079
      break;
2080
   case TGSI_FILE_SAMPLER:
2081
   case TGSI_FILE_RESOURCE:
2082
   case TGSI_FILE_SAMPLER_VIEW:
2083
      assert(!s->Register.Dimension);
2084
      src = tsrc_imm_d(s->Register.Index);
2085
      break;
2086
   case TGSI_FILE_IMMEDIATE:
2087
      {
2088
         const uint32_t *imm;
2089
         enum toy_type imm_type;
2090
         bool is_scalar;
2091
 
2092
         imm = toy_tgsi_get_imm(tgsi, s->Register.Index, &imm_type);
2093
 
2094
         is_scalar =
2095
            (imm[s->Register.SwizzleX] == imm[s->Register.SwizzleY] &&
2096
             imm[s->Register.SwizzleX] == imm[s->Register.SwizzleZ] &&
2097
             imm[s->Register.SwizzleX] == imm[s->Register.SwizzleW]);
2098
 
2099
         if (is_scalar) {
2100
            const enum toy_type type =
2101
               ra_get_type(tgsi, tgsi_inst, src_index, false);
2102
 
2103
            /* ignore imm_type */
2104
            src = tsrc_imm_ud(imm[s->Register.SwizzleX]);
2105
            src.type = type;
2106
            src.absolute = s->Register.Absolute;
2107
            src.negate = s->Register.Negate;
2108
         }
2109
         else {
2110
            need_vrf = true;
2111
         }
2112
      }
2113
      break;
2114
   default:
2115
      assert(!"unhandled src file");
2116
      src = tsrc_null();
2117
      break;
2118
   }
2119
 
2120
   if (need_vrf) {
2121
      const enum toy_type type = ra_get_type(tgsi, tgsi_inst, src_index, false);
2122
      bool is_new;
2123
      int vrf;
2124
 
2125
      vrf = ra_map_reg(tgsi, s->Register.File,
2126
            ra_src_dimension(s), ra_src_index(s), &is_new);
2127
 
2128
      src = ra_get_src_for_vrf(s, type, vrf);
2129
 
2130
      if (is_new) {
2131
         switch (s->Register.File) {
2132
         case TGSI_FILE_TEMPORARY:
2133
         case TGSI_FILE_ADDRESS:
2134
         case TGSI_FILE_PREDICATE:
2135
            {
2136
               struct toy_dst dst = tdst_from(src);
2137
               dst.writemask = TOY_WRITEMASK_XYZW;
2138
 
2139
               /* always initialize registers before use */
2140
               if (tgsi->aos) {
2141
                  tc_MOV(tgsi->tc, dst, tsrc_type(tsrc_imm_d(0), type));
2142
               }
2143
               else {
2144
                  struct toy_dst tdst[4];
2145
                  int i;
2146
 
2147
                  tdst_transpose(dst, tdst);
2148
 
2149
                  for (i = 0; i < 4; i++) {
2150
                     tc_MOV(tgsi->tc, tdst[i],
2151
                           tsrc_type(tsrc_imm_d(0), type));
2152
                  }
2153
               }
2154
            }
2155
            break;
2156
         default:
2157
            break;
2158
         }
2159
      }
2160
 
2161
   }
2162
 
2163
   return src;
2164
}
2165
 
2166
static void
2167
parse_instruction(struct toy_tgsi *tgsi,
2168
                  const struct tgsi_full_instruction *tgsi_inst)
2169
{
2170
   struct toy_dst dst[TGSI_FULL_MAX_DST_REGISTERS];
2171
   struct toy_src src[TGSI_FULL_MAX_SRC_REGISTERS];
2172
   bool dst_is_scratch[TGSI_FULL_MAX_DST_REGISTERS];
2173
   toy_tgsi_translate translate;
2174
   int i;
2175
 
2176
   /* convert TGSI registers to toy registers */
2177
   for (i = 0; i < tgsi_inst->Instruction.NumSrcRegs; i++)
2178
      src[i] = ra_get_src(tgsi, tgsi_inst, i);
2179
   for (i = 0; i < tgsi_inst->Instruction.NumDstRegs; i++)
2180
      dst[i] = ra_get_dst(tgsi, tgsi_inst, i, &dst_is_scratch[i]);
2181
 
2182
   /* translate the instruction */
2183
   translate = tgsi->translate_table[tgsi_inst->Instruction.Opcode];
2184
   translate(tgsi->tc, tgsi_inst, dst, src);
2185
 
2186
   /* write the result to the real destinations if needed */
2187
   for (i = 0; i < tgsi_inst->Instruction.NumDstRegs; i++) {
2188
      const struct tgsi_full_dst_register *d = &tgsi_inst->Dst[i];
2189
 
2190
      if (!dst_is_scratch[i])
2191
         continue;
2192
 
2193
      if (tgsi_inst->Instruction.Saturate == TGSI_SAT_MINUS_PLUS_ONE)
2194
         tc_fail(tgsi->tc, "TGSI_SAT_MINUS_PLUS_ONE unhandled");
2195
 
2196
      tgsi->tc->templ.saturate = tgsi_inst->Instruction.Saturate;
2197
 
2198
      /* emit indirect store */
2199
      if (ra_dst_is_indirect(d)) {
2200
         struct toy_inst *inst;
2201
 
2202
         inst = tc_add(tgsi->tc);
2203
         inst->opcode = TOY_OPCODE_TGSI_INDIRECT_STORE;
2204
         inst->dst = dst[i];
2205
 
2206
         init_tgsi_reg(tgsi, inst, d->Register.File, d->Register.Index,
2207
               (d->Register.Indirect) ? &d->Indirect : NULL,
2208
               (d->Register.Dimension) ? &d->Dimension : NULL,
2209
               (d->Dimension.Indirect) ? &d->DimIndirect : NULL);
2210
      }
2211
      else {
2212
         const enum toy_type type = ra_get_type(tgsi, tgsi_inst, i, true);
2213
         struct toy_dst real_dst;
2214
         int vrf;
2215
 
2216
         vrf = ra_map_reg(tgsi, d->Register.File,
2217
               ra_dst_dimension(d), ra_dst_index(d), NULL);
2218
         real_dst = tdst_full(TOY_FILE_VRF, type, TOY_RECT_LINEAR,
2219
               false, 0, d->Register.WriteMask, vrf * TOY_REG_WIDTH);
2220
 
2221
         if (tgsi->aos) {
2222
            tc_MOV(tgsi->tc, real_dst, tsrc_from(dst[i]));
2223
         }
2224
         else {
2225
            struct toy_dst tdst[4];
2226
            struct toy_src tsrc[4];
2227
            int j;
2228
 
2229
            tdst_transpose(real_dst, tdst);
2230
            tsrc_transpose(tsrc_from(dst[i]), tsrc);
2231
 
2232
            for (j = 0; j < 4; j++)
2233
               tc_MOV(tgsi->tc, tdst[j], tsrc[j]);
2234
         }
2235
      }
2236
 
2237
      tgsi->tc->templ.saturate = false;
2238
   }
2239
 
2240
   switch (tgsi_inst->Instruction.Opcode) {
2241
   case TGSI_OPCODE_KILL_IF:
2242
   case TGSI_OPCODE_KILL:
2243
      tgsi->uses_kill = true;
2244
      break;
2245
   }
2246
 
2247
   /* remember channels written */
2248
   for (i = 0; i < tgsi_inst->Instruction.NumDstRegs; i++) {
2249
      const struct tgsi_full_dst_register *d = &tgsi_inst->Dst[i];
2250
 
2251
      if (d->Register.File != TGSI_FILE_OUTPUT)
2252
         continue;
2253
      for (i = 0; i < tgsi->num_outputs; i++) {
2254
         if (tgsi->outputs[i].index == d->Register.Index) {
2255
            tgsi->outputs[i].undefined_mask &= ~d->Register.WriteMask;
2256
            break;
2257
         }
2258
      }
2259
   }
2260
}
2261
 
2262
static void
2263
decl_add_in(struct toy_tgsi *tgsi, const struct tgsi_full_declaration *decl)
2264
{
2265
   static const struct tgsi_declaration_interp default_interp = {
2266
      TGSI_INTERPOLATE_PERSPECTIVE, false, 0,
2267
   };
2268
   const struct tgsi_declaration_interp *interp =
2269
      (decl->Declaration.Interpolate) ? &decl->Interp: &default_interp;
2270
   int index;
2271
 
2272
   if (decl->Range.Last >= Elements(tgsi->inputs)) {
2273
      assert(!"invalid IN");
2274
      return;
2275
   }
2276
 
2277
   for (index = decl->Range.First; index <= decl->Range.Last; index++) {
2278
      const int slot = tgsi->num_inputs++;
2279
 
2280
      tgsi->inputs[slot].index = index;
2281
      tgsi->inputs[slot].usage_mask = decl->Declaration.UsageMask;
2282
      if (decl->Declaration.Semantic) {
2283
         tgsi->inputs[slot].semantic_name = decl->Semantic.Name;
2284
         tgsi->inputs[slot].semantic_index = decl->Semantic.Index;
2285
      }
2286
      else {
2287
         tgsi->inputs[slot].semantic_name = TGSI_SEMANTIC_GENERIC;
2288
         tgsi->inputs[slot].semantic_index = index;
2289
      }
2290
      tgsi->inputs[slot].interp = interp->Interpolate;
2291
      tgsi->inputs[slot].centroid = interp->Centroid;
2292
   }
2293
}
2294
 
2295
static void
2296
decl_add_out(struct toy_tgsi *tgsi, const struct tgsi_full_declaration *decl)
2297
{
2298
   int index;
2299
 
2300
   if (decl->Range.Last >= Elements(tgsi->outputs)) {
2301
      assert(!"invalid OUT");
2302
      return;
2303
   }
2304
 
2305
   assert(decl->Declaration.Semantic);
2306
 
2307
   for (index = decl->Range.First; index <= decl->Range.Last; index++) {
2308
      const int slot = tgsi->num_outputs++;
2309
 
2310
      tgsi->outputs[slot].index = index;
2311
      tgsi->outputs[slot].undefined_mask = TOY_WRITEMASK_XYZW;
2312
      tgsi->outputs[slot].usage_mask = decl->Declaration.UsageMask;
2313
      tgsi->outputs[slot].semantic_name = decl->Semantic.Name;
2314
      tgsi->outputs[slot].semantic_index = decl->Semantic.Index;
2315
   }
2316
}
2317
 
2318
static void
2319
decl_add_sv(struct toy_tgsi *tgsi, const struct tgsi_full_declaration *decl)
2320
{
2321
   int index;
2322
 
2323
   if (decl->Range.Last >= Elements(tgsi->system_values)) {
2324
      assert(!"invalid SV");
2325
      return;
2326
   }
2327
 
2328
   for (index = decl->Range.First; index <= decl->Range.Last; index++) {
2329
      const int slot = tgsi->num_system_values++;
2330
 
2331
      tgsi->system_values[slot].index = index;
2332
      if (decl->Declaration.Semantic) {
2333
         tgsi->system_values[slot].semantic_name = decl->Semantic.Name;
2334
         tgsi->system_values[slot].semantic_index = decl->Semantic.Index;
2335
      }
2336
      else {
2337
         tgsi->system_values[slot].semantic_name = TGSI_SEMANTIC_GENERIC;
2338
         tgsi->system_values[slot].semantic_index = index;
2339
      }
2340
   }
2341
}
2342
 
2343
/**
2344
 * Emit an instruction to fetch the value of a TGSI register.
2345
 */
2346
static void
2347
fetch_source(struct toy_tgsi *tgsi, enum tgsi_file_type file, int dim, int idx)
2348
{
2349
   struct toy_dst dst;
2350
   int vrf;
2351
   enum toy_opcode opcode;
2352
   enum toy_type type = TOY_TYPE_F;
2353
 
2354
   switch (file) {
2355
   case TGSI_FILE_INPUT:
2356
      opcode = TOY_OPCODE_TGSI_IN;
2357
      break;
2358
   case TGSI_FILE_CONSTANT:
2359
      opcode = TOY_OPCODE_TGSI_CONST;
2360
      break;
2361
   case TGSI_FILE_SYSTEM_VALUE:
2362
      opcode = TOY_OPCODE_TGSI_SV;
2363
      break;
2364
   case TGSI_FILE_IMMEDIATE:
2365
      opcode = TOY_OPCODE_TGSI_IMM;
2366
      toy_tgsi_get_imm(tgsi, idx, &type);
2367
      break;
2368
   default:
2369
      /* no need to fetch */
2370
      return;
2371
      break;
2372
   }
2373
 
2374
   vrf = ra_map_reg(tgsi, file, dim, idx, NULL);
2375
   dst = tdst(TOY_FILE_VRF, vrf, 0);
2376
   dst = tdst_type(dst, type);
2377
 
2378
   tc_add2(tgsi->tc, opcode, dst, tsrc_imm_d(dim), tsrc_imm_d(idx));
2379
}
2380
 
2381
static void
2382
parse_declaration(struct toy_tgsi *tgsi,
2383
                  const struct tgsi_full_declaration *decl)
2384
{
2385
   int i;
2386
 
2387
   switch (decl->Declaration.File) {
2388
   case TGSI_FILE_INPUT:
2389
      decl_add_in(tgsi, decl);
2390
      break;
2391
   case TGSI_FILE_OUTPUT:
2392
      decl_add_out(tgsi, decl);
2393
      break;
2394
   case TGSI_FILE_SYSTEM_VALUE:
2395
      decl_add_sv(tgsi, decl);
2396
      break;
2397
   case TGSI_FILE_IMMEDIATE:
2398
      /* immediates should be declared with TGSI_TOKEN_TYPE_IMMEDIATE */
2399
      assert(!"unexpected immediate declaration");
2400
      break;
2401
   case TGSI_FILE_NULL:
2402
   case TGSI_FILE_CONSTANT:
2403
   case TGSI_FILE_TEMPORARY:
2404
   case TGSI_FILE_SAMPLER:
2405
   case TGSI_FILE_PREDICATE:
2406
   case TGSI_FILE_ADDRESS:
2407
   case TGSI_FILE_RESOURCE:
2408
   case TGSI_FILE_SAMPLER_VIEW:
2409
      /* nothing to do */
2410
      break;
2411
   default:
2412
      assert(!"unhandled TGSI file");
2413
      break;
2414
   }
2415
 
2416
   /* fetch the registers now */
2417
   for (i = decl->Range.First; i <= decl->Range.Last; i++) {
2418
      const int dim = (decl->Declaration.Dimension) ? decl->Dim.Index2D : 0;
2419
      fetch_source(tgsi, decl->Declaration.File, dim, i);
2420
   }
2421
}
2422
 
2423
static int
2424
add_imm(struct toy_tgsi *tgsi, enum toy_type type, const uint32_t *buf)
2425
{
2426
   /* reallocate the buffer if necessary */
2427
   if (tgsi->imm_data.cur >= tgsi->imm_data.size) {
2428
      const int cur_size = tgsi->imm_data.size;
2429
      int new_size;
2430
      enum toy_type *new_types;
2431
      uint32_t (*new_buf)[4];
2432
 
2433
      new_size = (cur_size) ? cur_size << 1 : 16;
2434
      while (new_size <= tgsi->imm_data.cur)
2435
         new_size <<= 1;
2436
 
2437
      new_buf = REALLOC(tgsi->imm_data.buf,
2438
            cur_size * sizeof(new_buf[0]),
2439
            new_size * sizeof(new_buf[0]));
2440
      new_types = REALLOC(tgsi->imm_data.types,
2441
            cur_size * sizeof(new_types[0]),
2442
            new_size * sizeof(new_types[0]));
2443
      if (!new_buf || !new_types) {
2444
         if (new_buf)
2445
            FREE(new_buf);
2446
         if (new_types)
2447
            FREE(new_types);
2448
         return -1;
2449
      }
2450
 
2451
      tgsi->imm_data.buf = new_buf;
2452
      tgsi->imm_data.types = new_types;
2453
      tgsi->imm_data.size = new_size;
2454
   }
2455
 
2456
   tgsi->imm_data.types[tgsi->imm_data.cur] = type;
2457
   memcpy(&tgsi->imm_data.buf[tgsi->imm_data.cur],
2458
         buf, sizeof(tgsi->imm_data.buf[0]));
2459
 
2460
   return tgsi->imm_data.cur++;
2461
}
2462
 
2463
static void
2464
parse_immediate(struct toy_tgsi *tgsi, const struct tgsi_full_immediate *imm)
2465
{
2466
   enum toy_type type;
2467
   uint32_t imm_buf[4];
2468
   int idx;
2469
 
2470
   switch (imm->Immediate.DataType) {
2471
   case TGSI_IMM_FLOAT32:
2472
      type = TOY_TYPE_F;
2473
      imm_buf[0] = fui(imm->u[0].Float);
2474
      imm_buf[1] = fui(imm->u[1].Float);
2475
      imm_buf[2] = fui(imm->u[2].Float);
2476
      imm_buf[3] = fui(imm->u[3].Float);
2477
      break;
2478
   case TGSI_IMM_INT32:
2479
      type = TOY_TYPE_D;
2480
      imm_buf[0] = (uint32_t) imm->u[0].Int;
2481
      imm_buf[1] = (uint32_t) imm->u[1].Int;
2482
      imm_buf[2] = (uint32_t) imm->u[2].Int;
2483
      imm_buf[3] = (uint32_t) imm->u[3].Int;
2484
      break;
2485
   case TGSI_IMM_UINT32:
2486
      type = TOY_TYPE_UD;
2487
      imm_buf[0] = imm->u[0].Uint;
2488
      imm_buf[1] = imm->u[1].Uint;
2489
      imm_buf[2] = imm->u[2].Uint;
2490
      imm_buf[3] = imm->u[3].Uint;
2491
      break;
2492
   default:
2493
      assert(!"unhandled TGSI imm type");
2494
      type = TOY_TYPE_F;
2495
      memset(imm_buf, 0, sizeof(imm_buf));
2496
      break;
2497
   }
2498
 
2499
   idx = add_imm(tgsi, type, imm_buf);
2500
   if (idx >= 0)
2501
      fetch_source(tgsi, TGSI_FILE_IMMEDIATE, 0, idx);
2502
   else
2503
      tc_fail(tgsi->tc, "failed to add TGSI imm");
2504
}
2505
 
2506
static void
2507
parse_property(struct toy_tgsi *tgsi, const struct tgsi_full_property *prop)
2508
{
2509
   switch (prop->Property.PropertyName) {
2510
   case TGSI_PROPERTY_VS_PROHIBIT_UCPS:
2511
      tgsi->props.vs_prohibit_ucps = prop->u[0].Data;
2512
      break;
2513
   case TGSI_PROPERTY_FS_COORD_ORIGIN:
2514
      tgsi->props.fs_coord_origin = prop->u[0].Data;
2515
      break;
2516
   case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
2517
      tgsi->props.fs_coord_pixel_center = prop->u[0].Data;
2518
      break;
2519
   case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS:
2520
      tgsi->props.fs_color0_writes_all_cbufs = prop->u[0].Data;
2521
      break;
2522
   case TGSI_PROPERTY_FS_DEPTH_LAYOUT:
2523
      tgsi->props.fs_depth_layout = prop->u[0].Data;
2524
      break;
2525
   case TGSI_PROPERTY_GS_INPUT_PRIM:
2526
      tgsi->props.gs_input_prim = prop->u[0].Data;
2527
      break;
2528
   case TGSI_PROPERTY_GS_OUTPUT_PRIM:
2529
      tgsi->props.gs_output_prim = prop->u[0].Data;
2530
      break;
2531
   case TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES:
2532
      tgsi->props.gs_max_output_vertices = prop->u[0].Data;
2533
      break;
2534
   default:
2535
      assert(!"unhandled TGSI property");
2536
      break;
2537
   }
2538
}
2539
 
2540
static void
2541
parse_token(struct toy_tgsi *tgsi, const union tgsi_full_token *token)
2542
{
2543
   switch (token->Token.Type) {
2544
   case TGSI_TOKEN_TYPE_DECLARATION:
2545
      parse_declaration(tgsi, &token->FullDeclaration);
2546
      break;
2547
   case TGSI_TOKEN_TYPE_IMMEDIATE:
2548
      parse_immediate(tgsi, &token->FullImmediate);
2549
      break;
2550
   case TGSI_TOKEN_TYPE_INSTRUCTION:
2551
      parse_instruction(tgsi, &token->FullInstruction);
2552
      break;
2553
   case TGSI_TOKEN_TYPE_PROPERTY:
2554
      parse_property(tgsi, &token->FullProperty);
2555
      break;
2556
   default:
2557
      assert(!"unhandled TGSI token type");
2558
      break;
2559
   }
2560
}
2561
 
2562
static enum pipe_error
2563
dump_reg_mapping(void *key, void *val, void *data)
2564
{
2565
   int tgsi_file, tgsi_dim, tgsi_index;
2566
   uint32_t sig, vrf;
2567
 
2568
   sig = (uint32_t) pointer_to_intptr(key);
2569
   vrf = (uint32_t) pointer_to_intptr(val);
2570
 
2571
   /* see ra_get_map_key() */
2572
   tgsi_file =  (sig >> 28) & 0xf;
2573
   tgsi_dim =   (sig >> 16) & 0xfff;
2574
   tgsi_index = (sig >> 0)  & 0xffff;
2575
 
2576
   if (tgsi_dim) {
2577
      ilo_printf("  v%d:\t%s[%d][%d]\n", vrf,
2578
                 tgsi_file_name(tgsi_file), tgsi_dim, tgsi_index);
2579
   }
2580
   else {
2581
      ilo_printf("  v%d:\t%s[%d]\n", vrf,
2582
                 tgsi_file_name(tgsi_file), tgsi_index);
2583
   }
2584
 
2585
   return PIPE_OK;
2586
}
2587
 
2588
/**
2589
 * Dump the TGSI translator, currently only the register mapping.
2590
 */
2591
void
2592
toy_tgsi_dump(const struct toy_tgsi *tgsi)
2593
{
2594
   util_hash_table_foreach(tgsi->reg_mapping, dump_reg_mapping, NULL);
2595
}
2596
 
2597
/**
2598
 * Clean up the TGSI translator.
2599
 */
2600
void
2601
toy_tgsi_cleanup(struct toy_tgsi *tgsi)
2602
{
2603
   FREE(tgsi->imm_data.buf);
2604
   FREE(tgsi->imm_data.types);
2605
 
2606
   util_hash_table_destroy(tgsi->reg_mapping);
2607
}
2608
 
2609
static unsigned
2610
reg_mapping_hash(void *key)
2611
{
2612
   return (unsigned) pointer_to_intptr(key);
2613
}
2614
 
2615
static int
2616
reg_mapping_compare(void *key1, void *key2)
2617
{
2618
   return (key1 != key2);
2619
}
2620
 
2621
/**
2622
 * Initialize the TGSI translator.
2623
 */
2624
static bool
2625
init_tgsi(struct toy_tgsi *tgsi, struct toy_compiler *tc, bool aos)
2626
{
2627
   memset(tgsi, 0, sizeof(*tgsi));
2628
 
2629
   tgsi->tc = tc;
2630
   tgsi->aos = aos;
2631
   tgsi->translate_table = (aos) ? aos_translate_table : soa_translate_table;
2632
 
2633
   /* create a mapping of TGSI registers to VRF reigsters */
2634
   tgsi->reg_mapping =
2635
      util_hash_table_create(reg_mapping_hash, reg_mapping_compare);
2636
 
2637
   return (tgsi->reg_mapping != NULL);
2638
}
2639
 
2640
/**
2641
 * Translate TGSI tokens into toy instructions.
2642
 */
2643
void
2644
toy_compiler_translate_tgsi(struct toy_compiler *tc,
2645
                            const struct tgsi_token *tokens, bool aos,
2646
                            struct toy_tgsi *tgsi)
2647
{
2648
   struct tgsi_parse_context parse;
2649
 
2650
   if (!init_tgsi(tgsi, tc, aos)) {
2651
      tc_fail(tc, "failed to initialize TGSI translator");
2652
      return;
2653
   }
2654
 
2655
   tgsi_parse_init(&parse, tokens);
2656
   while (!tgsi_parse_end_of_tokens(&parse)) {
2657
      tgsi_parse_token(&parse);
2658
      parse_token(tgsi, &parse.FullToken);
2659
   }
2660
   tgsi_parse_free(&parse);
2661
}
2662
 
2663
/**
2664
 * Map the TGSI register to VRF register.
2665
 */
2666
int
2667
toy_tgsi_get_vrf(const struct toy_tgsi *tgsi,
2668
                 enum tgsi_file_type file, int dimension, int index)
2669
{
2670
   void *key, *val;
2671
 
2672
   key = ra_get_map_key(file, dimension, index);
2673
 
2674
   val = util_hash_table_get(tgsi->reg_mapping, key);
2675
 
2676
   return (val) ? pointer_to_intptr(val) : -1;
2677
}