2 * Mesa 3-D graphics library
4 * Copyright (C) 2012-2013 LunarG, Inc.
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
25 * Chia-I Wu <olv@lunarg.com>
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"
35 /* map TGSI opcode to GEN opcode 1-to-1 */
40 } aos_simple_opcode_map
[TGSI_OPCODE_LAST
] = {
41 [TGSI_OPCODE_ARL
] = { GEN6_OPCODE_RNDD
, 1, 1 },
42 [TGSI_OPCODE_MOV
] = { GEN6_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
] = { GEN6_OPCODE_MUL
, 1, 2 },
46 [TGSI_OPCODE_ADD
] = { GEN6_OPCODE_ADD
, 1, 2 },
47 [TGSI_OPCODE_DP3
] = { GEN6_OPCODE_DP3
, 1, 2 },
48 [TGSI_OPCODE_DP4
] = { GEN6_OPCODE_DP4
, 1, 2 },
49 [TGSI_OPCODE_MIN
] = { GEN6_OPCODE_SEL
, 1, 2 },
50 [TGSI_OPCODE_MAX
] = { GEN6_OPCODE_SEL
, 1, 2 },
51 /* a later pass will move src[2] to accumulator */
52 [TGSI_OPCODE_MAD
] = { GEN6_OPCODE_MAC
, 1, 3 },
53 [TGSI_OPCODE_SQRT
] = { TOY_OPCODE_SQRT
, 1, 1 },
54 [TGSI_OPCODE_FRC
] = { GEN6_OPCODE_FRC
, 1, 1 },
55 [TGSI_OPCODE_FLR
] = { GEN6_OPCODE_RNDD
, 1, 1 },
56 [TGSI_OPCODE_ROUND
] = { GEN6_OPCODE_RNDE
, 1, 1 },
57 [TGSI_OPCODE_EX2
] = { TOY_OPCODE_EXP
, 1, 1 },
58 [TGSI_OPCODE_LG2
] = { TOY_OPCODE_LOG
, 1, 1 },
59 [TGSI_OPCODE_POW
] = { TOY_OPCODE_POW
, 1, 2 },
60 [TGSI_OPCODE_DPH
] = { GEN6_OPCODE_DPH
, 1, 2 },
61 [TGSI_OPCODE_COS
] = { TOY_OPCODE_COS
, 1, 1 },
62 [TGSI_OPCODE_KILL
] = { TOY_OPCODE_KIL
, 0, 0 },
63 [TGSI_OPCODE_SIN
] = { TOY_OPCODE_SIN
, 1, 1 },
64 [TGSI_OPCODE_ARR
] = { GEN6_OPCODE_RNDZ
, 1, 1 },
65 [TGSI_OPCODE_DP2
] = { GEN6_OPCODE_DP2
, 1, 2 },
66 [TGSI_OPCODE_IF
] = { GEN6_OPCODE_IF
, 0, 1 },
67 [TGSI_OPCODE_UIF
] = { GEN6_OPCODE_IF
, 0, 1 },
68 [TGSI_OPCODE_ELSE
] = { GEN6_OPCODE_ELSE
, 0, 0 },
69 [TGSI_OPCODE_ENDIF
] = { GEN6_OPCODE_ENDIF
, 0, 0 },
70 [TGSI_OPCODE_I2F
] = { GEN6_OPCODE_MOV
, 1, 1 },
71 [TGSI_OPCODE_NOT
] = { GEN6_OPCODE_NOT
, 1, 1 },
72 [TGSI_OPCODE_TRUNC
] = { GEN6_OPCODE_RNDZ
, 1, 1 },
73 [TGSI_OPCODE_SHL
] = { GEN6_OPCODE_SHL
, 1, 2 },
74 [TGSI_OPCODE_AND
] = { GEN6_OPCODE_AND
, 1, 2 },
75 [TGSI_OPCODE_OR
] = { GEN6_OPCODE_OR
, 1, 2 },
76 [TGSI_OPCODE_MOD
] = { TOY_OPCODE_INT_DIV_REMAINDER
, 1, 2 },
77 [TGSI_OPCODE_XOR
] = { GEN6_OPCODE_XOR
, 1, 2 },
78 [TGSI_OPCODE_EMIT
] = { TOY_OPCODE_EMIT
, 0, 0 },
79 [TGSI_OPCODE_ENDPRIM
] = { TOY_OPCODE_ENDPRIM
, 0, 0 },
80 [TGSI_OPCODE_NOP
] = { GEN6_OPCODE_NOP
, 0, 0 },
81 [TGSI_OPCODE_KILL_IF
] = { TOY_OPCODE_KIL
, 0, 1 },
82 [TGSI_OPCODE_END
] = { GEN6_OPCODE_NOP
, 0, 0 },
83 [TGSI_OPCODE_F2I
] = { GEN6_OPCODE_MOV
, 1, 1 },
84 [TGSI_OPCODE_IDIV
] = { TOY_OPCODE_INT_DIV_QUOTIENT
, 1, 2 },
85 [TGSI_OPCODE_IMAX
] = { GEN6_OPCODE_SEL
, 1, 2 },
86 [TGSI_OPCODE_IMIN
] = { GEN6_OPCODE_SEL
, 1, 2 },
87 [TGSI_OPCODE_INEG
] = { GEN6_OPCODE_MOV
, 1, 1 },
88 [TGSI_OPCODE_ISHR
] = { GEN6_OPCODE_ASR
, 1, 2 },
89 [TGSI_OPCODE_F2U
] = { GEN6_OPCODE_MOV
, 1, 1 },
90 [TGSI_OPCODE_U2F
] = { GEN6_OPCODE_MOV
, 1, 1 },
91 [TGSI_OPCODE_UADD
] = { GEN6_OPCODE_ADD
, 1, 2 },
92 [TGSI_OPCODE_UDIV
] = { TOY_OPCODE_INT_DIV_QUOTIENT
, 1, 2 },
93 /* a later pass will move src[2] to accumulator */
94 [TGSI_OPCODE_UMAD
] = { GEN6_OPCODE_MAC
, 1, 3 },
95 [TGSI_OPCODE_UMAX
] = { GEN6_OPCODE_SEL
, 1, 2 },
96 [TGSI_OPCODE_UMIN
] = { GEN6_OPCODE_SEL
, 1, 2 },
97 [TGSI_OPCODE_UMOD
] = { TOY_OPCODE_INT_DIV_REMAINDER
, 1, 2 },
98 [TGSI_OPCODE_UMUL
] = { GEN6_OPCODE_MUL
, 1, 2 },
99 [TGSI_OPCODE_USHR
] = { GEN6_OPCODE_SHR
, 1, 2 },
100 [TGSI_OPCODE_UARL
] = { GEN6_OPCODE_MOV
, 1, 1 },
101 [TGSI_OPCODE_IABS
] = { GEN6_OPCODE_MOV
, 1, 1 },
105 aos_simple(struct toy_compiler
*tc
,
106 const struct tgsi_full_instruction
*tgsi_inst
,
110 struct toy_inst
*inst
;
112 int cond_modifier
= GEN6_COND_NONE
;
113 int num_dst
= tgsi_inst
->Instruction
.NumDstRegs
;
114 int num_src
= tgsi_inst
->Instruction
.NumSrcRegs
;
117 opcode
= aos_simple_opcode_map
[tgsi_inst
->Instruction
.Opcode
].opcode
;
118 assert(num_dst
== aos_simple_opcode_map
[tgsi_inst
->Instruction
.Opcode
].num_dst
);
119 assert(num_src
== aos_simple_opcode_map
[tgsi_inst
->Instruction
.Opcode
].num_src
);
121 assert(!"invalid aos_simple() call");
125 /* no need to emit nop */
126 if (opcode
== GEN6_OPCODE_NOP
)
133 inst
->opcode
= opcode
;
135 switch (tgsi_inst
->Instruction
.Opcode
) {
136 case TGSI_OPCODE_MIN
:
137 case TGSI_OPCODE_IMIN
:
138 case TGSI_OPCODE_UMIN
:
139 cond_modifier
= GEN6_COND_L
;
141 case TGSI_OPCODE_MAX
:
142 case TGSI_OPCODE_IMAX
:
143 case TGSI_OPCODE_UMAX
:
144 cond_modifier
= GEN6_COND_GE
;
146 case TGSI_OPCODE_IABS
:
147 src
[0] = tsrc_absolute(src
[0]);
150 cond_modifier
= GEN6_COND_NZ
;
152 assert(src
[0].type
== TOY_TYPE_F
);
153 src
[0] = tsrc_swizzle1(src
[0], TOY_SWIZZLE_X
);
154 src
[1] = tsrc_imm_f(0.0f
);
156 case TGSI_OPCODE_UIF
:
157 cond_modifier
= GEN6_COND_NZ
;
159 assert(src
[0].type
== TOY_TYPE_UD
);
160 src
[0] = tsrc_swizzle1(src
[0], TOY_SWIZZLE_X
);
161 src
[1] = tsrc_imm_d(0);
163 case TGSI_OPCODE_INEG
:
164 src
[0] = tsrc_negate(src
[0]);
166 case TGSI_OPCODE_RCP
:
167 case TGSI_OPCODE_RSQ
:
168 case TGSI_OPCODE_EX2
:
169 case TGSI_OPCODE_LG2
:
170 case TGSI_OPCODE_COS
:
171 case TGSI_OPCODE_SIN
:
172 src
[0] = tsrc_swizzle1(src
[0], TOY_SWIZZLE_X
);
174 case TGSI_OPCODE_POW
:
175 src
[0] = tsrc_swizzle1(src
[0], TOY_SWIZZLE_X
);
176 src
[1] = tsrc_swizzle1(src
[1], TOY_SWIZZLE_X
);
180 inst
->cond_modifier
= cond_modifier
;
183 assert(num_dst
== 1);
187 assert(num_src
<= ARRAY_SIZE(inst
->src
));
188 for (i
= 0; i
< num_src
; i
++)
189 inst
->src
[i
] = src
[i
];
193 aos_set_on_cond(struct toy_compiler
*tc
,
194 const struct tgsi_full_instruction
*tgsi_inst
,
198 struct toy_inst
*inst
;
200 struct toy_src zero
, one
;
202 switch (tgsi_inst
->Instruction
.Opcode
) {
203 case TGSI_OPCODE_SLT
:
204 case TGSI_OPCODE_ISLT
:
205 case TGSI_OPCODE_USLT
:
206 case TGSI_OPCODE_FSLT
:
209 case TGSI_OPCODE_SGE
:
210 case TGSI_OPCODE_ISGE
:
211 case TGSI_OPCODE_USGE
:
212 case TGSI_OPCODE_FSGE
:
215 case TGSI_OPCODE_SEQ
:
216 case TGSI_OPCODE_USEQ
:
217 case TGSI_OPCODE_FSEQ
:
220 case TGSI_OPCODE_SGT
:
223 case TGSI_OPCODE_SLE
:
226 case TGSI_OPCODE_SNE
:
227 case TGSI_OPCODE_USNE
:
228 case TGSI_OPCODE_FSNE
:
232 assert(!"invalid aos_set_on_cond() call");
236 /* note that for integer versions, all bits are set */
237 switch (dst
[0].type
) {
240 zero
= tsrc_imm_f(0.0f
);
241 one
= tsrc_imm_f(1.0f
);
244 zero
= tsrc_imm_d(0);
245 one
= tsrc_imm_d(-1);
248 zero
= tsrc_imm_ud(0);
249 one
= tsrc_imm_ud(~0);
253 tc_MOV(tc
, dst
[0], zero
);
254 tc_CMP(tc
, tdst_null(), src
[0], src
[1], cond
);
255 inst
= tc_MOV(tc
, dst
[0], one
);
256 inst
->pred_ctrl
= GEN6_PREDCTRL_NORMAL
;
260 aos_compare(struct toy_compiler
*tc
,
261 const struct tgsi_full_instruction
*tgsi_inst
,
265 struct toy_inst
*inst
;
268 switch (tgsi_inst
->Instruction
.Opcode
) {
269 case TGSI_OPCODE_CMP
:
270 zero
= tsrc_imm_f(0.0f
);
272 case TGSI_OPCODE_UCMP
:
273 zero
= tsrc_imm_ud(0);
276 assert(!"invalid aos_compare() call");
280 tc_CMP(tc
, tdst_null(), src
[0], zero
, GEN6_COND_L
);
281 inst
= tc_SEL(tc
, dst
[0], src
[1], src
[2], GEN6_COND_NONE
);
282 inst
->pred_ctrl
= GEN6_PREDCTRL_NORMAL
;
286 aos_set_sign(struct toy_compiler
*tc
,
287 const struct tgsi_full_instruction
*tgsi_inst
,
291 struct toy_inst
*inst
;
292 struct toy_src zero
, one
, neg_one
;
294 switch (tgsi_inst
->Instruction
.Opcode
) {
295 case TGSI_OPCODE_SSG
:
296 zero
= tsrc_imm_f(0.0f
);
297 one
= tsrc_imm_f(1.0f
);
298 neg_one
= tsrc_imm_f(-1.0f
);
300 case TGSI_OPCODE_ISSG
:
301 zero
= tsrc_imm_d(0);
303 neg_one
= tsrc_imm_d(-1);
306 assert(!"invalid aos_set_sign() call");
310 tc_MOV(tc
, dst
[0], zero
);
312 tc_CMP(tc
, tdst_null(), src
[0], zero
, GEN6_COND_G
);
313 inst
= tc_MOV(tc
, dst
[0], one
);
314 inst
->pred_ctrl
= GEN6_PREDCTRL_NORMAL
;
316 tc_CMP(tc
, tdst_null(), src
[0], zero
, GEN6_COND_L
);
317 inst
= tc_MOV(tc
, dst
[0], neg_one
);
318 inst
->pred_ctrl
= GEN6_PREDCTRL_NORMAL
;
322 aos_tex(struct toy_compiler
*tc
,
323 const struct tgsi_full_instruction
*tgsi_inst
,
327 struct toy_inst
*inst
;
328 enum toy_opcode opcode
;
331 switch (tgsi_inst
->Instruction
.Opcode
) {
332 case TGSI_OPCODE_TEX
:
333 opcode
= TOY_OPCODE_TGSI_TEX
;
335 case TGSI_OPCODE_TXD
:
336 opcode
= TOY_OPCODE_TGSI_TXD
;
338 case TGSI_OPCODE_TXP
:
339 opcode
= TOY_OPCODE_TGSI_TXP
;
341 case TGSI_OPCODE_TXB
:
342 opcode
= TOY_OPCODE_TGSI_TXB
;
344 case TGSI_OPCODE_TXL
:
345 opcode
= TOY_OPCODE_TGSI_TXL
;
347 case TGSI_OPCODE_TXF
:
348 opcode
= TOY_OPCODE_TGSI_TXF
;
350 case TGSI_OPCODE_TXQ
:
351 opcode
= TOY_OPCODE_TGSI_TXQ
;
353 case TGSI_OPCODE_TXQ_LZ
:
354 opcode
= TOY_OPCODE_TGSI_TXQ_LZ
;
356 case TGSI_OPCODE_TEX2
:
357 opcode
= TOY_OPCODE_TGSI_TEX2
;
359 case TGSI_OPCODE_TXB2
:
360 opcode
= TOY_OPCODE_TGSI_TXB2
;
362 case TGSI_OPCODE_TXL2
:
363 opcode
= TOY_OPCODE_TGSI_TXL2
;
366 assert(!"unsupported texturing opcode");
371 assert(tgsi_inst
->Instruction
.Texture
);
374 inst
->opcode
= opcode
;
375 inst
->tex
.target
= tgsi_inst
->Texture
.Texture
;
377 assert(tgsi_inst
->Instruction
.NumSrcRegs
<= ARRAY_SIZE(inst
->src
));
378 assert(tgsi_inst
->Instruction
.NumDstRegs
== 1);
381 for (i
= 0; i
< tgsi_inst
->Instruction
.NumSrcRegs
; i
++)
382 inst
->src
[i
] = src
[i
];
384 for (i
= 0; i
< tgsi_inst
->Texture
.NumOffsets
; i
++)
385 tc_fail(tc
, "texelFetchOffset unsupported");
389 aos_sample(struct toy_compiler
*tc
,
390 const struct tgsi_full_instruction
*tgsi_inst
,
394 struct toy_inst
*inst
;
395 enum toy_opcode opcode
;
398 assert(!"sampling untested");
400 switch (tgsi_inst
->Instruction
.Opcode
) {
401 case TGSI_OPCODE_SAMPLE
:
402 opcode
= TOY_OPCODE_TGSI_SAMPLE
;
404 case TGSI_OPCODE_SAMPLE_I
:
405 opcode
= TOY_OPCODE_TGSI_SAMPLE_I
;
407 case TGSI_OPCODE_SAMPLE_I_MS
:
408 opcode
= TOY_OPCODE_TGSI_SAMPLE_I_MS
;
410 case TGSI_OPCODE_SAMPLE_B
:
411 opcode
= TOY_OPCODE_TGSI_SAMPLE_B
;
413 case TGSI_OPCODE_SAMPLE_C
:
414 opcode
= TOY_OPCODE_TGSI_SAMPLE_C
;
416 case TGSI_OPCODE_SAMPLE_C_LZ
:
417 opcode
= TOY_OPCODE_TGSI_SAMPLE_C_LZ
;
419 case TGSI_OPCODE_SAMPLE_D
:
420 opcode
= TOY_OPCODE_TGSI_SAMPLE_D
;
422 case TGSI_OPCODE_SAMPLE_L
:
423 opcode
= TOY_OPCODE_TGSI_SAMPLE_L
;
425 case TGSI_OPCODE_GATHER4
:
426 opcode
= TOY_OPCODE_TGSI_GATHER4
;
428 case TGSI_OPCODE_SVIEWINFO
:
429 opcode
= TOY_OPCODE_TGSI_SVIEWINFO
;
431 case TGSI_OPCODE_SAMPLE_POS
:
432 opcode
= TOY_OPCODE_TGSI_SAMPLE_POS
;
434 case TGSI_OPCODE_SAMPLE_INFO
:
435 opcode
= TOY_OPCODE_TGSI_SAMPLE_INFO
;
438 assert(!"unsupported sampling opcode");
444 inst
->opcode
= opcode
;
446 assert(tgsi_inst
->Instruction
.NumSrcRegs
<= ARRAY_SIZE(inst
->src
));
447 assert(tgsi_inst
->Instruction
.NumDstRegs
== 1);
450 for (i
= 0; i
< tgsi_inst
->Instruction
.NumSrcRegs
; i
++)
451 inst
->src
[i
] = src
[i
];
455 aos_LIT(struct toy_compiler
*tc
,
456 const struct tgsi_full_instruction
*tgsi_inst
,
460 struct toy_inst
*inst
;
462 tc_MOV(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_XW
), tsrc_imm_f(1.0f
));
464 if (!(dst
[0].writemask
& TOY_WRITEMASK_YZ
))
467 tc_MOV(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_YZ
), tsrc_imm_f(0.0f
));
469 tc_CMP(tc
, tdst_null(),
470 tsrc_swizzle1(src
[0], TOY_SWIZZLE_X
),
475 tdst_writemask(dst
[0], TOY_WRITEMASK_Y
),
476 tsrc_swizzle1(src
[0], TOY_SWIZZLE_X
));
477 inst
->pred_ctrl
= GEN6_PREDCTRL_NORMAL
;
479 /* clamp W to (-128, 128)? */
481 tdst_writemask(dst
[0], TOY_WRITEMASK_Z
),
482 tsrc_swizzle1(src
[0], TOY_SWIZZLE_Y
),
483 tsrc_swizzle1(src
[0], TOY_SWIZZLE_W
));
484 inst
->pred_ctrl
= GEN6_PREDCTRL_NORMAL
;
488 aos_EXP(struct toy_compiler
*tc
,
489 const struct tgsi_full_instruction
*tgsi_inst
,
493 struct toy_src src0
= tsrc_swizzle1(src
[0], TOY_SWIZZLE_X
);
495 if (dst
[0].writemask
& TOY_WRITEMASK_X
) {
497 tdst_d(tdst_writemask(tc_alloc_tmp(tc
), TOY_WRITEMASK_X
));
499 tc_RNDD(tc
, tmp
, src0
);
501 /* construct the floating point number manually */
502 tc_ADD(tc
, tmp
, tsrc_from(tmp
), tsrc_imm_d(127));
503 tc_SHL(tc
, tdst_d(tdst_writemask(dst
[0], TOY_WRITEMASK_X
)),
504 tsrc_from(tmp
), tsrc_imm_d(23));
507 tc_FRC(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_Y
), src0
);
508 tc_EXP(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_Z
), src0
);
509 tc_MOV(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_W
), tsrc_imm_f(1.0f
));
513 aos_LOG(struct toy_compiler
*tc
,
514 const struct tgsi_full_instruction
*tgsi_inst
,
518 struct toy_src src0
= tsrc_swizzle1(src
[0], TOY_SWIZZLE_X
);
520 if (dst
[0].writemask
& TOY_WRITEMASK_XY
) {
523 tmp
= tdst_d(tdst_writemask(tc_alloc_tmp(tc
), TOY_WRITEMASK_X
));
526 tc_SHR(tc
, tmp
, tsrc_absolute(tsrc_d(src0
)), tsrc_imm_d(23));
527 tc_ADD(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_X
),
528 tsrc_from(tmp
), tsrc_imm_d(-127));
531 tc_AND(tc
, tmp
, tsrc_d(src0
), tsrc_imm_d((1 << 23) - 1));
532 tc_OR(tc
, tdst_writemask(tdst_d(dst
[0]), TOY_WRITEMASK_Y
),
533 tsrc_from(tmp
), tsrc_imm_d(127 << 23));
536 tc_LOG(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_Z
), src0
);
537 tc_MOV(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_W
), tsrc_imm_f(1.0f
));
541 aos_DST(struct toy_compiler
*tc
,
542 const struct tgsi_full_instruction
*tgsi_inst
,
546 tc_MOV(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_X
), tsrc_imm_f(1.0f
));
547 tc_MUL(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_Y
), src
[0], src
[1]);
548 tc_MOV(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_Z
), src
[0]);
549 tc_MOV(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_W
), src
[1]);
553 aos_LRP(struct toy_compiler
*tc
,
554 const struct tgsi_full_instruction
*tgsi_inst
,
558 struct toy_dst tmp
= tc_alloc_tmp(tc
);
560 tc_ADD(tc
, tmp
, tsrc_negate(src
[0]), tsrc_imm_f(1.0f
));
561 tc_MUL(tc
, tmp
, tsrc_from(tmp
), src
[2]);
562 tc_MAC(tc
, dst
[0], src
[0], src
[1], tsrc_from(tmp
));
566 aos_DP2A(struct toy_compiler
*tc
,
567 const struct tgsi_full_instruction
*tgsi_inst
,
571 struct toy_dst tmp
= tc_alloc_tmp(tc
);
573 assert(!"DP2A untested");
575 tc_DP2(tc
, tmp
, src
[0], src
[1]);
576 tc_ADD(tc
, dst
[0], tsrc_swizzle1(tsrc_from(tmp
), TOY_SWIZZLE_X
), src
[2]);
580 aos_CLAMP(struct toy_compiler
*tc
,
581 const struct tgsi_full_instruction
*tgsi_inst
,
585 assert(!"CLAMP untested");
587 tc_SEL(tc
, dst
[0], src
[0], src
[1], GEN6_COND_GE
);
588 tc_SEL(tc
, dst
[0], src
[2], tsrc_from(dst
[0]), GEN6_COND_L
);
592 aos_XPD(struct toy_compiler
*tc
,
593 const struct tgsi_full_instruction
*tgsi_inst
,
597 struct toy_dst tmp
= tc_alloc_tmp(tc
);
599 tc_MUL(tc
, tdst_writemask(tmp
, TOY_WRITEMASK_XYZ
),
600 tsrc_swizzle(src
[0], TOY_SWIZZLE_Z
, TOY_SWIZZLE_X
,
601 TOY_SWIZZLE_Y
, TOY_SWIZZLE_W
),
602 tsrc_swizzle(src
[1], TOY_SWIZZLE_Y
, TOY_SWIZZLE_Z
,
603 TOY_SWIZZLE_X
, TOY_SWIZZLE_W
));
605 tc_MAC(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_XYZ
),
606 tsrc_swizzle(src
[0], TOY_SWIZZLE_Y
, TOY_SWIZZLE_Z
,
607 TOY_SWIZZLE_X
, TOY_SWIZZLE_W
),
608 tsrc_swizzle(src
[1], TOY_SWIZZLE_Z
, TOY_SWIZZLE_X
,
609 TOY_SWIZZLE_Y
, TOY_SWIZZLE_W
),
610 tsrc_negate(tsrc_from(tmp
)));
612 tc_MOV(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_W
),
617 aos_PK2H(struct toy_compiler
*tc
,
618 const struct tgsi_full_instruction
*tgsi_inst
,
622 const struct toy_src h1
= tsrc_ud(tsrc_swizzle1(src
[0], TOY_SWIZZLE_X
));
623 const struct toy_src h2
= tsrc_ud(tsrc_swizzle1(src
[0], TOY_SWIZZLE_Y
));
624 struct toy_dst tmp
= tdst_ud(tc_alloc_tmp(tc
));
626 assert(!"PK2H untested");
628 tc_SHL(tc
, tmp
, h2
, tsrc_imm_ud(16));
629 tc_OR(tc
, tdst_ud(dst
[0]), h1
, tsrc_from(tmp
));
633 aos_UP2H(struct toy_compiler
*tc
,
634 const struct tgsi_full_instruction
*tgsi_inst
,
638 assert(!"UP2H untested");
640 tc_AND(tc
, tdst_writemask(tdst_ud(dst
[0]), TOY_WRITEMASK_XZ
),
641 tsrc_ud(src
[0]), tsrc_imm_ud(0xffff));
642 tc_SHR(tc
, tdst_writemask(tdst_ud(dst
[0]), TOY_WRITEMASK_YW
),
643 tsrc_ud(src
[0]), tsrc_imm_ud(16));
647 aos_SCS(struct toy_compiler
*tc
,
648 const struct tgsi_full_instruction
*tgsi_inst
,
652 assert(!"SCS untested");
654 tc_add1(tc
, TOY_OPCODE_COS
,
655 tdst_writemask(dst
[0], TOY_WRITEMASK_X
), src
[0]);
657 tc_add1(tc
, TOY_OPCODE_SIN
,
658 tdst_writemask(dst
[0], TOY_WRITEMASK_Y
), src
[0]);
660 tc_MOV(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_Z
), tsrc_imm_f(0.0f
));
661 tc_MOV(tc
, tdst_writemask(dst
[0], TOY_WRITEMASK_W
), tsrc_imm_f(1.0f
));
665 aos_DIV(struct toy_compiler
*tc
,
666 const struct tgsi_full_instruction
*tgsi_inst
,
670 struct toy_dst tmp
= tc_alloc_tmp(tc
);
672 assert(!"DIV untested");
674 tc_INV(tc
, tmp
, src
[1]);
675 tc_MUL(tc
, dst
[0], src
[0], tsrc_from(tmp
));
679 aos_BRK(struct toy_compiler
*tc
,
680 const struct tgsi_full_instruction
*tgsi_inst
,
684 tc_add0(tc
, GEN6_OPCODE_BREAK
);
688 aos_CEIL(struct toy_compiler
*tc
,
689 const struct tgsi_full_instruction
*tgsi_inst
,
693 struct toy_dst tmp
= tc_alloc_tmp(tc
);
695 tc_RNDD(tc
, tmp
, tsrc_negate(src
[0]));
696 tc_MOV(tc
, dst
[0], tsrc_negate(tsrc_from(tmp
)));
700 aos_SAD(struct toy_compiler
*tc
,
701 const struct tgsi_full_instruction
*tgsi_inst
,
705 struct toy_dst tmp
= tc_alloc_tmp(tc
);
707 assert(!"SAD untested");
709 tc_ADD(tc
, tmp
, src
[0], tsrc_negate(src
[1]));
710 tc_ADD(tc
, dst
[0], tsrc_absolute(tsrc_from(tmp
)), src
[2]);
714 aos_CONT(struct toy_compiler
*tc
,
715 const struct tgsi_full_instruction
*tgsi_inst
,
719 tc_add0(tc
, GEN6_OPCODE_CONT
);
723 aos_BGNLOOP(struct toy_compiler
*tc
,
724 const struct tgsi_full_instruction
*tgsi_inst
,
728 struct toy_inst
*inst
;
730 inst
= tc_add0(tc
, TOY_OPCODE_DO
);
731 /* this is just a marker */
736 aos_ENDLOOP(struct toy_compiler
*tc
,
737 const struct tgsi_full_instruction
*tgsi_inst
,
741 tc_add0(tc
, GEN6_OPCODE_WHILE
);
745 aos_unsupported(struct toy_compiler
*tc
,
746 const struct tgsi_full_instruction
*tgsi_inst
,
750 const char *name
= tgsi_get_opcode_name(tgsi_inst
->Instruction
.Opcode
);
752 ilo_warn("unsupported TGSI opcode: TGSI_OPCODE_%s\n", name
);
754 tc_fail(tc
, "unsupported TGSI instruction");
757 static const toy_tgsi_translate aos_translate_table
[TGSI_OPCODE_LAST
] = {
758 [TGSI_OPCODE_ARL
] = aos_simple
,
759 [TGSI_OPCODE_MOV
] = aos_simple
,
760 [TGSI_OPCODE_LIT
] = aos_LIT
,
761 [TGSI_OPCODE_RCP
] = aos_simple
,
762 [TGSI_OPCODE_RSQ
] = aos_simple
,
763 [TGSI_OPCODE_EXP
] = aos_EXP
,
764 [TGSI_OPCODE_LOG
] = aos_LOG
,
765 [TGSI_OPCODE_MUL
] = aos_simple
,
766 [TGSI_OPCODE_ADD
] = aos_simple
,
767 [TGSI_OPCODE_DP3
] = aos_simple
,
768 [TGSI_OPCODE_DP4
] = aos_simple
,
769 [TGSI_OPCODE_DST
] = aos_DST
,
770 [TGSI_OPCODE_MIN
] = aos_simple
,
771 [TGSI_OPCODE_MAX
] = aos_simple
,
772 [TGSI_OPCODE_SLT
] = aos_set_on_cond
,
773 [TGSI_OPCODE_SGE
] = aos_set_on_cond
,
774 [TGSI_OPCODE_MAD
] = aos_simple
,
775 [TGSI_OPCODE_LRP
] = aos_LRP
,
776 [TGSI_OPCODE_SQRT
] = aos_simple
,
777 [TGSI_OPCODE_DP2A
] = aos_DP2A
,
778 [TGSI_OPCODE_FRC
] = aos_simple
,
779 [TGSI_OPCODE_CLAMP
] = aos_CLAMP
,
780 [TGSI_OPCODE_FLR
] = aos_simple
,
781 [TGSI_OPCODE_ROUND
] = aos_simple
,
782 [TGSI_OPCODE_EX2
] = aos_simple
,
783 [TGSI_OPCODE_LG2
] = aos_simple
,
784 [TGSI_OPCODE_POW
] = aos_simple
,
785 [TGSI_OPCODE_XPD
] = aos_XPD
,
786 [TGSI_OPCODE_DPH
] = aos_simple
,
787 [TGSI_OPCODE_COS
] = aos_simple
,
788 [TGSI_OPCODE_DDX
] = aos_unsupported
,
789 [TGSI_OPCODE_DDY
] = aos_unsupported
,
790 [TGSI_OPCODE_KILL
] = aos_simple
,
791 [TGSI_OPCODE_PK2H
] = aos_PK2H
,
792 [TGSI_OPCODE_PK2US
] = aos_unsupported
,
793 [TGSI_OPCODE_PK4B
] = aos_unsupported
,
794 [TGSI_OPCODE_PK4UB
] = aos_unsupported
,
795 [TGSI_OPCODE_SEQ
] = aos_set_on_cond
,
796 [TGSI_OPCODE_SGT
] = aos_set_on_cond
,
797 [TGSI_OPCODE_SIN
] = aos_simple
,
798 [TGSI_OPCODE_SLE
] = aos_set_on_cond
,
799 [TGSI_OPCODE_SNE
] = aos_set_on_cond
,
800 [TGSI_OPCODE_TEX
] = aos_tex
,
801 [TGSI_OPCODE_TXD
] = aos_tex
,
802 [TGSI_OPCODE_TXP
] = aos_tex
,
803 [TGSI_OPCODE_UP2H
] = aos_UP2H
,
804 [TGSI_OPCODE_UP2US
] = aos_unsupported
,
805 [TGSI_OPCODE_UP4B
] = aos_unsupported
,
806 [TGSI_OPCODE_UP4UB
] = aos_unsupported
,
807 [TGSI_OPCODE_ARR
] = aos_simple
,
808 [TGSI_OPCODE_CAL
] = aos_unsupported
,
809 [TGSI_OPCODE_RET
] = aos_unsupported
,
810 [TGSI_OPCODE_SSG
] = aos_set_sign
,
811 [TGSI_OPCODE_CMP
] = aos_compare
,
812 [TGSI_OPCODE_SCS
] = aos_SCS
,
813 [TGSI_OPCODE_TXB
] = aos_tex
,
814 [TGSI_OPCODE_DIV
] = aos_DIV
,
815 [TGSI_OPCODE_DP2
] = aos_simple
,
816 [TGSI_OPCODE_TXL
] = aos_tex
,
817 [TGSI_OPCODE_BRK
] = aos_BRK
,
818 [TGSI_OPCODE_IF
] = aos_simple
,
819 [TGSI_OPCODE_UIF
] = aos_simple
,
820 [TGSI_OPCODE_ELSE
] = aos_simple
,
821 [TGSI_OPCODE_ENDIF
] = aos_simple
,
822 [TGSI_OPCODE_PUSHA
] = aos_unsupported
,
823 [TGSI_OPCODE_POPA
] = aos_unsupported
,
824 [TGSI_OPCODE_CEIL
] = aos_CEIL
,
825 [TGSI_OPCODE_I2F
] = aos_simple
,
826 [TGSI_OPCODE_NOT
] = aos_simple
,
827 [TGSI_OPCODE_TRUNC
] = aos_simple
,
828 [TGSI_OPCODE_SHL
] = aos_simple
,
829 [TGSI_OPCODE_AND
] = aos_simple
,
830 [TGSI_OPCODE_OR
] = aos_simple
,
831 [TGSI_OPCODE_MOD
] = aos_simple
,
832 [TGSI_OPCODE_XOR
] = aos_simple
,
833 [TGSI_OPCODE_SAD
] = aos_SAD
,
834 [TGSI_OPCODE_TXF
] = aos_tex
,
835 [TGSI_OPCODE_TXQ
] = aos_tex
,
836 [TGSI_OPCODE_CONT
] = aos_CONT
,
837 [TGSI_OPCODE_EMIT
] = aos_simple
,
838 [TGSI_OPCODE_ENDPRIM
] = aos_simple
,
839 [TGSI_OPCODE_BGNLOOP
] = aos_BGNLOOP
,
840 [TGSI_OPCODE_BGNSUB
] = aos_unsupported
,
841 [TGSI_OPCODE_ENDLOOP
] = aos_ENDLOOP
,
842 [TGSI_OPCODE_ENDSUB
] = aos_unsupported
,
843 [TGSI_OPCODE_TXQ_LZ
] = aos_tex
,
844 [TGSI_OPCODE_NOP
] = aos_simple
,
845 [TGSI_OPCODE_FSEQ
] = aos_set_on_cond
,
846 [TGSI_OPCODE_FSGE
] = aos_set_on_cond
,
847 [TGSI_OPCODE_FSLT
] = aos_set_on_cond
,
848 [TGSI_OPCODE_FSNE
] = aos_set_on_cond
,
849 [TGSI_OPCODE_CALLNZ
] = aos_unsupported
,
850 [TGSI_OPCODE_BREAKC
] = aos_unsupported
,
851 [TGSI_OPCODE_KILL_IF
] = aos_simple
,
852 [TGSI_OPCODE_END
] = aos_simple
,
853 [TGSI_OPCODE_F2I
] = aos_simple
,
854 [TGSI_OPCODE_IDIV
] = aos_simple
,
855 [TGSI_OPCODE_IMAX
] = aos_simple
,
856 [TGSI_OPCODE_IMIN
] = aos_simple
,
857 [TGSI_OPCODE_INEG
] = aos_simple
,
858 [TGSI_OPCODE_ISGE
] = aos_set_on_cond
,
859 [TGSI_OPCODE_ISHR
] = aos_simple
,
860 [TGSI_OPCODE_ISLT
] = aos_set_on_cond
,
861 [TGSI_OPCODE_F2U
] = aos_simple
,
862 [TGSI_OPCODE_U2F
] = aos_simple
,
863 [TGSI_OPCODE_UADD
] = aos_simple
,
864 [TGSI_OPCODE_UDIV
] = aos_simple
,
865 [TGSI_OPCODE_UMAD
] = aos_simple
,
866 [TGSI_OPCODE_UMAX
] = aos_simple
,
867 [TGSI_OPCODE_UMIN
] = aos_simple
,
868 [TGSI_OPCODE_UMOD
] = aos_simple
,
869 [TGSI_OPCODE_UMUL
] = aos_simple
,
870 [TGSI_OPCODE_USEQ
] = aos_set_on_cond
,
871 [TGSI_OPCODE_USGE
] = aos_set_on_cond
,
872 [TGSI_OPCODE_USHR
] = aos_simple
,
873 [TGSI_OPCODE_USLT
] = aos_set_on_cond
,
874 [TGSI_OPCODE_USNE
] = aos_set_on_cond
,
875 [TGSI_OPCODE_SWITCH
] = aos_unsupported
,
876 [TGSI_OPCODE_CASE
] = aos_unsupported
,
877 [TGSI_OPCODE_DEFAULT
] = aos_unsupported
,
878 [TGSI_OPCODE_ENDSWITCH
] = aos_unsupported
,
879 [TGSI_OPCODE_SAMPLE
] = aos_sample
,
880 [TGSI_OPCODE_SAMPLE_I
] = aos_sample
,
881 [TGSI_OPCODE_SAMPLE_I_MS
] = aos_sample
,
882 [TGSI_OPCODE_SAMPLE_B
] = aos_sample
,
883 [TGSI_OPCODE_SAMPLE_C
] = aos_sample
,
884 [TGSI_OPCODE_SAMPLE_C_LZ
] = aos_sample
,
885 [TGSI_OPCODE_SAMPLE_D
] = aos_sample
,
886 [TGSI_OPCODE_SAMPLE_L
] = aos_sample
,
887 [TGSI_OPCODE_GATHER4
] = aos_sample
,
888 [TGSI_OPCODE_SVIEWINFO
] = aos_sample
,
889 [TGSI_OPCODE_SAMPLE_POS
] = aos_sample
,
890 [TGSI_OPCODE_SAMPLE_INFO
] = aos_sample
,
891 [TGSI_OPCODE_UARL
] = aos_simple
,
892 [TGSI_OPCODE_UCMP
] = aos_compare
,
893 [TGSI_OPCODE_IABS
] = aos_simple
,
894 [TGSI_OPCODE_ISSG
] = aos_set_sign
,
895 [TGSI_OPCODE_LOAD
] = aos_unsupported
,
896 [TGSI_OPCODE_STORE
] = aos_unsupported
,
897 [TGSI_OPCODE_MFENCE
] = aos_unsupported
,
898 [TGSI_OPCODE_LFENCE
] = aos_unsupported
,
899 [TGSI_OPCODE_SFENCE
] = aos_unsupported
,
900 [TGSI_OPCODE_BARRIER
] = aos_unsupported
,
901 [TGSI_OPCODE_ATOMUADD
] = aos_unsupported
,
902 [TGSI_OPCODE_ATOMXCHG
] = aos_unsupported
,
903 [TGSI_OPCODE_ATOMCAS
] = aos_unsupported
,
904 [TGSI_OPCODE_ATOMAND
] = aos_unsupported
,
905 [TGSI_OPCODE_ATOMOR
] = aos_unsupported
,
906 [TGSI_OPCODE_ATOMXOR
] = aos_unsupported
,
907 [TGSI_OPCODE_ATOMUMIN
] = aos_unsupported
,
908 [TGSI_OPCODE_ATOMUMAX
] = aos_unsupported
,
909 [TGSI_OPCODE_ATOMIMIN
] = aos_unsupported
,
910 [TGSI_OPCODE_ATOMIMAX
] = aos_unsupported
,
911 [TGSI_OPCODE_TEX2
] = aos_tex
,
912 [TGSI_OPCODE_TXB2
] = aos_tex
,
913 [TGSI_OPCODE_TXL2
] = aos_tex
,
917 soa_passthrough(struct toy_compiler
*tc
,
918 const struct tgsi_full_instruction
*tgsi_inst
,
919 struct toy_dst
*dst_
,
920 struct toy_src
*src_
)
922 const toy_tgsi_translate translate
=
923 aos_translate_table
[tgsi_inst
->Instruction
.Opcode
];
925 translate(tc
, tgsi_inst
, dst_
, src_
);
929 soa_per_channel(struct toy_compiler
*tc
,
930 const struct tgsi_full_instruction
*tgsi_inst
,
931 struct toy_dst
*dst_
,
932 struct toy_src
*src_
)
934 struct toy_dst dst
[TGSI_FULL_MAX_DST_REGISTERS
][4];
935 struct toy_src src
[TGSI_FULL_MAX_SRC_REGISTERS
][4];
938 for (i
= 0; i
< tgsi_inst
->Instruction
.NumDstRegs
; i
++)
939 tdst_transpose(dst_
[i
], dst
[i
]);
940 for (i
= 0; i
< tgsi_inst
->Instruction
.NumSrcRegs
; i
++)
941 tsrc_transpose(src_
[i
], src
[i
]);
943 /* emit the same instruction four times for the four channels */
944 for (ch
= 0; ch
< 4; ch
++) {
945 struct toy_dst aos_dst
[TGSI_FULL_MAX_DST_REGISTERS
];
946 struct toy_src aos_src
[TGSI_FULL_MAX_SRC_REGISTERS
];
948 for (i
= 0; i
< tgsi_inst
->Instruction
.NumDstRegs
; i
++)
949 aos_dst
[i
] = dst
[i
][ch
];
950 for (i
= 0; i
< tgsi_inst
->Instruction
.NumSrcRegs
; i
++)
951 aos_src
[i
] = src
[i
][ch
];
953 aos_translate_table
[tgsi_inst
->Instruction
.Opcode
](tc
,
954 tgsi_inst
, aos_dst
, aos_src
);
959 soa_scalar_replicate(struct toy_compiler
*tc
,
960 const struct tgsi_full_instruction
*tgsi_inst
,
961 struct toy_dst
*dst_
,
962 struct toy_src
*src_
)
964 struct toy_dst dst0
[4], tmp
;
965 struct toy_src srcx
[TGSI_FULL_MAX_SRC_REGISTERS
];
968 assert(tgsi_inst
->Instruction
.NumDstRegs
== 1);
970 tdst_transpose(dst_
[0], dst0
);
971 for (i
= 0; i
< tgsi_inst
->Instruction
.NumSrcRegs
; i
++) {
972 struct toy_src tmp
[4];
974 tsrc_transpose(src_
[i
], tmp
);
975 /* only the X channels */
979 tmp
= tc_alloc_tmp(tc
);
981 opcode
= aos_simple_opcode_map
[tgsi_inst
->Instruction
.Opcode
].opcode
;
984 switch (tgsi_inst
->Instruction
.Opcode
) {
985 case TGSI_OPCODE_RCP
:
986 case TGSI_OPCODE_RSQ
:
987 case TGSI_OPCODE_SQRT
:
988 case TGSI_OPCODE_EX2
:
989 case TGSI_OPCODE_LG2
:
990 case TGSI_OPCODE_COS
:
991 case TGSI_OPCODE_SIN
:
992 tc_add1(tc
, opcode
, tmp
, srcx
[0]);
994 case TGSI_OPCODE_POW
:
995 tc_add2(tc
, opcode
, tmp
, srcx
[0], srcx
[1]);
998 assert(!"invalid soa_scalar_replicate() call");
1002 /* replicate the result */
1003 for (i
= 0; i
< 4; i
++)
1004 tc_MOV(tc
, dst0
[i
], tsrc_from(tmp
));
1008 soa_dot_product(struct toy_compiler
*tc
,
1009 const struct tgsi_full_instruction
*tgsi_inst
,
1010 struct toy_dst
*dst_
,
1011 struct toy_src
*src_
)
1013 struct toy_dst dst0
[4], tmp
;
1014 struct toy_src src
[TGSI_FULL_MAX_SRC_REGISTERS
][4];
1017 tdst_transpose(dst_
[0], dst0
);
1018 for (i
= 0; i
< tgsi_inst
->Instruction
.NumSrcRegs
; i
++)
1019 tsrc_transpose(src_
[i
], src
[i
]);
1021 tmp
= tc_alloc_tmp(tc
);
1023 switch (tgsi_inst
->Instruction
.Opcode
) {
1024 case TGSI_OPCODE_DP2
:
1025 tc_MUL(tc
, tmp
, src
[0][1], src
[1][1]);
1026 tc_MAC(tc
, tmp
, src
[0][0], src
[1][0], tsrc_from(tmp
));
1028 case TGSI_OPCODE_DP2A
:
1029 tc_MAC(tc
, tmp
, src
[0][1], src
[1][1], src
[2][0]);
1030 tc_MAC(tc
, tmp
, src
[0][0], src
[1][0], tsrc_from(tmp
));
1032 case TGSI_OPCODE_DP3
:
1033 tc_MUL(tc
, tmp
, src
[0][2], src
[1][2]);
1034 tc_MAC(tc
, tmp
, src
[0][1], src
[1][1], tsrc_from(tmp
));
1035 tc_MAC(tc
, tmp
, src
[0][0], src
[1][0], tsrc_from(tmp
));
1037 case TGSI_OPCODE_DPH
:
1038 tc_MAC(tc
, tmp
, src
[0][2], src
[1][2], src
[1][3]);
1039 tc_MAC(tc
, tmp
, src
[0][1], src
[1][1], tsrc_from(tmp
));
1040 tc_MAC(tc
, tmp
, src
[0][0], src
[1][0], tsrc_from(tmp
));
1042 case TGSI_OPCODE_DP4
:
1043 tc_MUL(tc
, tmp
, src
[0][3], src
[1][3]);
1044 tc_MAC(tc
, tmp
, src
[0][2], src
[1][2], tsrc_from(tmp
));
1045 tc_MAC(tc
, tmp
, src
[0][1], src
[1][1], tsrc_from(tmp
));
1046 tc_MAC(tc
, tmp
, src
[0][0], src
[1][0], tsrc_from(tmp
));
1049 assert(!"invalid soa_dot_product() call");
1053 for (i
= 0; i
< 4; i
++)
1054 tc_MOV(tc
, dst0
[i
], tsrc_from(tmp
));
1058 soa_partial_derivative(struct toy_compiler
*tc
,
1059 const struct tgsi_full_instruction
*tgsi_inst
,
1060 struct toy_dst
*dst_
,
1061 struct toy_src
*src_
)
1063 if (tgsi_inst
->Instruction
.Opcode
== TGSI_OPCODE_DDX
)
1064 tc_add1(tc
, TOY_OPCODE_DDX
, dst_
[0], src_
[0]);
1066 tc_add1(tc
, TOY_OPCODE_DDY
, dst_
[0], src_
[0]);
1070 soa_if(struct toy_compiler
*tc
,
1071 const struct tgsi_full_instruction
*tgsi_inst
,
1072 struct toy_dst
*dst_
,
1073 struct toy_src
*src_
)
1075 struct toy_src src0
[4];
1077 assert(tsrc_is_swizzle1(src_
[0]));
1078 tsrc_transpose(src_
[0], src0
);
1080 if (tgsi_inst
->Instruction
.Opcode
== TGSI_OPCODE_IF
)
1081 tc_IF(tc
, tdst_null(), src0
[0], tsrc_imm_f(0.0f
), GEN6_COND_NZ
);
1083 tc_IF(tc
, tdst_null(), src0
[0], tsrc_imm_d(0), GEN6_COND_NZ
);
1087 soa_LIT(struct toy_compiler
*tc
,
1088 const struct tgsi_full_instruction
*tgsi_inst
,
1089 struct toy_dst
*dst_
,
1090 struct toy_src
*src_
)
1092 struct toy_inst
*inst
;
1093 struct toy_dst dst0
[4];
1094 struct toy_src src0
[4];
1096 tdst_transpose(dst_
[0], dst0
);
1097 tsrc_transpose(src_
[0], src0
);
1099 tc_MOV(tc
, dst0
[0], tsrc_imm_f(1.0f
));
1100 tc_MOV(tc
, dst0
[1], src0
[0]);
1101 tc_POW(tc
, dst0
[2], src0
[1], src0
[3]);
1102 tc_MOV(tc
, dst0
[3], tsrc_imm_f(1.0f
));
1105 * POW is calculated first because math with pred_ctrl is broken here.
1108 tc_CMP(tc
, tdst_null(), src0
[0], tsrc_imm_f(0.0f
), GEN6_COND_L
);
1109 inst
= tc_MOV(tc
, dst0
[1], tsrc_imm_f(0.0f
));
1110 inst
->pred_ctrl
= GEN6_PREDCTRL_NORMAL
;
1111 inst
= tc_MOV(tc
, dst0
[2], tsrc_imm_f(0.0f
));
1112 inst
->pred_ctrl
= GEN6_PREDCTRL_NORMAL
;
1116 soa_EXP(struct toy_compiler
*tc
,
1117 const struct tgsi_full_instruction
*tgsi_inst
,
1118 struct toy_dst
*dst_
,
1119 struct toy_src
*src_
)
1121 struct toy_dst dst0
[4];
1122 struct toy_src src0
[4];
1124 assert(!"SoA EXP untested");
1126 tdst_transpose(dst_
[0], dst0
);
1127 tsrc_transpose(src_
[0], src0
);
1129 if (!tdst_is_null(dst0
[0])) {
1130 struct toy_dst tmp
= tdst_d(tc_alloc_tmp(tc
));
1132 tc_RNDD(tc
, tmp
, src0
[0]);
1134 /* construct the floating point number manually */
1135 tc_ADD(tc
, tmp
, tsrc_from(tmp
), tsrc_imm_d(127));
1136 tc_SHL(tc
, tdst_d(dst0
[0]), tsrc_from(tmp
), tsrc_imm_d(23));
1139 tc_FRC(tc
, dst0
[1], src0
[0]);
1140 tc_EXP(tc
, dst0
[2], src0
[0]);
1141 tc_MOV(tc
, dst0
[3], tsrc_imm_f(1.0f
));
1145 soa_LOG(struct toy_compiler
*tc
,
1146 const struct tgsi_full_instruction
*tgsi_inst
,
1147 struct toy_dst
*dst_
,
1148 struct toy_src
*src_
)
1150 struct toy_dst dst0
[4];
1151 struct toy_src src0
[4];
1153 assert(!"SoA LOG untested");
1155 tdst_transpose(dst_
[0], dst0
);
1156 tsrc_transpose(src_
[0], src0
);
1158 if (dst_
[0].writemask
& TOY_WRITEMASK_XY
) {
1159 struct toy_dst tmp
= tdst_d(tc_alloc_tmp(tc
));
1162 tc_SHR(tc
, tmp
, tsrc_absolute(tsrc_d(src0
[0])), tsrc_imm_d(23));
1163 tc_ADD(tc
, dst0
[0], tsrc_from(tmp
), tsrc_imm_d(-127));
1166 tc_AND(tc
, tmp
, tsrc_d(src0
[0]), tsrc_imm_d((1 << 23) - 1));
1167 tc_OR(tc
, dst0
[1], tsrc_from(tmp
), tsrc_imm_d(127 << 23));
1170 tc_LOG(tc
, dst0
[2], src0
[0]);
1171 tc_MOV(tc
, dst0
[3], tsrc_imm_f(1.0f
));
1175 soa_DST(struct toy_compiler
*tc
,
1176 const struct tgsi_full_instruction
*tgsi_inst
,
1177 struct toy_dst
*dst_
,
1178 struct toy_src
*src_
)
1180 struct toy_dst dst0
[4];
1181 struct toy_src src
[2][4];
1183 tdst_transpose(dst_
[0], dst0
);
1184 tsrc_transpose(src_
[0], src
[0]);
1185 tsrc_transpose(src_
[1], src
[1]);
1187 tc_MOV(tc
, dst0
[0], tsrc_imm_f(1.0f
));
1188 tc_MUL(tc
, dst0
[1], src
[0][1], src
[1][1]);
1189 tc_MOV(tc
, dst0
[2], src
[0][2]);
1190 tc_MOV(tc
, dst0
[3], src
[1][3]);
1194 soa_XPD(struct toy_compiler
*tc
,
1195 const struct tgsi_full_instruction
*tgsi_inst
,
1196 struct toy_dst
*dst_
,
1197 struct toy_src
*src_
)
1199 struct toy_dst dst0
[4];
1200 struct toy_src src
[2][4];
1202 tdst_transpose(dst_
[0], dst0
);
1203 tsrc_transpose(src_
[0], src
[0]);
1204 tsrc_transpose(src_
[1], src
[1]);
1206 /* dst.x = src0.y * src1.z - src1.y * src0.z */
1207 tc_MUL(tc
, dst0
[0], src
[0][2], src
[1][1]);
1208 tc_MAC(tc
, dst0
[0], src
[0][1], src
[1][2], tsrc_negate(tsrc_from(dst0
[0])));
1210 /* dst.y = src0.z * src1.x - src1.z * src0.x */
1211 tc_MUL(tc
, dst0
[1], src
[0][0], src
[1][2]);
1212 tc_MAC(tc
, dst0
[1], src
[0][2], src
[1][0], tsrc_negate(tsrc_from(dst0
[1])));
1214 /* dst.z = src0.x * src1.y - src1.x * src0.y */
1215 tc_MUL(tc
, dst0
[2], src
[0][1], src
[1][0]);
1216 tc_MAC(tc
, dst0
[2], src
[0][0], src
[1][1], tsrc_negate(tsrc_from(dst0
[2])));
1218 tc_MOV(tc
, dst0
[3], tsrc_imm_f(1.0f
));
1222 soa_PK2H(struct toy_compiler
*tc
,
1223 const struct tgsi_full_instruction
*tgsi_inst
,
1224 struct toy_dst
*dst_
,
1225 struct toy_src
*src_
)
1227 struct toy_dst tmp
= tdst_ud(tc_alloc_tmp(tc
));
1228 struct toy_dst dst0
[4];
1229 struct toy_src src0
[4];
1232 assert(!"SoA PK2H untested");
1234 tdst_transpose(dst_
[0], dst0
);
1235 tsrc_transpose(src_
[0], src0
);
1237 tc_SHL(tc
, tmp
, src0
[1], tsrc_imm_ud(16));
1238 tc_OR(tc
, tmp
, src0
[0], tsrc_from(tmp
));
1240 for (i
= 0; i
< 4; i
++)
1241 tc_MOV(tc
, dst0
[i
], tsrc_from(tmp
));
1245 soa_UP2H(struct toy_compiler
*tc
,
1246 const struct tgsi_full_instruction
*tgsi_inst
,
1247 struct toy_dst
*dst_
,
1248 struct toy_src
*src_
)
1250 struct toy_dst dst0
[4];
1251 struct toy_src src0
[4];
1253 assert(!"SoA UP2H untested");
1255 tdst_transpose(dst_
[0], dst0
);
1256 tsrc_transpose(src_
[0], src0
);
1258 tc_AND(tc
, tdst_ud(dst0
[0]), tsrc_ud(src0
[0]), tsrc_imm_ud(0xffff));
1259 tc_SHR(tc
, tdst_ud(dst0
[1]), tsrc_ud(src0
[1]), tsrc_imm_ud(16));
1260 tc_AND(tc
, tdst_ud(dst0
[2]), tsrc_ud(src0
[2]), tsrc_imm_ud(0xffff));
1261 tc_SHR(tc
, tdst_ud(dst0
[3]), tsrc_ud(src0
[3]), tsrc_imm_ud(16));
1266 soa_SCS(struct toy_compiler
*tc
,
1267 const struct tgsi_full_instruction
*tgsi_inst
,
1268 struct toy_dst
*dst_
,
1269 struct toy_src
*src_
)
1271 struct toy_dst dst0
[4];
1272 struct toy_src src0
[4];
1274 tdst_transpose(dst_
[0], dst0
);
1275 tsrc_transpose(src_
[0], src0
);
1277 tc_add1(tc
, TOY_OPCODE_COS
, dst0
[0], src0
[0]);
1278 tc_add1(tc
, TOY_OPCODE_SIN
, dst0
[1], src0
[0]);
1279 tc_MOV(tc
, dst0
[2], tsrc_imm_f(0.0f
));
1280 tc_MOV(tc
, dst0
[3], tsrc_imm_f(1.0f
));
1284 soa_unsupported(struct toy_compiler
*tc
,
1285 const struct tgsi_full_instruction
*tgsi_inst
,
1286 struct toy_dst
*dst_
,
1287 struct toy_src
*src_
)
1289 const struct tgsi_opcode_info
*info
=
1290 tgsi_get_opcode_info(tgsi_inst
->Instruction
.Opcode
);
1292 ilo_warn("unsupported TGSI opcode in SoA form: TGSI_OPCODE_%s\n",
1295 tc_fail(tc
, "unsupported TGSI instruction in SoA form");
1298 static const toy_tgsi_translate soa_translate_table
[TGSI_OPCODE_LAST
] = {
1299 [TGSI_OPCODE_ARL
] = soa_per_channel
,
1300 [TGSI_OPCODE_MOV
] = soa_per_channel
,
1301 [TGSI_OPCODE_LIT
] = soa_LIT
,
1302 [TGSI_OPCODE_RCP
] = soa_scalar_replicate
,
1303 [TGSI_OPCODE_RSQ
] = soa_scalar_replicate
,
1304 [TGSI_OPCODE_EXP
] = soa_EXP
,
1305 [TGSI_OPCODE_LOG
] = soa_LOG
,
1306 [TGSI_OPCODE_MUL
] = soa_per_channel
,
1307 [TGSI_OPCODE_ADD
] = soa_per_channel
,
1308 [TGSI_OPCODE_DP3
] = soa_dot_product
,
1309 [TGSI_OPCODE_DP4
] = soa_dot_product
,
1310 [TGSI_OPCODE_DST
] = soa_DST
,
1311 [TGSI_OPCODE_MIN
] = soa_per_channel
,
1312 [TGSI_OPCODE_MAX
] = soa_per_channel
,
1313 [TGSI_OPCODE_SLT
] = soa_per_channel
,
1314 [TGSI_OPCODE_SGE
] = soa_per_channel
,
1315 [TGSI_OPCODE_MAD
] = soa_per_channel
,
1316 [TGSI_OPCODE_LRP
] = soa_per_channel
,
1317 [TGSI_OPCODE_SQRT
] = soa_scalar_replicate
,
1318 [TGSI_OPCODE_DP2A
] = soa_dot_product
,
1319 [TGSI_OPCODE_FRC
] = soa_per_channel
,
1320 [TGSI_OPCODE_CLAMP
] = soa_per_channel
,
1321 [TGSI_OPCODE_FLR
] = soa_per_channel
,
1322 [TGSI_OPCODE_ROUND
] = soa_per_channel
,
1323 [TGSI_OPCODE_EX2
] = soa_scalar_replicate
,
1324 [TGSI_OPCODE_LG2
] = soa_scalar_replicate
,
1325 [TGSI_OPCODE_POW
] = soa_scalar_replicate
,
1326 [TGSI_OPCODE_XPD
] = soa_XPD
,
1327 [TGSI_OPCODE_DPH
] = soa_dot_product
,
1328 [TGSI_OPCODE_COS
] = soa_scalar_replicate
,
1329 [TGSI_OPCODE_DDX
] = soa_partial_derivative
,
1330 [TGSI_OPCODE_DDY
] = soa_partial_derivative
,
1331 [TGSI_OPCODE_KILL
] = soa_passthrough
,
1332 [TGSI_OPCODE_PK2H
] = soa_PK2H
,
1333 [TGSI_OPCODE_PK2US
] = soa_unsupported
,
1334 [TGSI_OPCODE_PK4B
] = soa_unsupported
,
1335 [TGSI_OPCODE_PK4UB
] = soa_unsupported
,
1336 [TGSI_OPCODE_SEQ
] = soa_per_channel
,
1337 [TGSI_OPCODE_SGT
] = soa_per_channel
,
1338 [TGSI_OPCODE_SIN
] = soa_scalar_replicate
,
1339 [TGSI_OPCODE_SLE
] = soa_per_channel
,
1340 [TGSI_OPCODE_SNE
] = soa_per_channel
,
1341 [TGSI_OPCODE_TEX
] = soa_passthrough
,
1342 [TGSI_OPCODE_TXD
] = soa_passthrough
,
1343 [TGSI_OPCODE_TXP
] = soa_passthrough
,
1344 [TGSI_OPCODE_UP2H
] = soa_UP2H
,
1345 [TGSI_OPCODE_UP2US
] = soa_unsupported
,
1346 [TGSI_OPCODE_UP4B
] = soa_unsupported
,
1347 [TGSI_OPCODE_UP4UB
] = soa_unsupported
,
1348 [TGSI_OPCODE_ARR
] = soa_per_channel
,
1349 [TGSI_OPCODE_CAL
] = soa_unsupported
,
1350 [TGSI_OPCODE_RET
] = soa_unsupported
,
1351 [TGSI_OPCODE_SSG
] = soa_per_channel
,
1352 [TGSI_OPCODE_CMP
] = soa_per_channel
,
1353 [TGSI_OPCODE_SCS
] = soa_SCS
,
1354 [TGSI_OPCODE_TXB
] = soa_passthrough
,
1355 [TGSI_OPCODE_DIV
] = soa_per_channel
,
1356 [TGSI_OPCODE_DP2
] = soa_dot_product
,
1357 [TGSI_OPCODE_TXL
] = soa_passthrough
,
1358 [TGSI_OPCODE_BRK
] = soa_passthrough
,
1359 [TGSI_OPCODE_IF
] = soa_if
,
1360 [TGSI_OPCODE_UIF
] = soa_if
,
1361 [TGSI_OPCODE_ELSE
] = soa_passthrough
,
1362 [TGSI_OPCODE_ENDIF
] = soa_passthrough
,
1363 [TGSI_OPCODE_PUSHA
] = soa_unsupported
,
1364 [TGSI_OPCODE_POPA
] = soa_unsupported
,
1365 [TGSI_OPCODE_CEIL
] = soa_per_channel
,
1366 [TGSI_OPCODE_I2F
] = soa_per_channel
,
1367 [TGSI_OPCODE_NOT
] = soa_per_channel
,
1368 [TGSI_OPCODE_TRUNC
] = soa_per_channel
,
1369 [TGSI_OPCODE_SHL
] = soa_per_channel
,
1370 [TGSI_OPCODE_AND
] = soa_per_channel
,
1371 [TGSI_OPCODE_OR
] = soa_per_channel
,
1372 [TGSI_OPCODE_MOD
] = soa_per_channel
,
1373 [TGSI_OPCODE_XOR
] = soa_per_channel
,
1374 [TGSI_OPCODE_SAD
] = soa_per_channel
,
1375 [TGSI_OPCODE_TXF
] = soa_passthrough
,
1376 [TGSI_OPCODE_TXQ
] = soa_passthrough
,
1377 [TGSI_OPCODE_CONT
] = soa_passthrough
,
1378 [TGSI_OPCODE_EMIT
] = soa_unsupported
,
1379 [TGSI_OPCODE_ENDPRIM
] = soa_unsupported
,
1380 [TGSI_OPCODE_BGNLOOP
] = soa_passthrough
,
1381 [TGSI_OPCODE_BGNSUB
] = soa_unsupported
,
1382 [TGSI_OPCODE_ENDLOOP
] = soa_passthrough
,
1383 [TGSI_OPCODE_ENDSUB
] = soa_unsupported
,
1384 [TGSI_OPCODE_TXQ_LZ
] = soa_passthrough
,
1385 [TGSI_OPCODE_NOP
] = soa_passthrough
,
1386 [TGSI_OPCODE_FSEQ
] = soa_per_channel
,
1387 [TGSI_OPCODE_FSGE
] = soa_per_channel
,
1388 [TGSI_OPCODE_FSLT
] = soa_per_channel
,
1389 [TGSI_OPCODE_FSNE
] = soa_per_channel
,
1390 [TGSI_OPCODE_CALLNZ
] = soa_unsupported
,
1391 [TGSI_OPCODE_BREAKC
] = soa_unsupported
,
1392 [TGSI_OPCODE_KILL_IF
] = soa_passthrough
,
1393 [TGSI_OPCODE_END
] = soa_passthrough
,
1394 [TGSI_OPCODE_F2I
] = soa_per_channel
,
1395 [TGSI_OPCODE_IDIV
] = soa_per_channel
,
1396 [TGSI_OPCODE_IMAX
] = soa_per_channel
,
1397 [TGSI_OPCODE_IMIN
] = soa_per_channel
,
1398 [TGSI_OPCODE_INEG
] = soa_per_channel
,
1399 [TGSI_OPCODE_ISGE
] = soa_per_channel
,
1400 [TGSI_OPCODE_ISHR
] = soa_per_channel
,
1401 [TGSI_OPCODE_ISLT
] = soa_per_channel
,
1402 [TGSI_OPCODE_F2U
] = soa_per_channel
,
1403 [TGSI_OPCODE_U2F
] = soa_per_channel
,
1404 [TGSI_OPCODE_UADD
] = soa_per_channel
,
1405 [TGSI_OPCODE_UDIV
] = soa_per_channel
,
1406 [TGSI_OPCODE_UMAD
] = soa_per_channel
,
1407 [TGSI_OPCODE_UMAX
] = soa_per_channel
,
1408 [TGSI_OPCODE_UMIN
] = soa_per_channel
,
1409 [TGSI_OPCODE_UMOD
] = soa_per_channel
,
1410 [TGSI_OPCODE_UMUL
] = soa_per_channel
,
1411 [TGSI_OPCODE_USEQ
] = soa_per_channel
,
1412 [TGSI_OPCODE_USGE
] = soa_per_channel
,
1413 [TGSI_OPCODE_USHR
] = soa_per_channel
,
1414 [TGSI_OPCODE_USLT
] = soa_per_channel
,
1415 [TGSI_OPCODE_USNE
] = soa_per_channel
,
1416 [TGSI_OPCODE_SWITCH
] = soa_unsupported
,
1417 [TGSI_OPCODE_CASE
] = soa_unsupported
,
1418 [TGSI_OPCODE_DEFAULT
] = soa_unsupported
,
1419 [TGSI_OPCODE_ENDSWITCH
] = soa_unsupported
,
1420 [TGSI_OPCODE_SAMPLE
] = soa_passthrough
,
1421 [TGSI_OPCODE_SAMPLE_I
] = soa_passthrough
,
1422 [TGSI_OPCODE_SAMPLE_I_MS
] = soa_passthrough
,
1423 [TGSI_OPCODE_SAMPLE_B
] = soa_passthrough
,
1424 [TGSI_OPCODE_SAMPLE_C
] = soa_passthrough
,
1425 [TGSI_OPCODE_SAMPLE_C_LZ
] = soa_passthrough
,
1426 [TGSI_OPCODE_SAMPLE_D
] = soa_passthrough
,
1427 [TGSI_OPCODE_SAMPLE_L
] = soa_passthrough
,
1428 [TGSI_OPCODE_GATHER4
] = soa_passthrough
,
1429 [TGSI_OPCODE_SVIEWINFO
] = soa_passthrough
,
1430 [TGSI_OPCODE_SAMPLE_POS
] = soa_passthrough
,
1431 [TGSI_OPCODE_SAMPLE_INFO
] = soa_passthrough
,
1432 [TGSI_OPCODE_UARL
] = soa_per_channel
,
1433 [TGSI_OPCODE_UCMP
] = soa_per_channel
,
1434 [TGSI_OPCODE_IABS
] = soa_per_channel
,
1435 [TGSI_OPCODE_ISSG
] = soa_per_channel
,
1436 [TGSI_OPCODE_LOAD
] = soa_unsupported
,
1437 [TGSI_OPCODE_STORE
] = soa_unsupported
,
1438 [TGSI_OPCODE_MFENCE
] = soa_unsupported
,
1439 [TGSI_OPCODE_LFENCE
] = soa_unsupported
,
1440 [TGSI_OPCODE_SFENCE
] = soa_unsupported
,
1441 [TGSI_OPCODE_BARRIER
] = soa_unsupported
,
1442 [TGSI_OPCODE_ATOMUADD
] = soa_unsupported
,
1443 [TGSI_OPCODE_ATOMXCHG
] = soa_unsupported
,
1444 [TGSI_OPCODE_ATOMCAS
] = soa_unsupported
,
1445 [TGSI_OPCODE_ATOMAND
] = soa_unsupported
,
1446 [TGSI_OPCODE_ATOMOR
] = soa_unsupported
,
1447 [TGSI_OPCODE_ATOMXOR
] = soa_unsupported
,
1448 [TGSI_OPCODE_ATOMUMIN
] = soa_unsupported
,
1449 [TGSI_OPCODE_ATOMUMAX
] = soa_unsupported
,
1450 [TGSI_OPCODE_ATOMIMIN
] = soa_unsupported
,
1451 [TGSI_OPCODE_ATOMIMAX
] = soa_unsupported
,
1452 [TGSI_OPCODE_TEX2
] = soa_passthrough
,
1453 [TGSI_OPCODE_TXB2
] = soa_passthrough
,
1454 [TGSI_OPCODE_TXL2
] = soa_passthrough
,
1458 ra_dst_is_indirect(const struct tgsi_full_dst_register
*d
)
1460 return (d
->Register
.Indirect
||
1461 (d
->Register
.Dimension
&& d
->Dimension
.Indirect
));
1465 ra_dst_index(const struct tgsi_full_dst_register
*d
)
1467 assert(!d
->Register
.Indirect
);
1468 return d
->Register
.Index
;
1472 ra_dst_dimension(const struct tgsi_full_dst_register
*d
)
1474 if (d
->Register
.Dimension
) {
1475 assert(!d
->Dimension
.Indirect
);
1476 return d
->Dimension
.Index
;
1484 ra_is_src_indirect(const struct tgsi_full_src_register
*s
)
1486 return (s
->Register
.Indirect
||
1487 (s
->Register
.Dimension
&& s
->Dimension
.Indirect
));
1491 ra_src_index(const struct tgsi_full_src_register
*s
)
1493 assert(!s
->Register
.Indirect
);
1494 return s
->Register
.Index
;
1498 ra_src_dimension(const struct tgsi_full_src_register
*s
)
1500 if (s
->Register
.Dimension
) {
1501 assert(!s
->Dimension
.Indirect
);
1502 return s
->Dimension
.Index
;
1510 * Infer the type of either the sources or the destination.
1512 static enum toy_type
1513 ra_infer_opcode_type(int tgsi_opcode
, bool is_dst
)
1515 enum tgsi_opcode_type type
;
1518 type
= tgsi_opcode_infer_dst_type(tgsi_opcode
);
1520 type
= tgsi_opcode_infer_src_type(tgsi_opcode
);
1523 case TGSI_TYPE_UNSIGNED
:
1525 case TGSI_TYPE_SIGNED
:
1527 case TGSI_TYPE_FLOAT
:
1529 case TGSI_TYPE_UNTYPED
:
1530 case TGSI_TYPE_VOID
:
1531 case TGSI_TYPE_DOUBLE
:
1533 assert(!"unsupported TGSI type");
1539 * Return the type of an operand of the specified instruction.
1541 static enum toy_type
1542 ra_get_type(struct toy_tgsi
*tgsi
, const struct tgsi_full_instruction
*tgsi_inst
,
1543 int operand
, bool is_dst
)
1546 enum tgsi_file_type file
;
1548 /* we need to look at both src and dst for MOV */
1549 /* XXX it should not be this complex */
1550 if (tgsi_inst
->Instruction
.Opcode
== TGSI_OPCODE_MOV
) {
1551 const enum tgsi_file_type dst_file
= tgsi_inst
->Dst
[0].Register
.File
;
1552 const enum tgsi_file_type src_file
= tgsi_inst
->Src
[0].Register
.File
;
1554 if (dst_file
== TGSI_FILE_ADDRESS
|| src_file
== TGSI_FILE_ADDRESS
) {
1557 else if (src_file
== TGSI_FILE_IMMEDIATE
&&
1558 !tgsi_inst
->Src
[0].Register
.Indirect
) {
1559 const int src_idx
= tgsi_inst
->Src
[0].Register
.Index
;
1560 type
= tgsi
->imm_data
.types
[src_idx
];
1563 /* this is the best we can do */
1569 else if (tgsi_inst
->Instruction
.Opcode
== TGSI_OPCODE_UCMP
) {
1570 if (!is_dst
&& operand
== 0)
1578 type
= ra_infer_opcode_type(tgsi_inst
->Instruction
.Opcode
, is_dst
);
1582 tgsi_inst
->Dst
[operand
].Register
.File
:
1583 tgsi_inst
->Src
[operand
].Register
.File
;
1585 case TGSI_FILE_SAMPLER
:
1586 case TGSI_FILE_IMAGE
:
1587 case TGSI_FILE_SAMPLER_VIEW
:
1590 case TGSI_FILE_ADDRESS
:
1591 assert(type
== TOY_TYPE_D
);
1601 * Allocate a VRF register.
1604 ra_alloc_reg(struct toy_tgsi
*tgsi
, enum tgsi_file_type file
)
1606 const int count
= (tgsi
->aos
) ? 1 : 4;
1607 return tc_alloc_vrf(tgsi
->tc
, count
);
1611 * Construct the key for VRF mapping look-up.
1614 ra_get_map_key(enum tgsi_file_type file
, unsigned dim
, unsigned index
)
1618 /* this is ugly... */
1619 assert(file
< 1 << 4);
1620 assert(dim
< 1 << 12);
1621 assert(index
< 1 << 16);
1622 key
= (file
<< 28) | (dim
<< 16) | index
;
1624 return intptr_to_pointer(key
);
1628 * Map a TGSI register to a VRF register.
1631 ra_map_reg(struct toy_tgsi
*tgsi
, enum tgsi_file_type file
,
1632 int dim
, int index
, bool *is_new
)
1637 key
= ra_get_map_key(file
, dim
, index
);
1640 * because we allocate vrf from 1 and on, val is never NULL as long as the
1643 val
= util_hash_table_get(tgsi
->reg_mapping
, key
);
1645 vrf
= pointer_to_intptr(val
);
1651 vrf
= (intptr_t) ra_alloc_reg(tgsi
, file
);
1653 /* add to the mapping */
1654 val
= intptr_to_pointer(vrf
);
1655 util_hash_table_set(tgsi
->reg_mapping
, key
, val
);
1665 * Return true if the destination aliases any of the sources.
1668 ra_dst_is_aliasing(const struct tgsi_full_instruction
*tgsi_inst
, int dst_index
)
1670 const struct tgsi_full_dst_register
*d
= &tgsi_inst
->Dst
[dst_index
];
1673 /* we need a scratch register for indirect dst anyway */
1674 if (ra_dst_is_indirect(d
))
1677 for (i
= 0; i
< tgsi_inst
->Instruction
.NumSrcRegs
; i
++) {
1678 const struct tgsi_full_src_register
*s
= &tgsi_inst
->Src
[i
];
1680 if (s
->Register
.File
!= d
->Register
.File
)
1684 * we can go on to check dimension and index respectively, but
1685 * keep it simple for now
1687 if (ra_is_src_indirect(s
))
1689 if (ra_src_dimension(s
) == ra_dst_dimension(d
) &&
1690 ra_src_index(s
) == ra_dst_index(d
))
1698 * Return the toy register for a TGSI destination operand.
1700 static struct toy_dst
1701 ra_get_dst(struct toy_tgsi
*tgsi
,
1702 const struct tgsi_full_instruction
*tgsi_inst
, int dst_index
,
1705 const struct tgsi_full_dst_register
*d
= &tgsi_inst
->Dst
[dst_index
];
1706 bool need_vrf
= false;
1709 switch (d
->Register
.File
) {
1710 case TGSI_FILE_NULL
:
1713 case TGSI_FILE_OUTPUT
:
1714 case TGSI_FILE_TEMPORARY
:
1715 case TGSI_FILE_ADDRESS
:
1716 case TGSI_FILE_PREDICATE
:
1720 assert(!"unhandled dst file");
1726 /* XXX we do not always need a scratch given the conditions... */
1727 const bool need_scratch
=
1728 (ra_dst_is_indirect(d
) || ra_dst_is_aliasing(tgsi_inst
, dst_index
) ||
1729 tgsi_inst
->Instruction
.Saturate
);
1730 const enum toy_type type
= ra_get_type(tgsi
, tgsi_inst
, dst_index
, true);
1734 vrf
= ra_alloc_reg(tgsi
, d
->Register
.File
);
1737 vrf
= ra_map_reg(tgsi
, d
->Register
.File
,
1738 ra_dst_dimension(d
), ra_dst_index(d
), NULL
);
1742 *is_scratch
= need_scratch
;
1744 dst
= tdst_full(TOY_FILE_VRF
, type
, TOY_RECT_LINEAR
,
1745 false, 0, d
->Register
.WriteMask
, vrf
* TOY_REG_WIDTH
);
1751 static struct toy_src
1752 ra_get_src_for_vrf(const struct tgsi_full_src_register
*s
,
1753 enum toy_type type
, int vrf
)
1755 return tsrc_full(TOY_FILE_VRF
, type
, TOY_RECT_LINEAR
,
1757 s
->Register
.SwizzleX
, s
->Register
.SwizzleY
,
1758 s
->Register
.SwizzleZ
, s
->Register
.SwizzleW
,
1759 s
->Register
.Absolute
, s
->Register
.Negate
,
1760 vrf
* TOY_REG_WIDTH
);
1764 init_tgsi_reg(struct toy_tgsi
*tgsi
, struct toy_inst
*inst
,
1765 enum tgsi_file_type file
, int index
,
1766 const struct tgsi_ind_register
*indirect
,
1767 const struct tgsi_dimension
*dimension
,
1768 const struct tgsi_ind_register
*dim_indirect
)
1773 /* src[0]: TGSI file */
1774 inst
->src
[num_src
++] = tsrc_imm_d(file
);
1776 /* src[1]: TGSI dimension */
1777 inst
->src
[num_src
++] = tsrc_imm_d((dimension
) ? dimension
->Index
: 0);
1779 /* src[2]: TGSI dimension indirection */
1781 const int vrf
= ra_map_reg(tgsi
, dim_indirect
->File
, 0,
1782 dim_indirect
->Index
, NULL
);
1784 src
= tsrc(TOY_FILE_VRF
, vrf
, 0);
1785 src
= tsrc_swizzle1(tsrc_d(src
), indirect
->Swizzle
);
1788 src
= tsrc_imm_d(0);
1791 inst
->src
[num_src
++] = src
;
1793 /* src[3]: TGSI index */
1794 inst
->src
[num_src
++] = tsrc_imm_d(index
);
1796 /* src[4]: TGSI index indirection */
1798 const int vrf
= ra_map_reg(tgsi
, indirect
->File
, 0,
1799 indirect
->Index
, NULL
);
1801 src
= tsrc(TOY_FILE_VRF
, vrf
, 0);
1802 src
= tsrc_swizzle1(tsrc_d(src
), indirect
->Swizzle
);
1805 src
= tsrc_imm_d(0);
1808 inst
->src
[num_src
++] = src
;
1813 static struct toy_src
1814 ra_get_src_indirect(struct toy_tgsi
*tgsi
,
1815 const struct tgsi_full_instruction
*tgsi_inst
,
1818 const struct tgsi_full_src_register
*s
= &tgsi_inst
->Src
[src_index
];
1819 bool need_vrf
= false, is_resource
= false;
1822 switch (s
->Register
.File
) {
1823 case TGSI_FILE_NULL
:
1826 case TGSI_FILE_SAMPLER
:
1827 case TGSI_FILE_IMAGE
:
1828 case TGSI_FILE_SAMPLER_VIEW
:
1831 case TGSI_FILE_CONSTANT
:
1832 case TGSI_FILE_INPUT
:
1833 case TGSI_FILE_SYSTEM_VALUE
:
1834 case TGSI_FILE_TEMPORARY
:
1835 case TGSI_FILE_ADDRESS
:
1836 case TGSI_FILE_IMMEDIATE
:
1837 case TGSI_FILE_PREDICATE
:
1841 assert(!"unhandled src file");
1847 const enum toy_type type
= ra_get_type(tgsi
, tgsi_inst
, src_index
, false);
1851 assert(!s
->Register
.Dimension
);
1852 assert(s
->Register
.Indirect
);
1854 vrf
= ra_map_reg(tgsi
, s
->Indirect
.File
, 0, s
->Indirect
.Index
, NULL
);
1857 vrf
= ra_alloc_reg(tgsi
, s
->Register
.File
);
1860 src
= ra_get_src_for_vrf(s
, type
, vrf
);
1862 /* emit indirect fetch */
1864 struct toy_inst
*inst
;
1866 inst
= tc_add(tgsi
->tc
);
1867 inst
->opcode
= TOY_OPCODE_TGSI_INDIRECT_FETCH
;
1868 inst
->dst
= tdst_from(src
);
1869 inst
->dst
.writemask
= TOY_WRITEMASK_XYZW
;
1871 init_tgsi_reg(tgsi
, inst
, s
->Register
.File
, s
->Register
.Index
,
1872 (s
->Register
.Indirect
) ? &s
->Indirect
: NULL
,
1873 (s
->Register
.Dimension
) ? &s
->Dimension
: NULL
,
1874 (s
->Dimension
.Indirect
) ? &s
->DimIndirect
: NULL
);
1882 * Return the toy register for a TGSI source operand.
1884 static struct toy_src
1885 ra_get_src(struct toy_tgsi
*tgsi
,
1886 const struct tgsi_full_instruction
*tgsi_inst
,
1889 const struct tgsi_full_src_register
*s
= &tgsi_inst
->Src
[src_index
];
1890 bool need_vrf
= false;
1893 if (ra_is_src_indirect(s
))
1894 return ra_get_src_indirect(tgsi
, tgsi_inst
, src_index
);
1896 switch (s
->Register
.File
) {
1897 case TGSI_FILE_NULL
:
1900 case TGSI_FILE_CONSTANT
:
1901 case TGSI_FILE_INPUT
:
1902 case TGSI_FILE_SYSTEM_VALUE
:
1905 case TGSI_FILE_TEMPORARY
:
1906 case TGSI_FILE_ADDRESS
:
1907 case TGSI_FILE_PREDICATE
:
1910 case TGSI_FILE_SAMPLER
:
1911 case TGSI_FILE_IMAGE
:
1912 case TGSI_FILE_SAMPLER_VIEW
:
1913 assert(!s
->Register
.Dimension
);
1914 src
= tsrc_imm_d(s
->Register
.Index
);
1916 case TGSI_FILE_IMMEDIATE
:
1918 const uint32_t *imm
;
1919 enum toy_type imm_type
;
1922 imm
= toy_tgsi_get_imm(tgsi
, s
->Register
.Index
, &imm_type
);
1925 (imm
[s
->Register
.SwizzleX
] == imm
[s
->Register
.SwizzleY
] &&
1926 imm
[s
->Register
.SwizzleX
] == imm
[s
->Register
.SwizzleZ
] &&
1927 imm
[s
->Register
.SwizzleX
] == imm
[s
->Register
.SwizzleW
]);
1930 const enum toy_type type
=
1931 ra_get_type(tgsi
, tgsi_inst
, src_index
, false);
1933 /* ignore imm_type */
1934 src
= tsrc_imm_ud(imm
[s
->Register
.SwizzleX
]);
1936 src
.absolute
= s
->Register
.Absolute
;
1937 src
.negate
= s
->Register
.Negate
;
1945 assert(!"unhandled src file");
1951 const enum toy_type type
= ra_get_type(tgsi
, tgsi_inst
, src_index
, false);
1955 vrf
= ra_map_reg(tgsi
, s
->Register
.File
,
1956 ra_src_dimension(s
), ra_src_index(s
), &is_new
);
1958 src
= ra_get_src_for_vrf(s
, type
, vrf
);
1961 switch (s
->Register
.File
) {
1962 case TGSI_FILE_TEMPORARY
:
1963 case TGSI_FILE_ADDRESS
:
1964 case TGSI_FILE_PREDICATE
:
1966 struct toy_dst dst
= tdst_from(src
);
1967 dst
.writemask
= TOY_WRITEMASK_XYZW
;
1969 /* always initialize registers before use */
1971 tc_MOV(tgsi
->tc
, dst
, tsrc_type(tsrc_imm_d(0), type
));
1974 struct toy_dst tdst
[4];
1977 tdst_transpose(dst
, tdst
);
1979 for (i
= 0; i
< 4; i
++) {
1980 tc_MOV(tgsi
->tc
, tdst
[i
],
1981 tsrc_type(tsrc_imm_d(0), type
));
1997 parse_instruction(struct toy_tgsi
*tgsi
,
1998 const struct tgsi_full_instruction
*tgsi_inst
)
2000 struct toy_dst dst
[TGSI_FULL_MAX_DST_REGISTERS
];
2001 struct toy_src src
[TGSI_FULL_MAX_SRC_REGISTERS
];
2002 bool dst_is_scratch
[TGSI_FULL_MAX_DST_REGISTERS
];
2003 toy_tgsi_translate translate
;
2006 /* convert TGSI registers to toy registers */
2007 for (i
= 0; i
< tgsi_inst
->Instruction
.NumSrcRegs
; i
++)
2008 src
[i
] = ra_get_src(tgsi
, tgsi_inst
, i
);
2009 for (i
= 0; i
< tgsi_inst
->Instruction
.NumDstRegs
; i
++)
2010 dst
[i
] = ra_get_dst(tgsi
, tgsi_inst
, i
, &dst_is_scratch
[i
]);
2012 /* translate the instruction */
2013 translate
= tgsi
->translate_table
[tgsi_inst
->Instruction
.Opcode
];
2015 if (tgsi
->translate_table
== soa_translate_table
)
2016 soa_unsupported(tgsi
->tc
, tgsi_inst
, dst
, src
);
2018 aos_unsupported(tgsi
->tc
, tgsi_inst
, dst
, src
);
2020 translate(tgsi
->tc
, tgsi_inst
, dst
, src
);
2022 /* write the result to the real destinations if needed */
2023 for (i
= 0; i
< tgsi_inst
->Instruction
.NumDstRegs
; i
++) {
2024 const struct tgsi_full_dst_register
*d
= &tgsi_inst
->Dst
[i
];
2026 if (!dst_is_scratch
[i
])
2029 tgsi
->tc
->templ
.saturate
= tgsi_inst
->Instruction
.Saturate
;
2031 /* emit indirect store */
2032 if (ra_dst_is_indirect(d
)) {
2033 struct toy_inst
*inst
;
2035 inst
= tc_add(tgsi
->tc
);
2036 inst
->opcode
= TOY_OPCODE_TGSI_INDIRECT_STORE
;
2039 init_tgsi_reg(tgsi
, inst
, d
->Register
.File
, d
->Register
.Index
,
2040 (d
->Register
.Indirect
) ? &d
->Indirect
: NULL
,
2041 (d
->Register
.Dimension
) ? &d
->Dimension
: NULL
,
2042 (d
->Dimension
.Indirect
) ? &d
->DimIndirect
: NULL
);
2045 const enum toy_type type
= ra_get_type(tgsi
, tgsi_inst
, i
, true);
2046 struct toy_dst real_dst
;
2049 vrf
= ra_map_reg(tgsi
, d
->Register
.File
,
2050 ra_dst_dimension(d
), ra_dst_index(d
), NULL
);
2051 real_dst
= tdst_full(TOY_FILE_VRF
, type
, TOY_RECT_LINEAR
,
2052 false, 0, d
->Register
.WriteMask
, vrf
* TOY_REG_WIDTH
);
2055 tc_MOV(tgsi
->tc
, real_dst
, tsrc_from(dst
[i
]));
2058 struct toy_dst tdst
[4];
2059 struct toy_src tsrc
[4];
2062 tdst_transpose(real_dst
, tdst
);
2063 tsrc_transpose(tsrc_from(dst
[i
]), tsrc
);
2065 for (j
= 0; j
< 4; j
++)
2066 tc_MOV(tgsi
->tc
, tdst
[j
], tsrc
[j
]);
2070 tgsi
->tc
->templ
.saturate
= false;
2073 switch (tgsi_inst
->Instruction
.Opcode
) {
2074 case TGSI_OPCODE_KILL_IF
:
2075 case TGSI_OPCODE_KILL
:
2076 tgsi
->uses_kill
= true;
2080 for (i
= 0; i
< tgsi_inst
->Instruction
.NumSrcRegs
; i
++) {
2081 const struct tgsi_full_src_register
*s
= &tgsi_inst
->Src
[i
];
2082 if (s
->Register
.File
== TGSI_FILE_CONSTANT
&& s
->Register
.Indirect
)
2083 tgsi
->const_indirect
= true;
2086 /* remember channels written */
2087 for (i
= 0; i
< tgsi_inst
->Instruction
.NumDstRegs
; i
++) {
2088 const struct tgsi_full_dst_register
*d
= &tgsi_inst
->Dst
[i
];
2090 if (d
->Register
.File
!= TGSI_FILE_OUTPUT
)
2092 for (i
= 0; i
< tgsi
->num_outputs
; i
++) {
2093 if (tgsi
->outputs
[i
].index
== d
->Register
.Index
) {
2094 tgsi
->outputs
[i
].undefined_mask
&= ~d
->Register
.WriteMask
;
2102 decl_add_in(struct toy_tgsi
*tgsi
, const struct tgsi_full_declaration
*decl
)
2104 static const struct tgsi_declaration_interp default_interp
= {
2105 TGSI_INTERPOLATE_PERSPECTIVE
, false, 0,
2107 const struct tgsi_declaration_interp
*interp
=
2108 (decl
->Declaration
.Interpolate
) ? &decl
->Interp
: &default_interp
;
2111 if (decl
->Range
.Last
>= ARRAY_SIZE(tgsi
->inputs
)) {
2112 assert(!"invalid IN");
2116 for (index
= decl
->Range
.First
; index
<= decl
->Range
.Last
; index
++) {
2117 const int slot
= tgsi
->num_inputs
++;
2119 tgsi
->inputs
[slot
].index
= index
;
2120 tgsi
->inputs
[slot
].usage_mask
= decl
->Declaration
.UsageMask
;
2121 if (decl
->Declaration
.Semantic
) {
2122 tgsi
->inputs
[slot
].semantic_name
= decl
->Semantic
.Name
;
2123 tgsi
->inputs
[slot
].semantic_index
= decl
->Semantic
.Index
;
2126 tgsi
->inputs
[slot
].semantic_name
= TGSI_SEMANTIC_GENERIC
;
2127 tgsi
->inputs
[slot
].semantic_index
= index
;
2129 tgsi
->inputs
[slot
].interp
= interp
->Interpolate
;
2130 tgsi
->inputs
[slot
].centroid
= interp
->Location
== TGSI_INTERPOLATE_LOC_CENTROID
;
2135 decl_add_out(struct toy_tgsi
*tgsi
, const struct tgsi_full_declaration
*decl
)
2139 if (decl
->Range
.Last
>= ARRAY_SIZE(tgsi
->outputs
)) {
2140 assert(!"invalid OUT");
2144 assert(decl
->Declaration
.Semantic
);
2146 for (index
= decl
->Range
.First
; index
<= decl
->Range
.Last
; index
++) {
2147 const int slot
= tgsi
->num_outputs
++;
2149 tgsi
->outputs
[slot
].index
= index
;
2150 tgsi
->outputs
[slot
].undefined_mask
= TOY_WRITEMASK_XYZW
;
2151 tgsi
->outputs
[slot
].usage_mask
= decl
->Declaration
.UsageMask
;
2152 tgsi
->outputs
[slot
].semantic_name
= decl
->Semantic
.Name
;
2153 tgsi
->outputs
[slot
].semantic_index
= decl
->Semantic
.Index
;
2158 decl_add_sv(struct toy_tgsi
*tgsi
, const struct tgsi_full_declaration
*decl
)
2162 if (decl
->Range
.Last
>= ARRAY_SIZE(tgsi
->system_values
)) {
2163 assert(!"invalid SV");
2167 for (index
= decl
->Range
.First
; index
<= decl
->Range
.Last
; index
++) {
2168 const int slot
= tgsi
->num_system_values
++;
2170 tgsi
->system_values
[slot
].index
= index
;
2171 if (decl
->Declaration
.Semantic
) {
2172 tgsi
->system_values
[slot
].semantic_name
= decl
->Semantic
.Name
;
2173 tgsi
->system_values
[slot
].semantic_index
= decl
->Semantic
.Index
;
2176 tgsi
->system_values
[slot
].semantic_name
= TGSI_SEMANTIC_GENERIC
;
2177 tgsi
->system_values
[slot
].semantic_index
= index
;
2183 * Emit an instruction to fetch the value of a TGSI register.
2186 fetch_source(struct toy_tgsi
*tgsi
, enum tgsi_file_type file
, int dim
, int idx
)
2190 enum toy_opcode opcode
;
2191 enum toy_type type
= TOY_TYPE_F
;
2194 case TGSI_FILE_INPUT
:
2195 opcode
= TOY_OPCODE_TGSI_IN
;
2197 case TGSI_FILE_CONSTANT
:
2198 opcode
= TOY_OPCODE_TGSI_CONST
;
2200 case TGSI_FILE_SYSTEM_VALUE
:
2201 opcode
= TOY_OPCODE_TGSI_SV
;
2203 case TGSI_FILE_IMMEDIATE
:
2204 opcode
= TOY_OPCODE_TGSI_IMM
;
2205 toy_tgsi_get_imm(tgsi
, idx
, &type
);
2208 /* no need to fetch */
2213 vrf
= ra_map_reg(tgsi
, file
, dim
, idx
, NULL
);
2214 dst
= tdst(TOY_FILE_VRF
, vrf
, 0);
2215 dst
= tdst_type(dst
, type
);
2217 tc_add2(tgsi
->tc
, opcode
, dst
, tsrc_imm_d(dim
), tsrc_imm_d(idx
));
2221 parse_declaration(struct toy_tgsi
*tgsi
,
2222 const struct tgsi_full_declaration
*decl
)
2226 switch (decl
->Declaration
.File
) {
2227 case TGSI_FILE_INPUT
:
2228 decl_add_in(tgsi
, decl
);
2230 case TGSI_FILE_OUTPUT
:
2231 decl_add_out(tgsi
, decl
);
2233 case TGSI_FILE_SYSTEM_VALUE
:
2234 decl_add_sv(tgsi
, decl
);
2236 case TGSI_FILE_IMMEDIATE
:
2237 /* immediates should be declared with TGSI_TOKEN_TYPE_IMMEDIATE */
2238 assert(!"unexpected immediate declaration");
2240 case TGSI_FILE_CONSTANT
:
2241 if (tgsi
->const_count
<= decl
->Range
.Last
)
2242 tgsi
->const_count
= decl
->Range
.Last
+ 1;
2244 case TGSI_FILE_NULL
:
2245 case TGSI_FILE_TEMPORARY
:
2246 case TGSI_FILE_SAMPLER
:
2247 case TGSI_FILE_PREDICATE
:
2248 case TGSI_FILE_ADDRESS
:
2249 case TGSI_FILE_IMAGE
:
2250 case TGSI_FILE_SAMPLER_VIEW
:
2254 assert(!"unhandled TGSI file");
2258 /* fetch the registers now */
2259 for (i
= decl
->Range
.First
; i
<= decl
->Range
.Last
; i
++) {
2260 const int dim
= (decl
->Declaration
.Dimension
) ? decl
->Dim
.Index2D
: 0;
2261 fetch_source(tgsi
, decl
->Declaration
.File
, dim
, i
);
2266 add_imm(struct toy_tgsi
*tgsi
, enum toy_type type
, const uint32_t *buf
)
2268 /* reallocate the buffer if necessary */
2269 if (tgsi
->imm_data
.cur
>= tgsi
->imm_data
.size
) {
2270 const int cur_size
= tgsi
->imm_data
.size
;
2272 enum toy_type
*new_types
;
2273 uint32_t (*new_buf
)[4];
2275 new_size
= (cur_size
) ? cur_size
<< 1 : 16;
2276 while (new_size
<= tgsi
->imm_data
.cur
)
2279 new_buf
= REALLOC(tgsi
->imm_data
.buf
,
2280 cur_size
* sizeof(new_buf
[0]),
2281 new_size
* sizeof(new_buf
[0]));
2282 new_types
= REALLOC(tgsi
->imm_data
.types
,
2283 cur_size
* sizeof(new_types
[0]),
2284 new_size
* sizeof(new_types
[0]));
2285 if (!new_buf
|| !new_types
) {
2291 tgsi
->imm_data
.buf
= new_buf
;
2292 tgsi
->imm_data
.types
= new_types
;
2293 tgsi
->imm_data
.size
= new_size
;
2296 tgsi
->imm_data
.types
[tgsi
->imm_data
.cur
] = type
;
2297 memcpy(&tgsi
->imm_data
.buf
[tgsi
->imm_data
.cur
],
2298 buf
, sizeof(tgsi
->imm_data
.buf
[0]));
2300 return tgsi
->imm_data
.cur
++;
2304 parse_immediate(struct toy_tgsi
*tgsi
, const struct tgsi_full_immediate
*imm
)
2307 uint32_t imm_buf
[4];
2310 switch (imm
->Immediate
.DataType
) {
2311 case TGSI_IMM_FLOAT32
:
2313 imm_buf
[0] = fui(imm
->u
[0].Float
);
2314 imm_buf
[1] = fui(imm
->u
[1].Float
);
2315 imm_buf
[2] = fui(imm
->u
[2].Float
);
2316 imm_buf
[3] = fui(imm
->u
[3].Float
);
2318 case TGSI_IMM_INT32
:
2320 imm_buf
[0] = (uint32_t) imm
->u
[0].Int
;
2321 imm_buf
[1] = (uint32_t) imm
->u
[1].Int
;
2322 imm_buf
[2] = (uint32_t) imm
->u
[2].Int
;
2323 imm_buf
[3] = (uint32_t) imm
->u
[3].Int
;
2325 case TGSI_IMM_UINT32
:
2327 imm_buf
[0] = imm
->u
[0].Uint
;
2328 imm_buf
[1] = imm
->u
[1].Uint
;
2329 imm_buf
[2] = imm
->u
[2].Uint
;
2330 imm_buf
[3] = imm
->u
[3].Uint
;
2333 assert(!"unhandled TGSI imm type");
2335 memset(imm_buf
, 0, sizeof(imm_buf
));
2339 idx
= add_imm(tgsi
, type
, imm_buf
);
2341 fetch_source(tgsi
, TGSI_FILE_IMMEDIATE
, 0, idx
);
2343 tc_fail(tgsi
->tc
, "failed to add TGSI imm");
2347 parse_property(struct toy_tgsi
*tgsi
, const struct tgsi_full_property
*prop
)
2349 switch (prop
->Property
.PropertyName
) {
2350 case TGSI_PROPERTY_VS_PROHIBIT_UCPS
:
2351 tgsi
->props
.vs_prohibit_ucps
= prop
->u
[0].Data
;
2353 case TGSI_PROPERTY_FS_COORD_ORIGIN
:
2354 tgsi
->props
.fs_coord_origin
= prop
->u
[0].Data
;
2356 case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER
:
2357 tgsi
->props
.fs_coord_pixel_center
= prop
->u
[0].Data
;
2359 case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS
:
2360 tgsi
->props
.fs_color0_writes_all_cbufs
= prop
->u
[0].Data
;
2362 case TGSI_PROPERTY_FS_DEPTH_LAYOUT
:
2363 tgsi
->props
.fs_depth_layout
= prop
->u
[0].Data
;
2365 case TGSI_PROPERTY_GS_INPUT_PRIM
:
2366 tgsi
->props
.gs_input_prim
= prop
->u
[0].Data
;
2368 case TGSI_PROPERTY_GS_OUTPUT_PRIM
:
2369 tgsi
->props
.gs_output_prim
= prop
->u
[0].Data
;
2371 case TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES
:
2372 tgsi
->props
.gs_max_output_vertices
= prop
->u
[0].Data
;
2375 assert(!"unhandled TGSI property");
2381 parse_token(struct toy_tgsi
*tgsi
, const union tgsi_full_token
*token
)
2383 switch (token
->Token
.Type
) {
2384 case TGSI_TOKEN_TYPE_DECLARATION
:
2385 parse_declaration(tgsi
, &token
->FullDeclaration
);
2387 case TGSI_TOKEN_TYPE_IMMEDIATE
:
2388 parse_immediate(tgsi
, &token
->FullImmediate
);
2390 case TGSI_TOKEN_TYPE_INSTRUCTION
:
2391 parse_instruction(tgsi
, &token
->FullInstruction
);
2393 case TGSI_TOKEN_TYPE_PROPERTY
:
2394 parse_property(tgsi
, &token
->FullProperty
);
2397 assert(!"unhandled TGSI token type");
2402 static enum pipe_error
2403 dump_reg_mapping(void *key
, void *val
, void *data
)
2405 int tgsi_file
, tgsi_dim
, tgsi_index
;
2408 sig
= (uint32_t) pointer_to_intptr(key
);
2409 vrf
= (uint32_t) pointer_to_intptr(val
);
2411 /* see ra_get_map_key() */
2412 tgsi_file
= (sig
>> 28) & 0xf;
2413 tgsi_dim
= (sig
>> 16) & 0xfff;
2414 tgsi_index
= (sig
>> 0) & 0xffff;
2417 ilo_printf(" v%d:\t%s[%d][%d]\n", vrf
,
2418 tgsi_file_name(tgsi_file
), tgsi_dim
, tgsi_index
);
2421 ilo_printf(" v%d:\t%s[%d]\n", vrf
,
2422 tgsi_file_name(tgsi_file
), tgsi_index
);
2429 * Dump the TGSI translator, currently only the register mapping.
2432 toy_tgsi_dump(const struct toy_tgsi
*tgsi
)
2434 util_hash_table_foreach(tgsi
->reg_mapping
, dump_reg_mapping
, NULL
);
2438 * Clean up the TGSI translator.
2441 toy_tgsi_cleanup(struct toy_tgsi
*tgsi
)
2443 FREE(tgsi
->imm_data
.buf
);
2444 FREE(tgsi
->imm_data
.types
);
2446 util_hash_table_destroy(tgsi
->reg_mapping
);
2450 reg_mapping_hash(void *key
)
2452 return (unsigned) pointer_to_intptr(key
);
2456 reg_mapping_compare(void *key1
, void *key2
)
2458 return (key1
!= key2
);
2462 * Initialize the TGSI translator.
2465 init_tgsi(struct toy_tgsi
*tgsi
, struct toy_compiler
*tc
, bool aos
)
2467 memset(tgsi
, 0, sizeof(*tgsi
));
2471 tgsi
->translate_table
= (aos
) ? aos_translate_table
: soa_translate_table
;
2473 /* create a mapping of TGSI registers to VRF reigsters */
2475 util_hash_table_create(reg_mapping_hash
, reg_mapping_compare
);
2477 return (tgsi
->reg_mapping
!= NULL
);
2481 * Translate TGSI tokens into toy instructions.
2484 toy_compiler_translate_tgsi(struct toy_compiler
*tc
,
2485 const struct tgsi_token
*tokens
, bool aos
,
2486 struct toy_tgsi
*tgsi
)
2488 struct tgsi_parse_context parse
;
2490 if (!init_tgsi(tgsi
, tc
, aos
)) {
2491 tc_fail(tc
, "failed to initialize TGSI translator");
2495 tgsi_parse_init(&parse
, tokens
);
2496 while (!tgsi_parse_end_of_tokens(&parse
)) {
2497 tgsi_parse_token(&parse
);
2498 parse_token(tgsi
, &parse
.FullToken
);
2500 tgsi_parse_free(&parse
);
2504 * Map the TGSI register to VRF register.
2507 toy_tgsi_get_vrf(const struct toy_tgsi
*tgsi
,
2508 enum tgsi_file_type file
, int dimension
, int index
)
2512 key
= ra_get_map_key(file
, dimension
, index
);
2514 val
= util_hash_table_get(tgsi
->reg_mapping
, key
);
2516 return (val
) ? pointer_to_intptr(val
) : -1;