OSDN Git Service

tgsi/exec: geometry shaders are executed on a single primitive
[android-x86/external-mesa.git] / src / gallium / auxiliary / tgsi / tgsi_exec.c
1 /**************************************************************************
2  * 
3  * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4  * All Rights Reserved.
5  * Copyright 2009-2010 VMware, Inc.  All rights Reserved.
6  * 
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sub license, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  * 
15  * The above copyright notice and this permission notice (including the
16  * next paragraph) shall be included in all copies or substantial portions
17  * of the Software.
18  * 
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26  * 
27  **************************************************************************/
28
29 /**
30  * TGSI interpreter/executor.
31  *
32  * Flow control information:
33  *
34  * Since we operate on 'quads' (4 pixels or 4 vertices in parallel)
35  * flow control statements (IF/ELSE/ENDIF, LOOP/ENDLOOP) require special
36  * care since a condition may be true for some quad components but false
37  * for other components.
38  *
39  * We basically execute all statements (even if they're in the part of
40  * an IF/ELSE clause that's "not taken") and use a special mask to
41  * control writing to destination registers.  This is the ExecMask.
42  * See store_dest().
43  *
44  * The ExecMask is computed from three other masks (CondMask, LoopMask and
45  * ContMask) which are controlled by the flow control instructions (namely:
46  * (IF/ELSE/ENDIF, LOOP/ENDLOOP and CONT).
47  *
48  *
49  * Authors:
50  *   Michal Krol
51  *   Brian Paul
52  */
53
54 #include "pipe/p_compiler.h"
55 #include "pipe/p_state.h"
56 #include "pipe/p_shader_tokens.h"
57 #include "tgsi/tgsi_dump.h"
58 #include "tgsi/tgsi_parse.h"
59 #include "tgsi/tgsi_util.h"
60 #include "tgsi_exec.h"
61 #include "util/u_memory.h"
62 #include "util/u_math.h"
63
64
65 #define DEBUG_EXECUTION 0
66
67
68 #define FAST_MATH 0
69
70 #define TILE_TOP_LEFT     0
71 #define TILE_TOP_RIGHT    1
72 #define TILE_BOTTOM_LEFT  2
73 #define TILE_BOTTOM_RIGHT 3
74
75 static void
76 micro_abs(union tgsi_exec_channel *dst,
77           const union tgsi_exec_channel *src)
78 {
79    dst->f[0] = fabsf(src->f[0]);
80    dst->f[1] = fabsf(src->f[1]);
81    dst->f[2] = fabsf(src->f[2]);
82    dst->f[3] = fabsf(src->f[3]);
83 }
84
85 static void
86 micro_arl(union tgsi_exec_channel *dst,
87           const union tgsi_exec_channel *src)
88 {
89    dst->i[0] = (int)floorf(src->f[0]);
90    dst->i[1] = (int)floorf(src->f[1]);
91    dst->i[2] = (int)floorf(src->f[2]);
92    dst->i[3] = (int)floorf(src->f[3]);
93 }
94
95 static void
96 micro_arr(union tgsi_exec_channel *dst,
97           const union tgsi_exec_channel *src)
98 {
99    dst->i[0] = (int)floorf(src->f[0] + 0.5f);
100    dst->i[1] = (int)floorf(src->f[1] + 0.5f);
101    dst->i[2] = (int)floorf(src->f[2] + 0.5f);
102    dst->i[3] = (int)floorf(src->f[3] + 0.5f);
103 }
104
105 static void
106 micro_ceil(union tgsi_exec_channel *dst,
107            const union tgsi_exec_channel *src)
108 {
109    dst->f[0] = ceilf(src->f[0]);
110    dst->f[1] = ceilf(src->f[1]);
111    dst->f[2] = ceilf(src->f[2]);
112    dst->f[3] = ceilf(src->f[3]);
113 }
114
115 static void
116 micro_clamp(union tgsi_exec_channel *dst,
117             const union tgsi_exec_channel *src0,
118             const union tgsi_exec_channel *src1,
119             const union tgsi_exec_channel *src2)
120 {
121    dst->f[0] = src0->f[0] < src1->f[0] ? src1->f[0] : src0->f[0] > src2->f[0] ? src2->f[0] : src0->f[0];
122    dst->f[1] = src0->f[1] < src1->f[1] ? src1->f[1] : src0->f[1] > src2->f[1] ? src2->f[1] : src0->f[1];
123    dst->f[2] = src0->f[2] < src1->f[2] ? src1->f[2] : src0->f[2] > src2->f[2] ? src2->f[2] : src0->f[2];
124    dst->f[3] = src0->f[3] < src1->f[3] ? src1->f[3] : src0->f[3] > src2->f[3] ? src2->f[3] : src0->f[3];
125 }
126
127 static void
128 micro_cmp(union tgsi_exec_channel *dst,
129           const union tgsi_exec_channel *src0,
130           const union tgsi_exec_channel *src1,
131           const union tgsi_exec_channel *src2)
132 {
133    dst->f[0] = src0->f[0] < 0.0f ? src1->f[0] : src2->f[0];
134    dst->f[1] = src0->f[1] < 0.0f ? src1->f[1] : src2->f[1];
135    dst->f[2] = src0->f[2] < 0.0f ? src1->f[2] : src2->f[2];
136    dst->f[3] = src0->f[3] < 0.0f ? src1->f[3] : src2->f[3];
137 }
138
139 static void
140 micro_cnd(union tgsi_exec_channel *dst,
141           const union tgsi_exec_channel *src0,
142           const union tgsi_exec_channel *src1,
143           const union tgsi_exec_channel *src2)
144 {
145    dst->f[0] = src2->f[0] > 0.5f ? src0->f[0] : src1->f[0];
146    dst->f[1] = src2->f[1] > 0.5f ? src0->f[1] : src1->f[1];
147    dst->f[2] = src2->f[2] > 0.5f ? src0->f[2] : src1->f[2];
148    dst->f[3] = src2->f[3] > 0.5f ? src0->f[3] : src1->f[3];
149 }
150
151 static void
152 micro_cos(union tgsi_exec_channel *dst,
153           const union tgsi_exec_channel *src)
154 {
155    dst->f[0] = cosf(src->f[0]);
156    dst->f[1] = cosf(src->f[1]);
157    dst->f[2] = cosf(src->f[2]);
158    dst->f[3] = cosf(src->f[3]);
159 }
160
161 static void
162 micro_ddx(union tgsi_exec_channel *dst,
163           const union tgsi_exec_channel *src)
164 {
165    dst->f[0] =
166    dst->f[1] =
167    dst->f[2] =
168    dst->f[3] = src->f[TILE_BOTTOM_RIGHT] - src->f[TILE_BOTTOM_LEFT];
169 }
170
171 static void
172 micro_ddy(union tgsi_exec_channel *dst,
173           const union tgsi_exec_channel *src)
174 {
175    dst->f[0] =
176    dst->f[1] =
177    dst->f[2] =
178    dst->f[3] = src->f[TILE_BOTTOM_LEFT] - src->f[TILE_TOP_LEFT];
179 }
180
181 static void
182 micro_exp2(union tgsi_exec_channel *dst,
183            const union tgsi_exec_channel *src)
184 {
185 #if FAST_MATH
186    dst->f[0] = util_fast_exp2(src->f[0]);
187    dst->f[1] = util_fast_exp2(src->f[1]);
188    dst->f[2] = util_fast_exp2(src->f[2]);
189    dst->f[3] = util_fast_exp2(src->f[3]);
190 #else
191 #if DEBUG
192    /* Inf is okay for this instruction, so clamp it to silence assertions. */
193    uint i;
194    union tgsi_exec_channel clamped;
195
196    for (i = 0; i < 4; i++) {
197       if (src->f[i] > 127.99999f) {
198          clamped.f[i] = 127.99999f;
199       } else if (src->f[i] < -126.99999f) {
200          clamped.f[i] = -126.99999f;
201       } else {
202          clamped.f[i] = src->f[i];
203       }
204    }
205    src = &clamped;
206 #endif /* DEBUG */
207
208    dst->f[0] = powf(2.0f, src->f[0]);
209    dst->f[1] = powf(2.0f, src->f[1]);
210    dst->f[2] = powf(2.0f, src->f[2]);
211    dst->f[3] = powf(2.0f, src->f[3]);
212 #endif /* FAST_MATH */
213 }
214
215 static void
216 micro_flr(union tgsi_exec_channel *dst,
217           const union tgsi_exec_channel *src)
218 {
219    dst->f[0] = floorf(src->f[0]);
220    dst->f[1] = floorf(src->f[1]);
221    dst->f[2] = floorf(src->f[2]);
222    dst->f[3] = floorf(src->f[3]);
223 }
224
225 static void
226 micro_frc(union tgsi_exec_channel *dst,
227           const union tgsi_exec_channel *src)
228 {
229    dst->f[0] = src->f[0] - floorf(src->f[0]);
230    dst->f[1] = src->f[1] - floorf(src->f[1]);
231    dst->f[2] = src->f[2] - floorf(src->f[2]);
232    dst->f[3] = src->f[3] - floorf(src->f[3]);
233 }
234
235 static void
236 micro_iabs(union tgsi_exec_channel *dst,
237            const union tgsi_exec_channel *src)
238 {
239    dst->i[0] = src->i[0] >= 0 ? src->i[0] : -src->i[0];
240    dst->i[1] = src->i[1] >= 0 ? src->i[1] : -src->i[1];
241    dst->i[2] = src->i[2] >= 0 ? src->i[2] : -src->i[2];
242    dst->i[3] = src->i[3] >= 0 ? src->i[3] : -src->i[3];
243 }
244
245 static void
246 micro_ineg(union tgsi_exec_channel *dst,
247            const union tgsi_exec_channel *src)
248 {
249    dst->i[0] = -src->i[0];
250    dst->i[1] = -src->i[1];
251    dst->i[2] = -src->i[2];
252    dst->i[3] = -src->i[3];
253 }
254
255 static void
256 micro_lg2(union tgsi_exec_channel *dst,
257           const union tgsi_exec_channel *src)
258 {
259 #if FAST_MATH
260    dst->f[0] = util_fast_log2(src->f[0]);
261    dst->f[1] = util_fast_log2(src->f[1]);
262    dst->f[2] = util_fast_log2(src->f[2]);
263    dst->f[3] = util_fast_log2(src->f[3]);
264 #else
265    dst->f[0] = logf(src->f[0]) * 1.442695f;
266    dst->f[1] = logf(src->f[1]) * 1.442695f;
267    dst->f[2] = logf(src->f[2]) * 1.442695f;
268    dst->f[3] = logf(src->f[3]) * 1.442695f;
269 #endif
270 }
271
272 static void
273 micro_lrp(union tgsi_exec_channel *dst,
274           const union tgsi_exec_channel *src0,
275           const union tgsi_exec_channel *src1,
276           const union tgsi_exec_channel *src2)
277 {
278    dst->f[0] = src0->f[0] * (src1->f[0] - src2->f[0]) + src2->f[0];
279    dst->f[1] = src0->f[1] * (src1->f[1] - src2->f[1]) + src2->f[1];
280    dst->f[2] = src0->f[2] * (src1->f[2] - src2->f[2]) + src2->f[2];
281    dst->f[3] = src0->f[3] * (src1->f[3] - src2->f[3]) + src2->f[3];
282 }
283
284 static void
285 micro_mad(union tgsi_exec_channel *dst,
286           const union tgsi_exec_channel *src0,
287           const union tgsi_exec_channel *src1,
288           const union tgsi_exec_channel *src2)
289 {
290    dst->f[0] = src0->f[0] * src1->f[0] + src2->f[0];
291    dst->f[1] = src0->f[1] * src1->f[1] + src2->f[1];
292    dst->f[2] = src0->f[2] * src1->f[2] + src2->f[2];
293    dst->f[3] = src0->f[3] * src1->f[3] + src2->f[3];
294 }
295
296 static void
297 micro_mov(union tgsi_exec_channel *dst,
298           const union tgsi_exec_channel *src)
299 {
300    dst->u[0] = src->u[0];
301    dst->u[1] = src->u[1];
302    dst->u[2] = src->u[2];
303    dst->u[3] = src->u[3];
304 }
305
306 static void
307 micro_rcp(union tgsi_exec_channel *dst,
308           const union tgsi_exec_channel *src)
309 {
310 #if 0 /* for debugging */
311    assert(src->f[0] != 0.0f);
312    assert(src->f[1] != 0.0f);
313    assert(src->f[2] != 0.0f);
314    assert(src->f[3] != 0.0f);
315 #endif
316    dst->f[0] = 1.0f / src->f[0];
317    dst->f[1] = 1.0f / src->f[1];
318    dst->f[2] = 1.0f / src->f[2];
319    dst->f[3] = 1.0f / src->f[3];
320 }
321
322 static void
323 micro_rnd(union tgsi_exec_channel *dst,
324           const union tgsi_exec_channel *src)
325 {
326    dst->f[0] = floorf(src->f[0] + 0.5f);
327    dst->f[1] = floorf(src->f[1] + 0.5f);
328    dst->f[2] = floorf(src->f[2] + 0.5f);
329    dst->f[3] = floorf(src->f[3] + 0.5f);
330 }
331
332 static void
333 micro_rsq(union tgsi_exec_channel *dst,
334           const union tgsi_exec_channel *src)
335 {
336 #if 0 /* for debugging */
337    assert(src->f[0] != 0.0f);
338    assert(src->f[1] != 0.0f);
339    assert(src->f[2] != 0.0f);
340    assert(src->f[3] != 0.0f);
341 #endif
342    dst->f[0] = 1.0f / sqrtf(fabsf(src->f[0]));
343    dst->f[1] = 1.0f / sqrtf(fabsf(src->f[1]));
344    dst->f[2] = 1.0f / sqrtf(fabsf(src->f[2]));
345    dst->f[3] = 1.0f / sqrtf(fabsf(src->f[3]));
346 }
347
348 static void
349 micro_sqrt(union tgsi_exec_channel *dst,
350            const union tgsi_exec_channel *src)
351 {
352    dst->f[0] = sqrtf(fabsf(src->f[0]));
353    dst->f[1] = sqrtf(fabsf(src->f[1]));
354    dst->f[2] = sqrtf(fabsf(src->f[2]));
355    dst->f[3] = sqrtf(fabsf(src->f[3]));
356 }
357
358 static void
359 micro_seq(union tgsi_exec_channel *dst,
360           const union tgsi_exec_channel *src0,
361           const union tgsi_exec_channel *src1)
362 {
363    dst->f[0] = src0->f[0] == src1->f[0] ? 1.0f : 0.0f;
364    dst->f[1] = src0->f[1] == src1->f[1] ? 1.0f : 0.0f;
365    dst->f[2] = src0->f[2] == src1->f[2] ? 1.0f : 0.0f;
366    dst->f[3] = src0->f[3] == src1->f[3] ? 1.0f : 0.0f;
367 }
368
369 static void
370 micro_sge(union tgsi_exec_channel *dst,
371           const union tgsi_exec_channel *src0,
372           const union tgsi_exec_channel *src1)
373 {
374    dst->f[0] = src0->f[0] >= src1->f[0] ? 1.0f : 0.0f;
375    dst->f[1] = src0->f[1] >= src1->f[1] ? 1.0f : 0.0f;
376    dst->f[2] = src0->f[2] >= src1->f[2] ? 1.0f : 0.0f;
377    dst->f[3] = src0->f[3] >= src1->f[3] ? 1.0f : 0.0f;
378 }
379
380 static void
381 micro_sgn(union tgsi_exec_channel *dst,
382           const union tgsi_exec_channel *src)
383 {
384    dst->f[0] = src->f[0] < 0.0f ? -1.0f : src->f[0] > 0.0f ? 1.0f : 0.0f;
385    dst->f[1] = src->f[1] < 0.0f ? -1.0f : src->f[1] > 0.0f ? 1.0f : 0.0f;
386    dst->f[2] = src->f[2] < 0.0f ? -1.0f : src->f[2] > 0.0f ? 1.0f : 0.0f;
387    dst->f[3] = src->f[3] < 0.0f ? -1.0f : src->f[3] > 0.0f ? 1.0f : 0.0f;
388 }
389
390 static void
391 micro_isgn(union tgsi_exec_channel *dst,
392           const union tgsi_exec_channel *src)
393 {
394    dst->i[0] = src->i[0] < 0 ? -1 : src->i[0] > 0 ? 1 : 0;
395    dst->i[1] = src->i[1] < 0 ? -1 : src->i[1] > 0 ? 1 : 0;
396    dst->i[2] = src->i[2] < 0 ? -1 : src->i[2] > 0 ? 1 : 0;
397    dst->i[3] = src->i[3] < 0 ? -1 : src->i[3] > 0 ? 1 : 0;
398 }
399
400 static void
401 micro_sgt(union tgsi_exec_channel *dst,
402           const union tgsi_exec_channel *src0,
403           const union tgsi_exec_channel *src1)
404 {
405    dst->f[0] = src0->f[0] > src1->f[0] ? 1.0f : 0.0f;
406    dst->f[1] = src0->f[1] > src1->f[1] ? 1.0f : 0.0f;
407    dst->f[2] = src0->f[2] > src1->f[2] ? 1.0f : 0.0f;
408    dst->f[3] = src0->f[3] > src1->f[3] ? 1.0f : 0.0f;
409 }
410
411 static void
412 micro_sin(union tgsi_exec_channel *dst,
413           const union tgsi_exec_channel *src)
414 {
415    dst->f[0] = sinf(src->f[0]);
416    dst->f[1] = sinf(src->f[1]);
417    dst->f[2] = sinf(src->f[2]);
418    dst->f[3] = sinf(src->f[3]);
419 }
420
421 static void
422 micro_sle(union tgsi_exec_channel *dst,
423           const union tgsi_exec_channel *src0,
424           const union tgsi_exec_channel *src1)
425 {
426    dst->f[0] = src0->f[0] <= src1->f[0] ? 1.0f : 0.0f;
427    dst->f[1] = src0->f[1] <= src1->f[1] ? 1.0f : 0.0f;
428    dst->f[2] = src0->f[2] <= src1->f[2] ? 1.0f : 0.0f;
429    dst->f[3] = src0->f[3] <= src1->f[3] ? 1.0f : 0.0f;
430 }
431
432 static void
433 micro_slt(union tgsi_exec_channel *dst,
434           const union tgsi_exec_channel *src0,
435           const union tgsi_exec_channel *src1)
436 {
437    dst->f[0] = src0->f[0] < src1->f[0] ? 1.0f : 0.0f;
438    dst->f[1] = src0->f[1] < src1->f[1] ? 1.0f : 0.0f;
439    dst->f[2] = src0->f[2] < src1->f[2] ? 1.0f : 0.0f;
440    dst->f[3] = src0->f[3] < src1->f[3] ? 1.0f : 0.0f;
441 }
442
443 static void
444 micro_sne(union tgsi_exec_channel *dst,
445           const union tgsi_exec_channel *src0,
446           const union tgsi_exec_channel *src1)
447 {
448    dst->f[0] = src0->f[0] != src1->f[0] ? 1.0f : 0.0f;
449    dst->f[1] = src0->f[1] != src1->f[1] ? 1.0f : 0.0f;
450    dst->f[2] = src0->f[2] != src1->f[2] ? 1.0f : 0.0f;
451    dst->f[3] = src0->f[3] != src1->f[3] ? 1.0f : 0.0f;
452 }
453
454 static void
455 micro_sfl(union tgsi_exec_channel *dst)
456 {
457    dst->f[0] = 0.0f;
458    dst->f[1] = 0.0f;
459    dst->f[2] = 0.0f;
460    dst->f[3] = 0.0f;
461 }
462
463 static void
464 micro_str(union tgsi_exec_channel *dst)
465 {
466    dst->f[0] = 1.0f;
467    dst->f[1] = 1.0f;
468    dst->f[2] = 1.0f;
469    dst->f[3] = 1.0f;
470 }
471
472 static void
473 micro_trunc(union tgsi_exec_channel *dst,
474             const union tgsi_exec_channel *src)
475 {
476    dst->f[0] = (float)(int)src->f[0];
477    dst->f[1] = (float)(int)src->f[1];
478    dst->f[2] = (float)(int)src->f[2];
479    dst->f[3] = (float)(int)src->f[3];
480 }
481
482
483 enum tgsi_exec_datatype {
484    TGSI_EXEC_DATA_FLOAT,
485    TGSI_EXEC_DATA_INT,
486    TGSI_EXEC_DATA_UINT
487 };
488
489 /*
490  * Shorthand locations of various utility registers (_I = Index, _C = Channel)
491  */
492 #define TEMP_KILMASK_I     TGSI_EXEC_TEMP_KILMASK_I
493 #define TEMP_KILMASK_C     TGSI_EXEC_TEMP_KILMASK_C
494 #define TEMP_OUTPUT_I      TGSI_EXEC_TEMP_OUTPUT_I
495 #define TEMP_OUTPUT_C      TGSI_EXEC_TEMP_OUTPUT_C
496 #define TEMP_PRIMITIVE_I   TGSI_EXEC_TEMP_PRIMITIVE_I
497 #define TEMP_PRIMITIVE_C   TGSI_EXEC_TEMP_PRIMITIVE_C
498
499
500 /** The execution mask depends on the conditional mask and the loop mask */
501 #define UPDATE_EXEC_MASK(MACH) \
502       MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->Switch.mask & MACH->FuncMask
503
504
505 static const union tgsi_exec_channel ZeroVec =
506    { { 0.0, 0.0, 0.0, 0.0 } };
507
508 static const union tgsi_exec_channel OneVec = {
509    {1.0f, 1.0f, 1.0f, 1.0f}
510 };
511
512 static const union tgsi_exec_channel P128Vec = {
513    {128.0f, 128.0f, 128.0f, 128.0f}
514 };
515
516 static const union tgsi_exec_channel M128Vec = {
517    {-128.0f, -128.0f, -128.0f, -128.0f}
518 };
519
520
521 /**
522  * Assert that none of the float values in 'chan' are infinite or NaN.
523  * NaN and Inf may occur normally during program execution and should
524  * not lead to crashes, etc.  But when debugging, it's helpful to catch
525  * them.
526  */
527 static INLINE void
528 check_inf_or_nan(const union tgsi_exec_channel *chan)
529 {
530    assert(!util_is_inf_or_nan((chan)->f[0]));
531    assert(!util_is_inf_or_nan((chan)->f[1]));
532    assert(!util_is_inf_or_nan((chan)->f[2]));
533    assert(!util_is_inf_or_nan((chan)->f[3]));
534 }
535
536
537 #ifdef DEBUG
538 static void
539 print_chan(const char *msg, const union tgsi_exec_channel *chan)
540 {
541    debug_printf("%s = {%f, %f, %f, %f}\n",
542                 msg, chan->f[0], chan->f[1], chan->f[2], chan->f[3]);
543 }
544 #endif
545
546
547 #ifdef DEBUG
548 static void
549 print_temp(const struct tgsi_exec_machine *mach, uint index)
550 {
551    const struct tgsi_exec_vector *tmp = &mach->Temps[index];
552    int i;
553    debug_printf("Temp[%u] =\n", index);
554    for (i = 0; i < 4; i++) {
555       debug_printf("  %c: { %f, %f, %f, %f }\n",
556                    "XYZW"[i],
557                    tmp->xyzw[i].f[0],
558                    tmp->xyzw[i].f[1],
559                    tmp->xyzw[i].f[2],
560                    tmp->xyzw[i].f[3]);
561    }
562 }
563 #endif
564
565
566 void
567 tgsi_exec_set_constant_buffers(struct tgsi_exec_machine *mach,
568                                unsigned num_bufs,
569                                const void **bufs,
570                                const unsigned *buf_sizes)
571 {
572    unsigned i;
573
574    for (i = 0; i < num_bufs; i++) {
575       mach->Consts[i] = bufs[i];
576       mach->ConstsSize[i] = buf_sizes[i];
577    }
578 }
579
580
581 /**
582  * Check if there's a potential src/dst register data dependency when
583  * using SOA execution.
584  * Example:
585  *   MOV T, T.yxwz;
586  * This would expand into:
587  *   MOV t0, t1;
588  *   MOV t1, t0;
589  *   MOV t2, t3;
590  *   MOV t3, t2;
591  * The second instruction will have the wrong value for t0 if executed as-is.
592  */
593 boolean
594 tgsi_check_soa_dependencies(const struct tgsi_full_instruction *inst)
595 {
596    uint i, chan;
597
598    uint writemask = inst->Dst[0].Register.WriteMask;
599    if (writemask == TGSI_WRITEMASK_X ||
600        writemask == TGSI_WRITEMASK_Y ||
601        writemask == TGSI_WRITEMASK_Z ||
602        writemask == TGSI_WRITEMASK_W ||
603        writemask == TGSI_WRITEMASK_NONE) {
604       /* no chance of data dependency */
605       return FALSE;
606    }
607
608    /* loop over src regs */
609    for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
610       if ((inst->Src[i].Register.File ==
611            inst->Dst[0].Register.File) &&
612           ((inst->Src[i].Register.Index ==
613             inst->Dst[0].Register.Index) ||
614            inst->Src[i].Register.Indirect ||
615            inst->Dst[0].Register.Indirect)) {
616          /* loop over dest channels */
617          uint channelsWritten = 0x0;
618          for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
619             if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
620                /* check if we're reading a channel that's been written */
621                uint swizzle = tgsi_util_get_full_src_register_swizzle(&inst->Src[i], chan);
622                if (channelsWritten & (1 << swizzle)) {
623                   return TRUE;
624                }
625
626                channelsWritten |= (1 << chan);
627             }
628          }
629       }
630    }
631    return FALSE;
632 }
633
634
635 /**
636  * Initialize machine state by expanding tokens to full instructions,
637  * allocating temporary storage, setting up constants, etc.
638  * After this, we can call tgsi_exec_machine_run() many times.
639  */
640 void 
641 tgsi_exec_machine_bind_shader(
642    struct tgsi_exec_machine *mach,
643    const struct tgsi_token *tokens,
644    struct tgsi_sampler *sampler)
645 {
646    uint k;
647    struct tgsi_parse_context parse;
648    struct tgsi_full_instruction *instructions;
649    struct tgsi_full_declaration *declarations;
650    uint maxInstructions = 10, numInstructions = 0;
651    uint maxDeclarations = 10, numDeclarations = 0;
652
653 #if 0
654    tgsi_dump(tokens, 0);
655 #endif
656
657    util_init_math();
658
659
660    mach->Tokens = tokens;
661    mach->Sampler = sampler;
662
663    if (!tokens) {
664       /* unbind and free all */
665       FREE(mach->Declarations);
666       mach->Declarations = NULL;
667       mach->NumDeclarations = 0;
668
669       FREE(mach->Instructions);
670       mach->Instructions = NULL;
671       mach->NumInstructions = 0;
672
673       return;
674    }
675
676    k = tgsi_parse_init (&parse, mach->Tokens);
677    if (k != TGSI_PARSE_OK) {
678       debug_printf( "Problem parsing!\n" );
679       return;
680    }
681
682    mach->Processor = parse.FullHeader.Processor.Processor;
683    mach->ImmLimit = 0;
684    mach->NumOutputs = 0;
685
686    if (mach->Processor == TGSI_PROCESSOR_GEOMETRY &&
687        !mach->UsedGeometryShader) {
688       struct tgsi_exec_vector *inputs;
689       struct tgsi_exec_vector *outputs;
690
691       inputs = align_malloc(sizeof(struct tgsi_exec_vector) *
692                             TGSI_MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS,
693                             16);
694
695       if (!inputs)
696          return;
697
698       outputs = align_malloc(sizeof(struct tgsi_exec_vector) *
699                              TGSI_MAX_TOTAL_VERTICES, 16);
700
701       if (!outputs) {
702          align_free(inputs);
703          return;
704       }
705
706       align_free(mach->Inputs);
707       align_free(mach->Outputs);
708
709       mach->Inputs = inputs;
710       mach->Outputs = outputs;
711       mach->UsedGeometryShader = TRUE;
712    }
713
714    declarations = (struct tgsi_full_declaration *)
715       MALLOC( maxDeclarations * sizeof(struct tgsi_full_declaration) );
716
717    if (!declarations) {
718       return;
719    }
720
721    instructions = (struct tgsi_full_instruction *)
722       MALLOC( maxInstructions * sizeof(struct tgsi_full_instruction) );
723
724    if (!instructions) {
725       FREE( declarations );
726       return;
727    }
728
729    while( !tgsi_parse_end_of_tokens( &parse ) ) {
730       uint i;
731
732       tgsi_parse_token( &parse );
733       switch( parse.FullToken.Token.Type ) {
734       case TGSI_TOKEN_TYPE_DECLARATION:
735          /* save expanded declaration */
736          if (numDeclarations == maxDeclarations) {
737             declarations = REALLOC(declarations,
738                                    maxDeclarations
739                                    * sizeof(struct tgsi_full_declaration),
740                                    (maxDeclarations + 10)
741                                    * sizeof(struct tgsi_full_declaration));
742             maxDeclarations += 10;
743          }
744          if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_OUTPUT) {
745             unsigned reg;
746             for (reg = parse.FullToken.FullDeclaration.Range.First;
747                  reg <= parse.FullToken.FullDeclaration.Range.Last;
748                  ++reg) {
749                ++mach->NumOutputs;
750             }
751          }
752          memcpy(declarations + numDeclarations,
753                 &parse.FullToken.FullDeclaration,
754                 sizeof(declarations[0]));
755          numDeclarations++;
756          break;
757
758       case TGSI_TOKEN_TYPE_IMMEDIATE:
759          {
760             uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
761             assert( size <= 4 );
762             assert( mach->ImmLimit + 1 <= TGSI_EXEC_NUM_IMMEDIATES );
763
764             for( i = 0; i < size; i++ ) {
765                mach->Imms[mach->ImmLimit][i] = 
766                   parse.FullToken.FullImmediate.u[i].Float;
767             }
768             mach->ImmLimit += 1;
769          }
770          break;
771
772       case TGSI_TOKEN_TYPE_INSTRUCTION:
773
774          /* save expanded instruction */
775          if (numInstructions == maxInstructions) {
776             instructions = REALLOC(instructions,
777                                    maxInstructions
778                                    * sizeof(struct tgsi_full_instruction),
779                                    (maxInstructions + 10)
780                                    * sizeof(struct tgsi_full_instruction));
781             maxInstructions += 10;
782          }
783
784          memcpy(instructions + numInstructions,
785                 &parse.FullToken.FullInstruction,
786                 sizeof(instructions[0]));
787
788          numInstructions++;
789          break;
790
791       case TGSI_TOKEN_TYPE_PROPERTY:
792          break;
793
794       default:
795          assert( 0 );
796       }
797    }
798    tgsi_parse_free (&parse);
799
800    FREE(mach->Declarations);
801    mach->Declarations = declarations;
802    mach->NumDeclarations = numDeclarations;
803
804    FREE(mach->Instructions);
805    mach->Instructions = instructions;
806    mach->NumInstructions = numInstructions;
807 }
808
809
810 struct tgsi_exec_machine *
811 tgsi_exec_machine_create( void )
812 {
813    struct tgsi_exec_machine *mach;
814    uint i;
815
816    mach = align_malloc( sizeof *mach, 16 );
817    if (!mach)
818       goto fail;
819
820    memset(mach, 0, sizeof(*mach));
821
822    mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR];
823    mach->MaxGeometryShaderOutputs = TGSI_MAX_TOTAL_VERTICES;
824    mach->Predicates = &mach->Temps[TGSI_EXEC_TEMP_P0];
825
826    mach->Inputs = align_malloc(sizeof(struct tgsi_exec_vector) * PIPE_MAX_ATTRIBS, 16);
827    mach->Outputs = align_malloc(sizeof(struct tgsi_exec_vector) * PIPE_MAX_ATTRIBS, 16);
828    if (!mach->Inputs || !mach->Outputs)
829       goto fail;
830
831    /* Setup constants needed by the SSE2 executor. */
832    for( i = 0; i < 4; i++ ) {
833       mach->Temps[TGSI_EXEC_TEMP_00000000_I].xyzw[TGSI_EXEC_TEMP_00000000_C].u[i] = 0x00000000;
834       mach->Temps[TGSI_EXEC_TEMP_7FFFFFFF_I].xyzw[TGSI_EXEC_TEMP_7FFFFFFF_C].u[i] = 0x7FFFFFFF;
835       mach->Temps[TGSI_EXEC_TEMP_80000000_I].xyzw[TGSI_EXEC_TEMP_80000000_C].u[i] = 0x80000000;
836       mach->Temps[TGSI_EXEC_TEMP_FFFFFFFF_I].xyzw[TGSI_EXEC_TEMP_FFFFFFFF_C].u[i] = 0xFFFFFFFF;    /* not used */
837       mach->Temps[TGSI_EXEC_TEMP_ONE_I].xyzw[TGSI_EXEC_TEMP_ONE_C].f[i] = 1.0f;
838       mach->Temps[TGSI_EXEC_TEMP_TWO_I].xyzw[TGSI_EXEC_TEMP_TWO_C].f[i] = 2.0f;    /* not used */
839       mach->Temps[TGSI_EXEC_TEMP_128_I].xyzw[TGSI_EXEC_TEMP_128_C].f[i] = 128.0f;
840       mach->Temps[TGSI_EXEC_TEMP_MINUS_128_I].xyzw[TGSI_EXEC_TEMP_MINUS_128_C].f[i] = -128.0f;
841       mach->Temps[TGSI_EXEC_TEMP_THREE_I].xyzw[TGSI_EXEC_TEMP_THREE_C].f[i] = 3.0f;
842       mach->Temps[TGSI_EXEC_TEMP_HALF_I].xyzw[TGSI_EXEC_TEMP_HALF_C].f[i] = 0.5f;
843    }
844
845 #ifdef DEBUG
846    /* silence warnings */
847    (void) print_chan;
848    (void) print_temp;
849 #endif
850
851    return mach;
852
853 fail:
854    if (mach) {
855       align_free(mach->Inputs);
856       align_free(mach->Outputs);
857       align_free(mach);
858    }
859    return NULL;
860 }
861
862
863 void
864 tgsi_exec_machine_destroy(struct tgsi_exec_machine *mach)
865 {
866    if (mach) {
867       FREE(mach->Instructions);
868       FREE(mach->Declarations);
869
870       align_free(mach->Inputs);
871       align_free(mach->Outputs);
872
873       align_free(mach);
874    }
875 }
876
877 static void
878 micro_add(union tgsi_exec_channel *dst,
879           const union tgsi_exec_channel *src0,
880           const union tgsi_exec_channel *src1)
881 {
882    dst->f[0] = src0->f[0] + src1->f[0];
883    dst->f[1] = src0->f[1] + src1->f[1];
884    dst->f[2] = src0->f[2] + src1->f[2];
885    dst->f[3] = src0->f[3] + src1->f[3];
886 }
887
888 static void
889 micro_div(
890    union tgsi_exec_channel *dst,
891    const union tgsi_exec_channel *src0,
892    const union tgsi_exec_channel *src1 )
893 {
894    if (src1->f[0] != 0) {
895       dst->f[0] = src0->f[0] / src1->f[0];
896    }
897    if (src1->f[1] != 0) {
898       dst->f[1] = src0->f[1] / src1->f[1];
899    }
900    if (src1->f[2] != 0) {
901       dst->f[2] = src0->f[2] / src1->f[2];
902    }
903    if (src1->f[3] != 0) {
904       dst->f[3] = src0->f[3] / src1->f[3];
905    }
906 }
907
908 static void
909 micro_rcc(union tgsi_exec_channel *dst,
910           const union tgsi_exec_channel *src)
911 {
912    uint i;
913
914    for (i = 0; i < 4; i++) {
915       float recip = 1.0f / src->f[i];
916
917       if (recip > 0.0f) {
918          if (recip > 1.884467e+019f) {
919             dst->f[i] = 1.884467e+019f;
920          }
921          else if (recip < 5.42101e-020f) {
922             dst->f[i] = 5.42101e-020f;
923          }
924          else {
925             dst->f[i] = recip;
926          }
927       }
928       else {
929          if (recip < -1.884467e+019f) {
930             dst->f[i] = -1.884467e+019f;
931          }
932          else if (recip > -5.42101e-020f) {
933             dst->f[i] = -5.42101e-020f;
934          }
935          else {
936             dst->f[i] = recip;
937          }
938       }
939    }
940 }
941
942 static void
943 micro_lt(
944    union tgsi_exec_channel *dst,
945    const union tgsi_exec_channel *src0,
946    const union tgsi_exec_channel *src1,
947    const union tgsi_exec_channel *src2,
948    const union tgsi_exec_channel *src3 )
949 {
950    dst->f[0] = src0->f[0] < src1->f[0] ? src2->f[0] : src3->f[0];
951    dst->f[1] = src0->f[1] < src1->f[1] ? src2->f[1] : src3->f[1];
952    dst->f[2] = src0->f[2] < src1->f[2] ? src2->f[2] : src3->f[2];
953    dst->f[3] = src0->f[3] < src1->f[3] ? src2->f[3] : src3->f[3];
954 }
955
956 static void
957 micro_max(union tgsi_exec_channel *dst,
958           const union tgsi_exec_channel *src0,
959           const union tgsi_exec_channel *src1)
960 {
961    dst->f[0] = src0->f[0] > src1->f[0] ? src0->f[0] : src1->f[0];
962    dst->f[1] = src0->f[1] > src1->f[1] ? src0->f[1] : src1->f[1];
963    dst->f[2] = src0->f[2] > src1->f[2] ? src0->f[2] : src1->f[2];
964    dst->f[3] = src0->f[3] > src1->f[3] ? src0->f[3] : src1->f[3];
965 }
966
967 static void
968 micro_min(union tgsi_exec_channel *dst,
969           const union tgsi_exec_channel *src0,
970           const union tgsi_exec_channel *src1)
971 {
972    dst->f[0] = src0->f[0] < src1->f[0] ? src0->f[0] : src1->f[0];
973    dst->f[1] = src0->f[1] < src1->f[1] ? src0->f[1] : src1->f[1];
974    dst->f[2] = src0->f[2] < src1->f[2] ? src0->f[2] : src1->f[2];
975    dst->f[3] = src0->f[3] < src1->f[3] ? src0->f[3] : src1->f[3];
976 }
977
978 static void
979 micro_mul(union tgsi_exec_channel *dst,
980           const union tgsi_exec_channel *src0,
981           const union tgsi_exec_channel *src1)
982 {
983    dst->f[0] = src0->f[0] * src1->f[0];
984    dst->f[1] = src0->f[1] * src1->f[1];
985    dst->f[2] = src0->f[2] * src1->f[2];
986    dst->f[3] = src0->f[3] * src1->f[3];
987 }
988
989 static void
990 micro_neg(
991    union tgsi_exec_channel *dst,
992    const union tgsi_exec_channel *src )
993 {
994    dst->f[0] = -src->f[0];
995    dst->f[1] = -src->f[1];
996    dst->f[2] = -src->f[2];
997    dst->f[3] = -src->f[3];
998 }
999
1000 static void
1001 micro_pow(
1002    union tgsi_exec_channel *dst,
1003    const union tgsi_exec_channel *src0,
1004    const union tgsi_exec_channel *src1 )
1005 {
1006 #if FAST_MATH
1007    dst->f[0] = util_fast_pow( src0->f[0], src1->f[0] );
1008    dst->f[1] = util_fast_pow( src0->f[1], src1->f[1] );
1009    dst->f[2] = util_fast_pow( src0->f[2], src1->f[2] );
1010    dst->f[3] = util_fast_pow( src0->f[3], src1->f[3] );
1011 #else
1012    dst->f[0] = powf( src0->f[0], src1->f[0] );
1013    dst->f[1] = powf( src0->f[1], src1->f[1] );
1014    dst->f[2] = powf( src0->f[2], src1->f[2] );
1015    dst->f[3] = powf( src0->f[3], src1->f[3] );
1016 #endif
1017 }
1018
1019 static void
1020 micro_sub(union tgsi_exec_channel *dst,
1021           const union tgsi_exec_channel *src0,
1022           const union tgsi_exec_channel *src1)
1023 {
1024    dst->f[0] = src0->f[0] - src1->f[0];
1025    dst->f[1] = src0->f[1] - src1->f[1];
1026    dst->f[2] = src0->f[2] - src1->f[2];
1027    dst->f[3] = src0->f[3] - src1->f[3];
1028 }
1029
1030 static void
1031 fetch_src_file_channel(const struct tgsi_exec_machine *mach,
1032                        const uint chan_index,
1033                        const uint file,
1034                        const uint swizzle,
1035                        const union tgsi_exec_channel *index,
1036                        const union tgsi_exec_channel *index2D,
1037                        union tgsi_exec_channel *chan)
1038 {
1039    uint i;
1040
1041    assert(swizzle < 4);
1042
1043    switch (file) {
1044    case TGSI_FILE_CONSTANT:
1045       for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1046          assert(index2D->i[i] >= 0 && index2D->i[i] < PIPE_MAX_CONSTANT_BUFFERS);
1047          assert(mach->Consts[index2D->i[i]]);
1048
1049          if (index->i[i] < 0) {
1050             chan->u[i] = 0;
1051          } else {
1052             /* NOTE: copying the const value as a uint instead of float */
1053             const uint constbuf = index2D->i[i];
1054             const uint *buf = (const uint *)mach->Consts[constbuf];
1055             const int pos = index->i[i] * 4 + swizzle;
1056             /* const buffer bounds check */
1057             if (pos < 0 || pos >= (int) mach->ConstsSize[constbuf]) {
1058                if (0) {
1059                   /* Debug: print warning */
1060                   static int count = 0;
1061                   if (count++ < 100)
1062                      debug_printf("TGSI Exec: const buffer index %d"
1063                                   " out of bounds\n", pos);
1064                }
1065                chan->u[i] = 0;
1066             }
1067             else
1068                chan->u[i] = buf[pos];
1069          }
1070       }
1071       break;
1072
1073    case TGSI_FILE_INPUT:
1074       for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1075          /*
1076          if (TGSI_PROCESSOR_GEOMETRY == mach->Processor) {
1077             debug_printf("Fetching Input[%d] (2d=%d, 1d=%d)\n",
1078                          index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i],
1079                          index2D->i[i], index->i[i]);
1080                          }*/
1081          int pos = index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i];
1082          assert(pos >= 0);
1083          assert(pos < TGSI_MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS);
1084          chan->u[i] = mach->Inputs[pos].xyzw[swizzle].u[i];
1085       }
1086       break;
1087
1088    case TGSI_FILE_SYSTEM_VALUE:
1089       /* XXX no swizzling at this point.  Will be needed if we put
1090        * gl_FragCoord, for example, in a sys value register.
1091        */
1092       for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1093          chan->u[i] = mach->SystemValue[index->i[i]].u[i];
1094       }
1095       break;
1096
1097    case TGSI_FILE_TEMPORARY:
1098       for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1099          assert(index->i[i] < TGSI_EXEC_NUM_TEMPS);
1100          assert(index2D->i[i] == 0);
1101
1102          chan->u[i] = mach->Temps[index->i[i]].xyzw[swizzle].u[i];
1103       }
1104       break;
1105
1106    case TGSI_FILE_IMMEDIATE:
1107       for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1108          assert(index->i[i] >= 0 && index->i[i] < (int)mach->ImmLimit);
1109          assert(index2D->i[i] == 0);
1110
1111          chan->f[i] = mach->Imms[index->i[i]][swizzle];
1112       }
1113       break;
1114
1115    case TGSI_FILE_ADDRESS:
1116       for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1117          assert(index->i[i] >= 0);
1118          assert(index2D->i[i] == 0);
1119
1120          chan->u[i] = mach->Addrs[index->i[i]].xyzw[swizzle].u[i];
1121       }
1122       break;
1123
1124    case TGSI_FILE_PREDICATE:
1125       for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1126          assert(index->i[i] >= 0 && index->i[i] < TGSI_EXEC_NUM_PREDS);
1127          assert(index2D->i[i] == 0);
1128
1129          chan->u[i] = mach->Predicates[0].xyzw[swizzle].u[i];
1130       }
1131       break;
1132
1133    case TGSI_FILE_OUTPUT:
1134       /* vertex/fragment output vars can be read too */
1135       for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1136          assert(index->i[i] >= 0);
1137          assert(index2D->i[i] == 0);
1138
1139          chan->u[i] = mach->Outputs[index->i[i]].xyzw[swizzle].u[i];
1140       }
1141       break;
1142
1143    default:
1144       assert(0);
1145       for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1146          chan->u[i] = 0;
1147       }
1148    }
1149 }
1150
1151 static void
1152 fetch_source(const struct tgsi_exec_machine *mach,
1153              union tgsi_exec_channel *chan,
1154              const struct tgsi_full_src_register *reg,
1155              const uint chan_index,
1156              enum tgsi_exec_datatype src_datatype)
1157 {
1158    union tgsi_exec_channel index;
1159    union tgsi_exec_channel index2D;
1160    uint swizzle;
1161
1162    /* We start with a direct index into a register file.
1163     *
1164     *    file[1],
1165     *    where:
1166     *       file = Register.File
1167     *       [1] = Register.Index
1168     */
1169    index.i[0] =
1170    index.i[1] =
1171    index.i[2] =
1172    index.i[3] = reg->Register.Index;
1173
1174    /* There is an extra source register that indirectly subscripts
1175     * a register file. The direct index now becomes an offset
1176     * that is being added to the indirect register.
1177     *
1178     *    file[ind[2].x+1],
1179     *    where:
1180     *       ind = Indirect.File
1181     *       [2] = Indirect.Index
1182     *       .x = Indirect.SwizzleX
1183     */
1184    if (reg->Register.Indirect) {
1185       union tgsi_exec_channel index2;
1186       union tgsi_exec_channel indir_index;
1187       const uint execmask = mach->ExecMask;
1188       uint i;
1189
1190       /* which address register (always zero now) */
1191       index2.i[0] =
1192       index2.i[1] =
1193       index2.i[2] =
1194       index2.i[3] = reg->Indirect.Index;
1195       /* get current value of address register[swizzle] */
1196       swizzle = reg->Indirect.Swizzle;
1197       fetch_src_file_channel(mach,
1198                              chan_index,
1199                              reg->Indirect.File,
1200                              swizzle,
1201                              &index2,
1202                              &ZeroVec,
1203                              &indir_index);
1204
1205       /* add value of address register to the offset */
1206       index.i[0] += indir_index.i[0];
1207       index.i[1] += indir_index.i[1];
1208       index.i[2] += indir_index.i[2];
1209       index.i[3] += indir_index.i[3];
1210
1211       /* for disabled execution channels, zero-out the index to
1212        * avoid using a potential garbage value.
1213        */
1214       for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1215          if ((execmask & (1 << i)) == 0)
1216             index.i[i] = 0;
1217       }
1218    }
1219
1220    /* There is an extra source register that is a second
1221     * subscript to a register file. Effectively it means that
1222     * the register file is actually a 2D array of registers.
1223     *
1224     *    file[3][1],
1225     *    where:
1226     *       [3] = Dimension.Index
1227     */
1228    if (reg->Register.Dimension) {
1229       index2D.i[0] =
1230       index2D.i[1] =
1231       index2D.i[2] =
1232       index2D.i[3] = reg->Dimension.Index;
1233
1234       /* Again, the second subscript index can be addressed indirectly
1235        * identically to the first one.
1236        * Nothing stops us from indirectly addressing the indirect register,
1237        * but there is no need for that, so we won't exercise it.
1238        *
1239        *    file[ind[4].y+3][1],
1240        *    where:
1241        *       ind = DimIndirect.File
1242        *       [4] = DimIndirect.Index
1243        *       .y = DimIndirect.SwizzleX
1244        */
1245       if (reg->Dimension.Indirect) {
1246          union tgsi_exec_channel index2;
1247          union tgsi_exec_channel indir_index;
1248          const uint execmask = mach->ExecMask;
1249          uint i;
1250
1251          index2.i[0] =
1252          index2.i[1] =
1253          index2.i[2] =
1254          index2.i[3] = reg->DimIndirect.Index;
1255
1256          swizzle = reg->DimIndirect.Swizzle;
1257          fetch_src_file_channel(mach,
1258                                 chan_index,
1259                                 reg->DimIndirect.File,
1260                                 swizzle,
1261                                 &index2,
1262                                 &ZeroVec,
1263                                 &indir_index);
1264
1265          index2D.i[0] += indir_index.i[0];
1266          index2D.i[1] += indir_index.i[1];
1267          index2D.i[2] += indir_index.i[2];
1268          index2D.i[3] += indir_index.i[3];
1269
1270          /* for disabled execution channels, zero-out the index to
1271           * avoid using a potential garbage value.
1272           */
1273          for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1274             if ((execmask & (1 << i)) == 0) {
1275                index2D.i[i] = 0;
1276             }
1277          }
1278       }
1279
1280       /* If by any chance there was a need for a 3D array of register
1281        * files, we would have to check whether Dimension is followed
1282        * by a dimension register and continue the saga.
1283        */
1284    } else {
1285       index2D.i[0] =
1286       index2D.i[1] =
1287       index2D.i[2] =
1288       index2D.i[3] = 0;
1289    }
1290
1291    swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
1292    fetch_src_file_channel(mach,
1293                           chan_index,
1294                           reg->Register.File,
1295                           swizzle,
1296                           &index,
1297                           &index2D,
1298                           chan);
1299
1300    if (reg->Register.Absolute) {
1301       if (src_datatype == TGSI_EXEC_DATA_FLOAT) {
1302          micro_abs(chan, chan);
1303       } else {
1304          micro_iabs(chan, chan);
1305       }
1306    }
1307
1308    if (reg->Register.Negate) {
1309       if (src_datatype == TGSI_EXEC_DATA_FLOAT) {
1310          micro_neg(chan, chan);
1311       } else {
1312          micro_ineg(chan, chan);
1313       }
1314    }
1315 }
1316
1317 static void
1318 store_dest(struct tgsi_exec_machine *mach,
1319            const union tgsi_exec_channel *chan,
1320            const struct tgsi_full_dst_register *reg,
1321            const struct tgsi_full_instruction *inst,
1322            uint chan_index,
1323            enum tgsi_exec_datatype dst_datatype)
1324 {
1325    uint i;
1326    union tgsi_exec_channel null;
1327    union tgsi_exec_channel *dst;
1328    union tgsi_exec_channel index2D;
1329    uint execmask = mach->ExecMask;
1330    int offset = 0;  /* indirection offset */
1331    int index;
1332
1333    /* for debugging */
1334    if (0 && dst_datatype == TGSI_EXEC_DATA_FLOAT) {
1335       check_inf_or_nan(chan);
1336    }
1337
1338    /* There is an extra source register that indirectly subscripts
1339     * a register file. The direct index now becomes an offset
1340     * that is being added to the indirect register.
1341     *
1342     *    file[ind[2].x+1],
1343     *    where:
1344     *       ind = Indirect.File
1345     *       [2] = Indirect.Index
1346     *       .x = Indirect.SwizzleX
1347     */
1348    if (reg->Register.Indirect) {
1349       union tgsi_exec_channel index;
1350       union tgsi_exec_channel indir_index;
1351       uint swizzle;
1352
1353       /* which address register (always zero for now) */
1354       index.i[0] =
1355       index.i[1] =
1356       index.i[2] =
1357       index.i[3] = reg->Indirect.Index;
1358
1359       /* get current value of address register[swizzle] */
1360       swizzle = reg->Indirect.Swizzle;
1361
1362       /* fetch values from the address/indirection register */
1363       fetch_src_file_channel(mach,
1364                              chan_index,
1365                              reg->Indirect.File,
1366                              swizzle,
1367                              &index,
1368                              &ZeroVec,
1369                              &indir_index);
1370
1371       /* save indirection offset */
1372       offset = indir_index.i[0];
1373    }
1374
1375    /* There is an extra source register that is a second
1376     * subscript to a register file. Effectively it means that
1377     * the register file is actually a 2D array of registers.
1378     *
1379     *    file[3][1],
1380     *    where:
1381     *       [3] = Dimension.Index
1382     */
1383    if (reg->Register.Dimension) {
1384       index2D.i[0] =
1385       index2D.i[1] =
1386       index2D.i[2] =
1387       index2D.i[3] = reg->Dimension.Index;
1388
1389       /* Again, the second subscript index can be addressed indirectly
1390        * identically to the first one.
1391        * Nothing stops us from indirectly addressing the indirect register,
1392        * but there is no need for that, so we won't exercise it.
1393        *
1394        *    file[ind[4].y+3][1],
1395        *    where:
1396        *       ind = DimIndirect.File
1397        *       [4] = DimIndirect.Index
1398        *       .y = DimIndirect.SwizzleX
1399        */
1400       if (reg->Dimension.Indirect) {
1401          union tgsi_exec_channel index2;
1402          union tgsi_exec_channel indir_index;
1403          const uint execmask = mach->ExecMask;
1404          unsigned swizzle;
1405          uint i;
1406
1407          index2.i[0] =
1408          index2.i[1] =
1409          index2.i[2] =
1410          index2.i[3] = reg->DimIndirect.Index;
1411
1412          swizzle = reg->DimIndirect.Swizzle;
1413          fetch_src_file_channel(mach,
1414                                 chan_index,
1415                                 reg->DimIndirect.File,
1416                                 swizzle,
1417                                 &index2,
1418                                 &ZeroVec,
1419                                 &indir_index);
1420
1421          index2D.i[0] += indir_index.i[0];
1422          index2D.i[1] += indir_index.i[1];
1423          index2D.i[2] += indir_index.i[2];
1424          index2D.i[3] += indir_index.i[3];
1425
1426          /* for disabled execution channels, zero-out the index to
1427           * avoid using a potential garbage value.
1428           */
1429          for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1430             if ((execmask & (1 << i)) == 0) {
1431                index2D.i[i] = 0;
1432             }
1433          }
1434       }
1435
1436       /* If by any chance there was a need for a 3D array of register
1437        * files, we would have to check whether Dimension is followed
1438        * by a dimension register and continue the saga.
1439        */
1440    } else {
1441       index2D.i[0] =
1442       index2D.i[1] =
1443       index2D.i[2] =
1444       index2D.i[3] = 0;
1445    }
1446
1447    switch (reg->Register.File) {
1448    case TGSI_FILE_NULL:
1449       dst = &null;
1450       break;
1451
1452    case TGSI_FILE_OUTPUT:
1453       index = mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0]
1454          + reg->Register.Index;
1455       dst = &mach->Outputs[offset + index].xyzw[chan_index];
1456 #if 0
1457       debug_printf("NumOutputs = %d, TEMP_O_C/I = %d, redindex = %d\n",
1458                    mach->NumOutputs, mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0],
1459                    reg->Register.Index);
1460       if (TGSI_PROCESSOR_GEOMETRY == mach->Processor) {
1461          debug_printf("STORING OUT[%d] mask(%d), = (", offset + index, execmask);
1462          for (i = 0; i < TGSI_QUAD_SIZE; i++)
1463             if (execmask & (1 << i))
1464                debug_printf("%f, ", chan->f[i]);
1465          debug_printf(")\n");
1466       }
1467 #endif
1468       break;
1469
1470    case TGSI_FILE_TEMPORARY:
1471       index = reg->Register.Index;
1472       assert( index < TGSI_EXEC_NUM_TEMPS );
1473       dst = &mach->Temps[offset + index].xyzw[chan_index];
1474       break;
1475
1476    case TGSI_FILE_ADDRESS:
1477       index = reg->Register.Index;
1478       dst = &mach->Addrs[index].xyzw[chan_index];
1479       break;
1480
1481    case TGSI_FILE_PREDICATE:
1482       index = reg->Register.Index;
1483       assert(index < TGSI_EXEC_NUM_PREDS);
1484       dst = &mach->Predicates[index].xyzw[chan_index];
1485       break;
1486
1487    default:
1488       assert( 0 );
1489       return;
1490    }
1491
1492    if (inst->Instruction.Predicate) {
1493       uint swizzle;
1494       union tgsi_exec_channel *pred;
1495
1496       switch (chan_index) {
1497       case TGSI_CHAN_X:
1498          swizzle = inst->Predicate.SwizzleX;
1499          break;
1500       case TGSI_CHAN_Y:
1501          swizzle = inst->Predicate.SwizzleY;
1502          break;
1503       case TGSI_CHAN_Z:
1504          swizzle = inst->Predicate.SwizzleZ;
1505          break;
1506       case TGSI_CHAN_W:
1507          swizzle = inst->Predicate.SwizzleW;
1508          break;
1509       default:
1510          assert(0);
1511          return;
1512       }
1513
1514       assert(inst->Predicate.Index == 0);
1515
1516       pred = &mach->Predicates[inst->Predicate.Index].xyzw[swizzle];
1517
1518       if (inst->Predicate.Negate) {
1519          for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1520             if (pred->u[i]) {
1521                execmask &= ~(1 << i);
1522             }
1523          }
1524       } else {
1525          for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1526             if (!pred->u[i]) {
1527                execmask &= ~(1 << i);
1528             }
1529          }
1530       }
1531    }
1532
1533    switch (inst->Instruction.Saturate) {
1534    case TGSI_SAT_NONE:
1535       for (i = 0; i < TGSI_QUAD_SIZE; i++)
1536          if (execmask & (1 << i))
1537             dst->i[i] = chan->i[i];
1538       break;
1539
1540    case TGSI_SAT_ZERO_ONE:
1541       for (i = 0; i < TGSI_QUAD_SIZE; i++)
1542          if (execmask & (1 << i)) {
1543             if (chan->f[i] < 0.0f)
1544                dst->f[i] = 0.0f;
1545             else if (chan->f[i] > 1.0f)
1546                dst->f[i] = 1.0f;
1547             else
1548                dst->i[i] = chan->i[i];
1549          }
1550       break;
1551
1552    case TGSI_SAT_MINUS_PLUS_ONE:
1553       for (i = 0; i < TGSI_QUAD_SIZE; i++)
1554          if (execmask & (1 << i)) {
1555             if (chan->f[i] < -1.0f)
1556                dst->f[i] = -1.0f;
1557             else if (chan->f[i] > 1.0f)
1558                dst->f[i] = 1.0f;
1559             else
1560                dst->i[i] = chan->i[i];
1561          }
1562       break;
1563
1564    default:
1565       assert( 0 );
1566    }
1567 }
1568
1569 #define FETCH(VAL,INDEX,CHAN)\
1570     fetch_source(mach, VAL, &inst->Src[INDEX], CHAN, TGSI_EXEC_DATA_FLOAT)
1571
1572 #define IFETCH(VAL,INDEX,CHAN)\
1573     fetch_source(mach, VAL, &inst->Src[INDEX], CHAN, TGSI_EXEC_DATA_INT)
1574
1575
1576 /**
1577  * Execute ARB-style KIL which is predicated by a src register.
1578  * Kill fragment if any of the four values is less than zero.
1579  */
1580 static void
1581 exec_kil(struct tgsi_exec_machine *mach,
1582          const struct tgsi_full_instruction *inst)
1583 {
1584    uint uniquemask;
1585    uint chan_index;
1586    uint kilmask = 0; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */
1587    union tgsi_exec_channel r[1];
1588
1589    /* This mask stores component bits that were already tested. */
1590    uniquemask = 0;
1591
1592    for (chan_index = 0; chan_index < 4; chan_index++)
1593    {
1594       uint swizzle;
1595       uint i;
1596
1597       /* unswizzle channel */
1598       swizzle = tgsi_util_get_full_src_register_swizzle (
1599                         &inst->Src[0],
1600                         chan_index);
1601
1602       /* check if the component has not been already tested */
1603       if (uniquemask & (1 << swizzle))
1604          continue;
1605       uniquemask |= 1 << swizzle;
1606
1607       FETCH(&r[0], 0, chan_index);
1608       for (i = 0; i < 4; i++)
1609          if (r[0].f[i] < 0.0f)
1610             kilmask |= 1 << i;
1611    }
1612
1613    mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask;
1614 }
1615
1616 /**
1617  * Execute NVIDIA-style KIL which is predicated by a condition code.
1618  * Kill fragment if the condition code is TRUE.
1619  */
1620 static void
1621 exec_kilp(struct tgsi_exec_machine *mach,
1622           const struct tgsi_full_instruction *inst)
1623 {
1624    uint kilmask; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */
1625
1626    /* "unconditional" kil */
1627    kilmask = mach->ExecMask;
1628    mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask;
1629 }
1630
1631 static void
1632 emit_vertex(struct tgsi_exec_machine *mach)
1633 {
1634    /* FIXME: check for exec mask correctly
1635    unsigned i;
1636    for (i = 0; i < TGSI_QUAD_SIZE; ++i) {
1637          if ((mach->ExecMask & (1 << i)))
1638    */
1639    if (mach->ExecMask) {
1640       mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += mach->NumOutputs;
1641       mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++;
1642    }
1643 }
1644
1645 static void
1646 emit_primitive(struct tgsi_exec_machine *mach)
1647 {
1648    unsigned *prim_count = &mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0];
1649    /* FIXME: check for exec mask correctly
1650    unsigned i;
1651    for (i = 0; i < TGSI_QUAD_SIZE; ++i) {
1652          if ((mach->ExecMask & (1 << i)))
1653    */
1654    if (mach->ExecMask) {
1655       ++(*prim_count);
1656       debug_assert((*prim_count * mach->NumOutputs) < mach->MaxGeometryShaderOutputs);
1657       mach->Primitives[*prim_count] = 0;
1658    }
1659 }
1660
1661 static void
1662 conditional_emit_primitive(struct tgsi_exec_machine *mach)
1663 {
1664    if (TGSI_PROCESSOR_GEOMETRY == mach->Processor) {
1665       int emitted_verts =
1666          mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]];
1667       if (emitted_verts) {
1668          emit_primitive(mach);
1669       }
1670    }
1671 }
1672
1673
1674 /*
1675  * Fetch four texture samples using STR texture coordinates.
1676  */
1677 static void
1678 fetch_texel( struct tgsi_sampler *sampler,
1679              const unsigned sview_idx,
1680              const unsigned sampler_idx,
1681              const union tgsi_exec_channel *s,
1682              const union tgsi_exec_channel *t,
1683              const union tgsi_exec_channel *p,
1684              const union tgsi_exec_channel *c0,
1685              const union tgsi_exec_channel *c1,
1686              float derivs[3][2][TGSI_QUAD_SIZE],
1687              const int8_t offset[3],
1688              enum tgsi_sampler_control control,
1689              union tgsi_exec_channel *r,
1690              union tgsi_exec_channel *g,
1691              union tgsi_exec_channel *b,
1692              union tgsi_exec_channel *a )
1693 {
1694    uint j;
1695    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
1696
1697    /* FIXME: handle explicit derivs, offsets */
1698    sampler->get_samples(sampler, sview_idx, sampler_idx,
1699                         s->f, t->f, p->f, c0->f, c1->f, derivs, offset, control, rgba);
1700
1701    for (j = 0; j < 4; j++) {
1702       r->f[j] = rgba[0][j];
1703       g->f[j] = rgba[1][j];
1704       b->f[j] = rgba[2][j];
1705       a->f[j] = rgba[3][j];
1706    }
1707 }
1708
1709
1710 #define TEX_MODIFIER_NONE           0
1711 #define TEX_MODIFIER_PROJECTED      1
1712 #define TEX_MODIFIER_LOD_BIAS       2
1713 #define TEX_MODIFIER_EXPLICIT_LOD   3
1714 #define TEX_MODIFIER_LEVEL_ZERO     4
1715
1716
1717 /*
1718  * Fetch all 3 (for s,t,r coords) texel offsets, put them into int array.
1719  */
1720 static void
1721 fetch_texel_offsets(struct tgsi_exec_machine *mach,
1722                     const struct tgsi_full_instruction *inst,
1723                     int8_t offsets[3])
1724 {
1725    if (inst->Texture.NumOffsets == 1) {
1726       union tgsi_exec_channel index;
1727       union tgsi_exec_channel offset[3];
1728       index.i[0] = index.i[1] = index.i[2] = index.i[3] = inst->TexOffsets[0].Index;
1729       fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
1730                              inst->TexOffsets[0].SwizzleX, &index, &ZeroVec, &offset[0]);
1731       fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
1732                              inst->TexOffsets[0].SwizzleY, &index, &ZeroVec, &offset[1]);
1733       fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
1734                              inst->TexOffsets[0].SwizzleZ, &index, &ZeroVec, &offset[2]);
1735      offsets[0] = offset[0].i[0];
1736      offsets[1] = offset[1].i[0];
1737      offsets[2] = offset[2].i[0];
1738    } else {
1739      assert(inst->Texture.NumOffsets == 0);
1740      offsets[0] = offsets[1] = offsets[2] = 0;
1741    }
1742 }
1743
1744
1745 /*
1746  * Fetch dx and dy values for one channel (s, t or r).
1747  * Put dx values into one float array, dy values into another.
1748  */
1749 static void
1750 fetch_assign_deriv_channel(struct tgsi_exec_machine *mach,
1751                            const struct tgsi_full_instruction *inst,
1752                            unsigned regdsrcx,
1753                            unsigned chan,
1754                            float derivs[2][TGSI_QUAD_SIZE])
1755 {
1756    union tgsi_exec_channel d;
1757    FETCH(&d, regdsrcx, chan);
1758    derivs[0][0] = d.f[0];
1759    derivs[0][1] = d.f[1];
1760    derivs[0][2] = d.f[2];
1761    derivs[0][3] = d.f[3];
1762    FETCH(&d, regdsrcx + 1, chan);
1763    derivs[1][0] = d.f[0];
1764    derivs[1][1] = d.f[1];
1765    derivs[1][2] = d.f[2];
1766    derivs[1][3] = d.f[3];
1767 }
1768
1769
1770 /*
1771  * execute a texture instruction.
1772  *
1773  * modifier is used to control the channel routing for the\
1774  * instruction variants like proj, lod, and texture with lod bias.
1775  * sampler indicates which src register the sampler is contained in.
1776  */
1777 static void
1778 exec_tex(struct tgsi_exec_machine *mach,
1779          const struct tgsi_full_instruction *inst,
1780          uint modifier, uint sampler)
1781 {
1782    const uint unit = inst->Src[sampler].Register.Index;
1783    union tgsi_exec_channel r[4], cubearraycomp, cubelod;
1784    const union tgsi_exec_channel *lod = &ZeroVec;
1785    enum tgsi_sampler_control control =  tgsi_sampler_lod_none;
1786    uint chan;
1787    int8_t offsets[3];
1788
1789    /* always fetch all 3 offsets, overkill but keeps code simple */
1790    fetch_texel_offsets(mach, inst, offsets);
1791
1792    assert(modifier != TEX_MODIFIER_LEVEL_ZERO);
1793
1794    if (modifier != TEX_MODIFIER_NONE && (sampler == 1)) {
1795       FETCH(&r[3], 0, TGSI_CHAN_W);
1796       if (modifier != TEX_MODIFIER_PROJECTED) {
1797          lod = &r[3];
1798       }
1799    }
1800
1801    if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
1802       control = tgsi_sampler_lod_explicit;
1803    } else if (modifier == TEX_MODIFIER_LOD_BIAS){
1804       control = tgsi_sampler_lod_bias;
1805    }
1806
1807    switch (inst->Texture.Texture) {
1808    case TGSI_TEXTURE_1D:
1809       FETCH(&r[0], 0, TGSI_CHAN_X);
1810
1811       if (modifier == TEX_MODIFIER_PROJECTED) {
1812          micro_div(&r[0], &r[0], &r[3]);
1813       }
1814
1815       fetch_texel(mach->Sampler, unit, unit,
1816                   &r[0], &ZeroVec, &ZeroVec, &ZeroVec, lod, /* S, T, P, C, LOD */
1817                   NULL, offsets, control,
1818                   &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
1819       break;
1820
1821    case TGSI_TEXTURE_SHADOW1D:
1822       FETCH(&r[0], 0, TGSI_CHAN_X);
1823       FETCH(&r[2], 0, TGSI_CHAN_Z);
1824
1825       if (modifier == TEX_MODIFIER_PROJECTED) {
1826          micro_div(&r[0], &r[0], &r[3]);
1827          micro_div(&r[2], &r[2], &r[3]);
1828       }
1829
1830       fetch_texel(mach->Sampler, unit, unit,
1831                   &r[0], &ZeroVec, &r[2], &ZeroVec, lod, /* S, T, P, C, LOD */
1832                   NULL, offsets, control,
1833                   &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
1834       break;
1835
1836    case TGSI_TEXTURE_2D:
1837    case TGSI_TEXTURE_RECT:
1838       FETCH(&r[0], 0, TGSI_CHAN_X);
1839       FETCH(&r[1], 0, TGSI_CHAN_Y);
1840
1841       if (modifier == TEX_MODIFIER_PROJECTED) {
1842          micro_div(&r[0], &r[0], &r[3]);
1843          micro_div(&r[1], &r[1], &r[3]);
1844       }
1845
1846       fetch_texel(mach->Sampler, unit, unit,
1847                   &r[0], &r[1], &ZeroVec, &ZeroVec, lod,    /* S, T, P, C, LOD */
1848                   NULL, offsets, control,
1849                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
1850       break;
1851
1852    case TGSI_TEXTURE_SHADOW2D:
1853    case TGSI_TEXTURE_SHADOWRECT:
1854       FETCH(&r[0], 0, TGSI_CHAN_X);
1855       FETCH(&r[1], 0, TGSI_CHAN_Y);
1856       FETCH(&r[2], 0, TGSI_CHAN_Z);
1857
1858       if (modifier == TEX_MODIFIER_PROJECTED) {
1859          micro_div(&r[0], &r[0], &r[3]);
1860          micro_div(&r[1], &r[1], &r[3]);
1861          micro_div(&r[2], &r[2], &r[3]);
1862       }
1863
1864       fetch_texel(mach->Sampler, unit, unit,
1865                   &r[0], &r[1], &r[2], &ZeroVec, lod,    /* S, T, P, C, LOD */
1866                   NULL, offsets, control,
1867                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
1868       break;
1869
1870    case TGSI_TEXTURE_1D_ARRAY:
1871       FETCH(&r[0], 0, TGSI_CHAN_X);
1872       FETCH(&r[1], 0, TGSI_CHAN_Y);
1873
1874       if (modifier == TEX_MODIFIER_PROJECTED) {
1875          micro_div(&r[0], &r[0], &r[3]);
1876       }
1877
1878       fetch_texel(mach->Sampler, unit, unit,
1879                   &r[0], &r[1], &ZeroVec, &ZeroVec, lod,   /* S, T, P, C, LOD */
1880                   NULL, offsets, control,
1881                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
1882       break;
1883    case TGSI_TEXTURE_SHADOW1D_ARRAY:
1884       FETCH(&r[0], 0, TGSI_CHAN_X);
1885       FETCH(&r[1], 0, TGSI_CHAN_Y);
1886       FETCH(&r[2], 0, TGSI_CHAN_Z);
1887
1888       if (modifier == TEX_MODIFIER_PROJECTED) {
1889          micro_div(&r[0], &r[0], &r[3]);
1890          micro_div(&r[2], &r[2], &r[3]);
1891       }
1892
1893       fetch_texel(mach->Sampler, unit, unit,
1894                   &r[0], &r[1], &r[2], &ZeroVec, lod,   /* S, T, P, C, LOD */
1895                   NULL, offsets, control,
1896                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
1897       break;
1898
1899    case TGSI_TEXTURE_2D_ARRAY:
1900       FETCH(&r[0], 0, TGSI_CHAN_X);
1901       FETCH(&r[1], 0, TGSI_CHAN_Y);
1902       FETCH(&r[2], 0, TGSI_CHAN_Z);
1903
1904       if (modifier == TEX_MODIFIER_PROJECTED) {
1905          micro_div(&r[0], &r[0], &r[3]);
1906          micro_div(&r[1], &r[1], &r[3]);
1907       }
1908
1909       fetch_texel(mach->Sampler, unit, unit,
1910                   &r[0], &r[1], &r[2], &ZeroVec, lod,   /* S, T, P, C, LOD */
1911                   NULL, offsets, control,
1912                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
1913       break;
1914    case TGSI_TEXTURE_SHADOW2D_ARRAY:
1915    case TGSI_TEXTURE_SHADOWCUBE:
1916       FETCH(&r[0], 0, TGSI_CHAN_X);
1917       FETCH(&r[1], 0, TGSI_CHAN_Y);
1918       FETCH(&r[2], 0, TGSI_CHAN_Z);
1919       FETCH(&r[3], 0, TGSI_CHAN_W);
1920
1921       fetch_texel(mach->Sampler, unit, unit,
1922                   &r[0], &r[1], &r[2], &r[3], &ZeroVec,    /* S, T, P, C, LOD */
1923                   NULL, offsets, control,
1924                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
1925       break;
1926    case TGSI_TEXTURE_CUBE_ARRAY:
1927       FETCH(&r[0], 0, TGSI_CHAN_X);
1928       FETCH(&r[1], 0, TGSI_CHAN_Y);
1929       FETCH(&r[2], 0, TGSI_CHAN_Z);
1930       FETCH(&r[3], 0, TGSI_CHAN_W);
1931
1932       if (modifier == TEX_MODIFIER_EXPLICIT_LOD ||
1933           modifier == TEX_MODIFIER_LOD_BIAS)
1934          FETCH(&cubelod, 1, TGSI_CHAN_X);
1935       else
1936          cubelod = ZeroVec;
1937
1938       fetch_texel(mach->Sampler, unit, unit,
1939                   &r[0], &r[1], &r[2], &r[3], &cubelod,    /* S, T, P, C, LOD */
1940                   NULL, offsets, control,
1941                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
1942       break;
1943    case TGSI_TEXTURE_3D:
1944    case TGSI_TEXTURE_CUBE:
1945       FETCH(&r[0], 0, TGSI_CHAN_X);
1946       FETCH(&r[1], 0, TGSI_CHAN_Y);
1947       FETCH(&r[2], 0, TGSI_CHAN_Z);
1948
1949       if (modifier == TEX_MODIFIER_PROJECTED) {
1950          micro_div(&r[0], &r[0], &r[3]);
1951          micro_div(&r[1], &r[1], &r[3]);
1952          micro_div(&r[2], &r[2], &r[3]);
1953       }
1954
1955       fetch_texel(mach->Sampler, unit, unit,
1956                   &r[0], &r[1], &r[2], &ZeroVec, lod,
1957                   NULL, offsets, control,
1958                   &r[0], &r[1], &r[2], &r[3]);
1959       break;
1960
1961    case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
1962       FETCH(&r[0], 0, TGSI_CHAN_X);
1963       FETCH(&r[1], 0, TGSI_CHAN_Y);
1964       FETCH(&r[2], 0, TGSI_CHAN_Z);
1965       FETCH(&r[3], 0, TGSI_CHAN_W);
1966
1967       FETCH(&cubearraycomp, 1, TGSI_CHAN_X);
1968
1969       fetch_texel(mach->Sampler, unit, unit,
1970                   &r[0], &r[1], &r[2], &r[3], &cubearraycomp, /* S, T, P, C, LOD */
1971                   NULL, offsets, control,
1972                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
1973       break;
1974    default:
1975       assert(0);
1976    }
1977
1978 #if 0
1979    debug_printf("fetch r: %g %g %g %g\n",
1980          r[0].f[0], r[0].f[1], r[0].f[2], r[0].f[3]);
1981    debug_printf("fetch g: %g %g %g %g\n",
1982          r[1].f[0], r[1].f[1], r[1].f[2], r[1].f[3]);
1983    debug_printf("fetch b: %g %g %g %g\n",
1984          r[2].f[0], r[2].f[1], r[2].f[2], r[2].f[3]);
1985    debug_printf("fetch a: %g %g %g %g\n",
1986          r[3].f[0], r[3].f[1], r[3].f[2], r[3].f[3]);
1987 #endif
1988
1989    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
1990       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
1991          store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
1992       }
1993    }
1994 }
1995
1996
1997 static void
1998 exec_txd(struct tgsi_exec_machine *mach,
1999          const struct tgsi_full_instruction *inst)
2000 {
2001    const uint unit = inst->Src[3].Register.Index;
2002    union tgsi_exec_channel r[4];
2003    float derivs[3][2][TGSI_QUAD_SIZE];
2004    uint chan;
2005    int8_t offsets[3];
2006
2007    /* always fetch all 3 offsets, overkill but keeps code simple */
2008    fetch_texel_offsets(mach, inst, offsets);
2009
2010    switch (inst->Texture.Texture) {
2011    case TGSI_TEXTURE_1D:
2012       FETCH(&r[0], 0, TGSI_CHAN_X);
2013
2014       fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
2015
2016       fetch_texel(mach->Sampler, unit, unit,
2017                   &r[0], &ZeroVec, &ZeroVec, &ZeroVec, &ZeroVec,   /* S, T, P, C, LOD */
2018                   derivs, offsets, tgsi_sampler_derivs_explicit,
2019                   &r[0], &r[1], &r[2], &r[3]);           /* R, G, B, A */
2020       break;
2021
2022    case TGSI_TEXTURE_SHADOW1D:
2023    case TGSI_TEXTURE_1D_ARRAY:
2024    case TGSI_TEXTURE_SHADOW1D_ARRAY:
2025       /* SHADOW1D/1D_ARRAY would not need Y/Z respectively, but don't bother */
2026       FETCH(&r[0], 0, TGSI_CHAN_X);
2027       FETCH(&r[1], 0, TGSI_CHAN_Y);
2028       FETCH(&r[2], 0, TGSI_CHAN_Z);
2029
2030       fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
2031
2032       fetch_texel(mach->Sampler, unit, unit,
2033                   &r[0], &r[1], &r[2], &ZeroVec, &ZeroVec,   /* S, T, P, C, LOD */
2034                   derivs, offsets, tgsi_sampler_derivs_explicit,
2035                   &r[0], &r[1], &r[2], &r[3]);           /* R, G, B, A */
2036       break;
2037
2038    case TGSI_TEXTURE_2D:
2039    case TGSI_TEXTURE_RECT:
2040       FETCH(&r[0], 0, TGSI_CHAN_X);
2041       FETCH(&r[1], 0, TGSI_CHAN_Y);
2042
2043       fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
2044       fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_Y, derivs[1]);
2045
2046       fetch_texel(mach->Sampler, unit, unit,
2047                   &r[0], &r[1], &ZeroVec, &ZeroVec, &ZeroVec,   /* S, T, P, C, LOD */
2048                   derivs, offsets, tgsi_sampler_derivs_explicit,
2049                   &r[0], &r[1], &r[2], &r[3]);           /* R, G, B, A */
2050       break;
2051
2052
2053    case TGSI_TEXTURE_SHADOW2D:
2054    case TGSI_TEXTURE_SHADOWRECT:
2055    case TGSI_TEXTURE_2D_ARRAY:
2056    case TGSI_TEXTURE_SHADOW2D_ARRAY:
2057       /* only SHADOW2D_ARRAY actually needs W */
2058       FETCH(&r[0], 0, TGSI_CHAN_X);
2059       FETCH(&r[1], 0, TGSI_CHAN_Y);
2060       FETCH(&r[2], 0, TGSI_CHAN_Z);
2061       FETCH(&r[3], 0, TGSI_CHAN_W);
2062
2063       fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
2064       fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_Y, derivs[1]);
2065
2066       fetch_texel(mach->Sampler, unit, unit,
2067                   &r[0], &r[1], &r[2], &r[3], &ZeroVec,   /* inputs */
2068                   derivs, offsets, tgsi_sampler_derivs_explicit,
2069                   &r[0], &r[1], &r[2], &r[3]);     /* outputs */
2070       break;
2071
2072    case TGSI_TEXTURE_3D:
2073    case TGSI_TEXTURE_CUBE:
2074    case TGSI_TEXTURE_CUBE_ARRAY:
2075       /* only TEXTURE_CUBE_ARRAY actually needs W */
2076       FETCH(&r[0], 0, TGSI_CHAN_X);
2077       FETCH(&r[1], 0, TGSI_CHAN_Y);
2078       FETCH(&r[2], 0, TGSI_CHAN_Z);
2079       FETCH(&r[3], 0, TGSI_CHAN_W);
2080
2081       fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
2082       fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_Y, derivs[1]);
2083       fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_Z, derivs[2]);
2084
2085       fetch_texel(mach->Sampler, unit, unit,
2086                   &r[0], &r[1], &r[2], &r[3], &ZeroVec,   /* inputs */
2087                   derivs, offsets, tgsi_sampler_derivs_explicit,
2088                   &r[0], &r[1], &r[2], &r[3]);     /* outputs */
2089       break;
2090
2091    default:
2092       assert(0);
2093    }
2094
2095    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2096       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2097          store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
2098       }
2099    }
2100 }
2101
2102
2103 static void
2104 exec_txf(struct tgsi_exec_machine *mach,
2105          const struct tgsi_full_instruction *inst)
2106 {
2107    const uint unit = inst->Src[1].Register.Index;
2108    union tgsi_exec_channel r[4];
2109    uint chan;
2110    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
2111    int j;
2112    int8_t offsets[3];
2113    unsigned target;
2114
2115    /* always fetch all 3 offsets, overkill but keeps code simple */
2116    fetch_texel_offsets(mach, inst, offsets);
2117
2118    IFETCH(&r[3], 0, TGSI_CHAN_W);
2119
2120    if (inst->Instruction.Opcode == TGSI_OPCODE_SAMPLE_I) {
2121       target = mach->SamplerViews[unit].Resource;
2122    }
2123    else {
2124       target = inst->Texture.Texture;
2125    }
2126    switch(target) {
2127    case TGSI_TEXTURE_3D:
2128    case TGSI_TEXTURE_2D_ARRAY:
2129    case TGSI_TEXTURE_SHADOW2D_ARRAY:
2130       IFETCH(&r[2], 0, TGSI_CHAN_Z);
2131       /* fallthrough */
2132    case TGSI_TEXTURE_2D:
2133    case TGSI_TEXTURE_RECT:
2134    case TGSI_TEXTURE_SHADOW1D_ARRAY:
2135    case TGSI_TEXTURE_SHADOW2D:
2136    case TGSI_TEXTURE_SHADOWRECT:
2137    case TGSI_TEXTURE_1D_ARRAY:
2138       IFETCH(&r[1], 0, TGSI_CHAN_Y);
2139       /* fallthrough */
2140    case TGSI_TEXTURE_BUFFER:
2141    case TGSI_TEXTURE_1D:
2142    case TGSI_TEXTURE_SHADOW1D:
2143       IFETCH(&r[0], 0, TGSI_CHAN_X);
2144       break;
2145    default:
2146       assert(0);
2147       break;
2148    }      
2149
2150    mach->Sampler->get_texel(mach->Sampler, unit, r[0].i, r[1].i, r[2].i, r[3].i,
2151                             offsets, rgba);
2152
2153    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
2154       r[0].f[j] = rgba[0][j];
2155       r[1].f[j] = rgba[1][j];
2156       r[2].f[j] = rgba[2][j];
2157       r[3].f[j] = rgba[3][j];
2158    }
2159
2160    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2161       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2162          store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
2163       }
2164    }
2165 }
2166
2167 static void
2168 exec_txq(struct tgsi_exec_machine *mach,
2169          const struct tgsi_full_instruction *inst)
2170 {
2171    const uint unit = inst->Src[1].Register.Index;
2172    int result[4];
2173    union tgsi_exec_channel r[4], src;
2174    uint chan;
2175    int i,j;
2176
2177    fetch_source(mach, &src, &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_INT);
2178
2179    mach->Sampler->get_dims(mach->Sampler, unit, src.i[0], result);
2180
2181    for (i = 0; i < TGSI_QUAD_SIZE; i++) {
2182       for (j = 0; j < 4; j++) {
2183          r[j].i[i] = result[j];
2184       }
2185    }
2186
2187    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2188       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2189          store_dest(mach, &r[chan], &inst->Dst[0], inst, chan,
2190                     TGSI_EXEC_DATA_INT);
2191       }
2192    }
2193 }
2194
2195 static void
2196 exec_sample(struct tgsi_exec_machine *mach,
2197             const struct tgsi_full_instruction *inst,
2198             uint modifier, boolean compare)
2199 {
2200    const uint resource_unit = inst->Src[1].Register.Index;
2201    const uint sampler_unit = inst->Src[2].Register.Index;
2202    union tgsi_exec_channel r[4], c1;
2203    const union tgsi_exec_channel *lod = &ZeroVec;
2204    enum tgsi_sampler_control control = tgsi_sampler_lod_none;
2205    uint chan;
2206    int8_t offsets[3];
2207
2208    /* always fetch all 3 offsets, overkill but keeps code simple */
2209    fetch_texel_offsets(mach, inst, offsets);
2210
2211    assert(modifier != TEX_MODIFIER_PROJECTED);
2212
2213    if (modifier != TEX_MODIFIER_NONE) {
2214       if (modifier == TEX_MODIFIER_LOD_BIAS) {
2215          FETCH(&c1, 3, TGSI_CHAN_X);
2216          lod = &c1;
2217          control = tgsi_sampler_lod_bias;
2218       }
2219       else if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
2220          FETCH(&c1, 3, TGSI_CHAN_X);
2221          lod = &c1;
2222          control = tgsi_sampler_lod_explicit;
2223       }
2224       else {
2225          assert(modifier == TEX_MODIFIER_LEVEL_ZERO);
2226          control = tgsi_sampler_lod_zero;
2227       }
2228    }
2229
2230    FETCH(&r[0], 0, TGSI_CHAN_X);
2231
2232    switch (mach->SamplerViews[resource_unit].Resource) {
2233    case TGSI_TEXTURE_1D:
2234       if (compare) {
2235          FETCH(&r[2], 3, TGSI_CHAN_X);
2236          fetch_texel(mach->Sampler, resource_unit, sampler_unit,
2237                      &r[0], &ZeroVec, &r[2], &ZeroVec, lod, /* S, T, P, C, LOD */
2238                      NULL, offsets, control,
2239                      &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
2240       }
2241       else {
2242          fetch_texel(mach->Sampler, resource_unit, sampler_unit,
2243                      &r[0], &ZeroVec, &ZeroVec, &ZeroVec, lod, /* S, T, P, C, LOD */
2244                      NULL, offsets, control,
2245                      &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
2246       }
2247       break;
2248
2249    case TGSI_TEXTURE_1D_ARRAY:
2250    case TGSI_TEXTURE_2D:
2251    case TGSI_TEXTURE_RECT:
2252       FETCH(&r[1], 0, TGSI_CHAN_Y);
2253       if (compare) {
2254          FETCH(&r[2], 3, TGSI_CHAN_X);
2255          fetch_texel(mach->Sampler, resource_unit, sampler_unit,
2256                      &r[0], &r[1], &r[2], &ZeroVec, lod,    /* S, T, P, C, LOD */
2257                      NULL, offsets, control,
2258                      &r[0], &r[1], &r[2], &r[3]);  /* outputs */
2259       }
2260       else {
2261          fetch_texel(mach->Sampler, resource_unit, sampler_unit,
2262                      &r[0], &r[1], &ZeroVec, &ZeroVec, lod,    /* S, T, P, C, LOD */
2263                      NULL, offsets, control,
2264                      &r[0], &r[1], &r[2], &r[3]);  /* outputs */
2265       }
2266       break;
2267
2268    case TGSI_TEXTURE_2D_ARRAY:
2269    case TGSI_TEXTURE_3D:
2270    case TGSI_TEXTURE_CUBE:
2271       FETCH(&r[1], 0, TGSI_CHAN_Y);
2272       FETCH(&r[2], 0, TGSI_CHAN_Z);
2273       if(compare) {
2274          FETCH(&r[3], 3, TGSI_CHAN_X);
2275          fetch_texel(mach->Sampler, resource_unit, sampler_unit,
2276                      &r[0], &r[1], &r[2], &r[3], lod,
2277                      NULL, offsets, control,
2278                      &r[0], &r[1], &r[2], &r[3]);
2279       }
2280       else {
2281          fetch_texel(mach->Sampler, resource_unit, sampler_unit,
2282                      &r[0], &r[1], &r[2], &ZeroVec, lod,
2283                      NULL, offsets, control,
2284                      &r[0], &r[1], &r[2], &r[3]);
2285       }
2286       break;
2287
2288    case TGSI_TEXTURE_CUBE_ARRAY:
2289       FETCH(&r[1], 0, TGSI_CHAN_Y);
2290       FETCH(&r[2], 0, TGSI_CHAN_Z);
2291       FETCH(&r[3], 0, TGSI_CHAN_W);
2292       if(compare) {
2293          FETCH(&r[4], 3, TGSI_CHAN_X);
2294          fetch_texel(mach->Sampler, resource_unit, sampler_unit,
2295                      &r[0], &r[1], &r[2], &r[3], &r[4],
2296                      NULL, offsets, control,
2297                      &r[0], &r[1], &r[2], &r[3]);
2298       }
2299       else {
2300          fetch_texel(mach->Sampler, resource_unit, sampler_unit,
2301                      &r[0], &r[1], &r[2], &r[3], lod,
2302                      NULL, offsets, control,
2303                      &r[0], &r[1], &r[2], &r[3]);
2304       }
2305       break;
2306
2307
2308    default:
2309       assert(0);
2310    }
2311
2312    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2313       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2314          store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
2315       }
2316    }
2317 }
2318
2319 static void
2320 exec_sample_d(struct tgsi_exec_machine *mach,
2321               const struct tgsi_full_instruction *inst)
2322 {
2323    const uint resource_unit = inst->Src[1].Register.Index;
2324    const uint sampler_unit = inst->Src[2].Register.Index;
2325    union tgsi_exec_channel r[4];
2326    float derivs[3][2][TGSI_QUAD_SIZE];
2327    uint chan;
2328    int8_t offsets[3];
2329
2330    /* always fetch all 3 offsets, overkill but keeps code simple */
2331    fetch_texel_offsets(mach, inst, offsets);
2332
2333    FETCH(&r[0], 0, TGSI_CHAN_X);
2334
2335    switch (mach->SamplerViews[resource_unit].Resource) {
2336    case TGSI_TEXTURE_1D:
2337    case TGSI_TEXTURE_1D_ARRAY:
2338       /* only 1D array actually needs Y */
2339       FETCH(&r[1], 0, TGSI_CHAN_Y);
2340
2341       fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_X, derivs[0]);
2342
2343       fetch_texel(mach->Sampler, resource_unit, sampler_unit,
2344                   &r[0], &r[1], &ZeroVec, &ZeroVec, &ZeroVec,   /* S, T, P, C, LOD */
2345                   derivs, offsets, tgsi_sampler_derivs_explicit,
2346                   &r[0], &r[1], &r[2], &r[3]);           /* R, G, B, A */
2347       break;
2348
2349    case TGSI_TEXTURE_2D:
2350    case TGSI_TEXTURE_RECT:
2351    case TGSI_TEXTURE_2D_ARRAY:
2352       /* only 2D array actually needs Z */
2353       FETCH(&r[1], 0, TGSI_CHAN_Y);
2354       FETCH(&r[2], 0, TGSI_CHAN_Z);
2355
2356       fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_X, derivs[0]);
2357       fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_Y, derivs[1]);
2358
2359       fetch_texel(mach->Sampler, resource_unit, sampler_unit,
2360                   &r[0], &r[1], &r[2], &ZeroVec, &ZeroVec,   /* inputs */
2361                   derivs, offsets, tgsi_sampler_derivs_explicit,
2362                   &r[0], &r[1], &r[2], &r[3]);     /* outputs */
2363       break;
2364
2365    case TGSI_TEXTURE_3D:
2366    case TGSI_TEXTURE_CUBE:
2367    case TGSI_TEXTURE_CUBE_ARRAY:
2368       /* only cube array actually needs W */
2369       FETCH(&r[1], 0, TGSI_CHAN_Y);
2370       FETCH(&r[2], 0, TGSI_CHAN_Z);
2371       FETCH(&r[3], 0, TGSI_CHAN_W);
2372
2373       fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_X, derivs[0]);
2374       fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_Y, derivs[1]);
2375       fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_Z, derivs[2]);
2376
2377       fetch_texel(mach->Sampler, resource_unit, sampler_unit,
2378                   &r[0], &r[1], &r[2], &r[3], &ZeroVec,
2379                   derivs, offsets, tgsi_sampler_derivs_explicit,
2380                   &r[0], &r[1], &r[2], &r[3]);
2381       break;
2382
2383    default:
2384       assert(0);
2385    }
2386
2387    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2388       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2389          store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
2390       }
2391    }
2392 }
2393
2394
2395 /**
2396  * Evaluate a constant-valued coefficient at the position of the
2397  * current quad.
2398  */
2399 static void
2400 eval_constant_coef(
2401    struct tgsi_exec_machine *mach,
2402    unsigned attrib,
2403    unsigned chan )
2404 {
2405    unsigned i;
2406
2407    for( i = 0; i < TGSI_QUAD_SIZE; i++ ) {
2408       mach->Inputs[attrib].xyzw[chan].f[i] = mach->InterpCoefs[attrib].a0[chan];
2409    }
2410 }
2411
2412 /**
2413  * Evaluate a linear-valued coefficient at the position of the
2414  * current quad.
2415  */
2416 static void
2417 eval_linear_coef(
2418    struct tgsi_exec_machine *mach,
2419    unsigned attrib,
2420    unsigned chan )
2421 {
2422    const float x = mach->QuadPos.xyzw[0].f[0];
2423    const float y = mach->QuadPos.xyzw[1].f[0];
2424    const float dadx = mach->InterpCoefs[attrib].dadx[chan];
2425    const float dady = mach->InterpCoefs[attrib].dady[chan];
2426    const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y;
2427    mach->Inputs[attrib].xyzw[chan].f[0] = a0;
2428    mach->Inputs[attrib].xyzw[chan].f[1] = a0 + dadx;
2429    mach->Inputs[attrib].xyzw[chan].f[2] = a0 + dady;
2430    mach->Inputs[attrib].xyzw[chan].f[3] = a0 + dadx + dady;
2431 }
2432
2433 /**
2434  * Evaluate a perspective-valued coefficient at the position of the
2435  * current quad.
2436  */
2437 static void
2438 eval_perspective_coef(
2439    struct tgsi_exec_machine *mach,
2440    unsigned attrib,
2441    unsigned chan )
2442 {
2443    const float x = mach->QuadPos.xyzw[0].f[0];
2444    const float y = mach->QuadPos.xyzw[1].f[0];
2445    const float dadx = mach->InterpCoefs[attrib].dadx[chan];
2446    const float dady = mach->InterpCoefs[attrib].dady[chan];
2447    const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y;
2448    const float *w = mach->QuadPos.xyzw[3].f;
2449    /* divide by W here */
2450    mach->Inputs[attrib].xyzw[chan].f[0] = a0 / w[0];
2451    mach->Inputs[attrib].xyzw[chan].f[1] = (a0 + dadx) / w[1];
2452    mach->Inputs[attrib].xyzw[chan].f[2] = (a0 + dady) / w[2];
2453    mach->Inputs[attrib].xyzw[chan].f[3] = (a0 + dadx + dady) / w[3];
2454 }
2455
2456
2457 typedef void (* eval_coef_func)(
2458    struct tgsi_exec_machine *mach,
2459    unsigned attrib,
2460    unsigned chan );
2461
2462 static void
2463 exec_declaration(struct tgsi_exec_machine *mach,
2464                  const struct tgsi_full_declaration *decl)
2465 {
2466    if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) {
2467       mach->SamplerViews[decl->Range.First] = decl->SamplerView;
2468       return;
2469    }
2470
2471    if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) {
2472       if (decl->Declaration.File == TGSI_FILE_INPUT) {
2473          uint first, last, mask;
2474
2475          first = decl->Range.First;
2476          last = decl->Range.Last;
2477          mask = decl->Declaration.UsageMask;
2478
2479          /* XXX we could remove this special-case code since
2480           * mach->InterpCoefs[first].a0 should already have the
2481           * front/back-face value.  But we should first update the
2482           * ureg code to emit the right UsageMask value (WRITEMASK_X).
2483           * Then, we could remove the tgsi_exec_machine::Face field.
2484           */
2485          /* XXX make FACE a system value */
2486          if (decl->Semantic.Name == TGSI_SEMANTIC_FACE) {
2487             uint i;
2488
2489             assert(decl->Semantic.Index == 0);
2490             assert(first == last);
2491
2492             for (i = 0; i < TGSI_QUAD_SIZE; i++) {
2493                mach->Inputs[first].xyzw[0].f[i] = mach->Face;
2494             }
2495          } else {
2496             eval_coef_func eval;
2497             uint i, j;
2498
2499             switch (decl->Interp.Interpolate) {
2500             case TGSI_INTERPOLATE_CONSTANT:
2501                eval = eval_constant_coef;
2502                break;
2503
2504             case TGSI_INTERPOLATE_LINEAR:
2505                eval = eval_linear_coef;
2506                break;
2507
2508             case TGSI_INTERPOLATE_PERSPECTIVE:
2509                eval = eval_perspective_coef;
2510                break;
2511
2512             case TGSI_INTERPOLATE_COLOR:
2513                eval = mach->flatshade_color ? eval_constant_coef : eval_perspective_coef;
2514                break;
2515
2516             default:
2517                assert(0);
2518                return;
2519             }
2520
2521             for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
2522                if (mask & (1 << j)) {
2523                   for (i = first; i <= last; i++) {
2524                      eval(mach, i, j);
2525                   }
2526                }
2527             }
2528          }
2529
2530          if (DEBUG_EXECUTION) {
2531             uint i, j;
2532             for (i = first; i <= last; ++i) {
2533                debug_printf("IN[%2u] = ", i);
2534                for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
2535                   if (j > 0) {
2536                      debug_printf("         ");
2537                   }
2538                   debug_printf("(%6f %u, %6f %u, %6f %u, %6f %u)\n",
2539                                mach->Inputs[i].xyzw[0].f[j], mach->Inputs[i].xyzw[0].u[j],
2540                                mach->Inputs[i].xyzw[1].f[j], mach->Inputs[i].xyzw[1].u[j],
2541                                mach->Inputs[i].xyzw[2].f[j], mach->Inputs[i].xyzw[2].u[j],
2542                                mach->Inputs[i].xyzw[3].f[j], mach->Inputs[i].xyzw[3].u[j]);
2543                }
2544             }
2545          }
2546       }
2547    }
2548
2549    if (decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE) {
2550       mach->SysSemanticToIndex[decl->Declaration.Semantic] = decl->Range.First;
2551    }
2552 }
2553
2554
2555 typedef void (* micro_op)(union tgsi_exec_channel *dst);
2556
2557 static void
2558 exec_vector(struct tgsi_exec_machine *mach,
2559             const struct tgsi_full_instruction *inst,
2560             micro_op op,
2561             enum tgsi_exec_datatype dst_datatype)
2562 {
2563    unsigned int chan;
2564
2565    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2566       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2567          union tgsi_exec_channel dst;
2568
2569          op(&dst);
2570          store_dest(mach, &dst, &inst->Dst[0], inst, chan, dst_datatype);
2571       }
2572    }
2573 }
2574
2575 typedef void (* micro_unary_op)(union tgsi_exec_channel *dst,
2576                                 const union tgsi_exec_channel *src);
2577
2578 static void
2579 exec_scalar_unary(struct tgsi_exec_machine *mach,
2580                   const struct tgsi_full_instruction *inst,
2581                   micro_unary_op op,
2582                   enum tgsi_exec_datatype dst_datatype,
2583                   enum tgsi_exec_datatype src_datatype)
2584 {
2585    unsigned int chan;
2586    union tgsi_exec_channel src;
2587    union tgsi_exec_channel dst;
2588
2589    fetch_source(mach, &src, &inst->Src[0], TGSI_CHAN_X, src_datatype);
2590    op(&dst, &src);
2591    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2592       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2593          store_dest(mach, &dst, &inst->Dst[0], inst, chan, dst_datatype);
2594       }
2595    }
2596 }
2597
2598 static void
2599 exec_vector_unary(struct tgsi_exec_machine *mach,
2600                   const struct tgsi_full_instruction *inst,
2601                   micro_unary_op op,
2602                   enum tgsi_exec_datatype dst_datatype,
2603                   enum tgsi_exec_datatype src_datatype)
2604 {
2605    unsigned int chan;
2606    struct tgsi_exec_vector dst;
2607
2608    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2609       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2610          union tgsi_exec_channel src;
2611
2612          fetch_source(mach, &src, &inst->Src[0], chan, src_datatype);
2613          op(&dst.xyzw[chan], &src);
2614       }
2615    }
2616    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2617       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2618          store_dest(mach, &dst.xyzw[chan], &inst->Dst[0], inst, chan, dst_datatype);
2619       }
2620    }
2621 }
2622
2623 typedef void (* micro_binary_op)(union tgsi_exec_channel *dst,
2624                                  const union tgsi_exec_channel *src0,
2625                                  const union tgsi_exec_channel *src1);
2626
2627 static void
2628 exec_scalar_binary(struct tgsi_exec_machine *mach,
2629                    const struct tgsi_full_instruction *inst,
2630                    micro_binary_op op,
2631                    enum tgsi_exec_datatype dst_datatype,
2632                    enum tgsi_exec_datatype src_datatype)
2633 {
2634    unsigned int chan;
2635    union tgsi_exec_channel src[2];
2636    union tgsi_exec_channel dst;
2637
2638    fetch_source(mach, &src[0], &inst->Src[0], TGSI_CHAN_X, src_datatype);
2639    fetch_source(mach, &src[1], &inst->Src[1], TGSI_CHAN_Y, src_datatype);
2640    op(&dst, &src[0], &src[1]);
2641    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2642       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2643          store_dest(mach, &dst, &inst->Dst[0], inst, chan, dst_datatype);
2644       }
2645    }
2646 }
2647
2648 static void
2649 exec_vector_binary(struct tgsi_exec_machine *mach,
2650                    const struct tgsi_full_instruction *inst,
2651                    micro_binary_op op,
2652                    enum tgsi_exec_datatype dst_datatype,
2653                    enum tgsi_exec_datatype src_datatype)
2654 {
2655    unsigned int chan;
2656    struct tgsi_exec_vector dst;
2657
2658    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2659       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2660          union tgsi_exec_channel src[2];
2661
2662          fetch_source(mach, &src[0], &inst->Src[0], chan, src_datatype);
2663          fetch_source(mach, &src[1], &inst->Src[1], chan, src_datatype);
2664          op(&dst.xyzw[chan], &src[0], &src[1]);
2665       }
2666    }
2667    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2668       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2669          store_dest(mach, &dst.xyzw[chan], &inst->Dst[0], inst, chan, dst_datatype);
2670       }
2671    }
2672 }
2673
2674 typedef void (* micro_trinary_op)(union tgsi_exec_channel *dst,
2675                                   const union tgsi_exec_channel *src0,
2676                                   const union tgsi_exec_channel *src1,
2677                                   const union tgsi_exec_channel *src2);
2678
2679 static void
2680 exec_vector_trinary(struct tgsi_exec_machine *mach,
2681                     const struct tgsi_full_instruction *inst,
2682                     micro_trinary_op op,
2683                     enum tgsi_exec_datatype dst_datatype,
2684                     enum tgsi_exec_datatype src_datatype)
2685 {
2686    unsigned int chan;
2687    struct tgsi_exec_vector dst;
2688
2689    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2690       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2691          union tgsi_exec_channel src[3];
2692
2693          fetch_source(mach, &src[0], &inst->Src[0], chan, src_datatype);
2694          fetch_source(mach, &src[1], &inst->Src[1], chan, src_datatype);
2695          fetch_source(mach, &src[2], &inst->Src[2], chan, src_datatype);
2696          op(&dst.xyzw[chan], &src[0], &src[1], &src[2]);
2697       }
2698    }
2699    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2700       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2701          store_dest(mach, &dst.xyzw[chan], &inst->Dst[0], inst, chan, dst_datatype);
2702       }
2703    }
2704 }
2705
2706 static void
2707 exec_dp3(struct tgsi_exec_machine *mach,
2708          const struct tgsi_full_instruction *inst)
2709 {
2710    unsigned int chan;
2711    union tgsi_exec_channel arg[3];
2712
2713    fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2714    fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2715    micro_mul(&arg[2], &arg[0], &arg[1]);
2716
2717    for (chan = TGSI_CHAN_Y; chan <= TGSI_CHAN_Z; chan++) {
2718       fetch_source(mach, &arg[0], &inst->Src[0], chan, TGSI_EXEC_DATA_FLOAT);
2719       fetch_source(mach, &arg[1], &inst->Src[1], chan, TGSI_EXEC_DATA_FLOAT);
2720       micro_mad(&arg[2], &arg[0], &arg[1], &arg[2]);
2721    }
2722
2723    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2724       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2725          store_dest(mach, &arg[2], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
2726       }
2727    }
2728 }
2729
2730 static void
2731 exec_dp4(struct tgsi_exec_machine *mach,
2732          const struct tgsi_full_instruction *inst)
2733 {
2734    unsigned int chan;
2735    union tgsi_exec_channel arg[3];
2736
2737    fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2738    fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2739    micro_mul(&arg[2], &arg[0], &arg[1]);
2740
2741    for (chan = TGSI_CHAN_Y; chan <= TGSI_CHAN_W; chan++) {
2742       fetch_source(mach, &arg[0], &inst->Src[0], chan, TGSI_EXEC_DATA_FLOAT);
2743       fetch_source(mach, &arg[1], &inst->Src[1], chan, TGSI_EXEC_DATA_FLOAT);
2744       micro_mad(&arg[2], &arg[0], &arg[1], &arg[2]);
2745    }
2746
2747    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2748       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2749          store_dest(mach, &arg[2], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
2750       }
2751    }
2752 }
2753
2754 static void
2755 exec_dp2a(struct tgsi_exec_machine *mach,
2756           const struct tgsi_full_instruction *inst)
2757 {
2758    unsigned int chan;
2759    union tgsi_exec_channel arg[3];
2760
2761    fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2762    fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2763    micro_mul(&arg[2], &arg[0], &arg[1]);
2764
2765    fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
2766    fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
2767    micro_mad(&arg[0], &arg[0], &arg[1], &arg[2]);
2768
2769    fetch_source(mach, &arg[1], &inst->Src[2], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2770    micro_add(&arg[0], &arg[0], &arg[1]);
2771
2772    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2773       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2774          store_dest(mach, &arg[0], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
2775       }
2776    }
2777 }
2778
2779 static void
2780 exec_dph(struct tgsi_exec_machine *mach,
2781          const struct tgsi_full_instruction *inst)
2782 {
2783    unsigned int chan;
2784    union tgsi_exec_channel arg[3];
2785
2786    fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2787    fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2788    micro_mul(&arg[2], &arg[0], &arg[1]);
2789
2790    fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
2791    fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
2792    micro_mad(&arg[2], &arg[0], &arg[1], &arg[2]);
2793
2794    fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
2795    fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
2796    micro_mad(&arg[0], &arg[0], &arg[1], &arg[2]);
2797
2798    fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
2799    micro_add(&arg[0], &arg[0], &arg[1]);
2800
2801    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2802       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2803          store_dest(mach, &arg[0], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
2804       }
2805    }
2806 }
2807
2808 static void
2809 exec_dp2(struct tgsi_exec_machine *mach,
2810          const struct tgsi_full_instruction *inst)
2811 {
2812    unsigned int chan;
2813    union tgsi_exec_channel arg[3];
2814
2815    fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2816    fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2817    micro_mul(&arg[2], &arg[0], &arg[1]);
2818
2819    fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
2820    fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
2821    micro_mad(&arg[2], &arg[0], &arg[1], &arg[2]);
2822
2823    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
2824       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2825          store_dest(mach, &arg[2], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
2826       }
2827    }
2828 }
2829
2830 static void
2831 exec_nrm4(struct tgsi_exec_machine *mach,
2832           const struct tgsi_full_instruction *inst)
2833 {
2834    unsigned int chan;
2835    union tgsi_exec_channel arg[4];
2836    union tgsi_exec_channel scale;
2837
2838    fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2839    micro_mul(&scale, &arg[0], &arg[0]);
2840
2841    for (chan = TGSI_CHAN_Y; chan <= TGSI_CHAN_W; chan++) {
2842       union tgsi_exec_channel product;
2843
2844       fetch_source(mach, &arg[chan], &inst->Src[0], chan, TGSI_EXEC_DATA_FLOAT);
2845       micro_mul(&product, &arg[chan], &arg[chan]);
2846       micro_add(&scale, &scale, &product);
2847    }
2848
2849    micro_rsq(&scale, &scale);
2850
2851    for (chan = TGSI_CHAN_X; chan <= TGSI_CHAN_W; chan++) {
2852       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2853          micro_mul(&arg[chan], &arg[chan], &scale);
2854          store_dest(mach, &arg[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
2855       }
2856    }
2857 }
2858
2859 static void
2860 exec_nrm3(struct tgsi_exec_machine *mach,
2861           const struct tgsi_full_instruction *inst)
2862 {
2863    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XYZ) {
2864       unsigned int chan;
2865       union tgsi_exec_channel arg[3];
2866       union tgsi_exec_channel scale;
2867
2868       fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2869       micro_mul(&scale, &arg[0], &arg[0]);
2870
2871       for (chan = TGSI_CHAN_Y; chan <= TGSI_CHAN_Z; chan++) {
2872          union tgsi_exec_channel product;
2873
2874          fetch_source(mach, &arg[chan], &inst->Src[0], chan, TGSI_EXEC_DATA_FLOAT);
2875          micro_mul(&product, &arg[chan], &arg[chan]);
2876          micro_add(&scale, &scale, &product);
2877       }
2878
2879       micro_rsq(&scale, &scale);
2880
2881       for (chan = TGSI_CHAN_X; chan <= TGSI_CHAN_Z; chan++) {
2882          if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
2883             micro_mul(&arg[chan], &arg[chan], &scale);
2884             store_dest(mach, &arg[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
2885          }
2886       }
2887    }
2888
2889    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
2890       store_dest(mach, &OneVec, &inst->Dst[0], inst, TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
2891    }
2892 }
2893
2894 static void
2895 exec_scs(struct tgsi_exec_machine *mach,
2896          const struct tgsi_full_instruction *inst)
2897 {
2898    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XY) {
2899       union tgsi_exec_channel arg;
2900       union tgsi_exec_channel result;
2901
2902       fetch_source(mach, &arg, &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2903
2904       if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
2905          micro_cos(&result, &arg);
2906          store_dest(mach, &result, &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2907       }
2908       if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
2909          micro_sin(&result, &arg);
2910          store_dest(mach, &result, &inst->Dst[0], inst, TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
2911       }
2912    }
2913    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
2914       store_dest(mach, &ZeroVec, &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
2915    }
2916    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
2917       store_dest(mach, &OneVec, &inst->Dst[0], inst, TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
2918    }
2919 }
2920
2921 static void
2922 exec_x2d(struct tgsi_exec_machine *mach,
2923          const struct tgsi_full_instruction *inst)
2924 {
2925    union tgsi_exec_channel r[4];
2926    union tgsi_exec_channel d[2];
2927
2928    fetch_source(mach, &r[0], &inst->Src[1], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2929    fetch_source(mach, &r[1], &inst->Src[1], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
2930    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XZ) {
2931       fetch_source(mach, &r[2], &inst->Src[2], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2932       micro_mul(&r[2], &r[2], &r[0]);
2933       fetch_source(mach, &r[3], &inst->Src[2], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
2934       micro_mul(&r[3], &r[3], &r[1]);
2935       micro_add(&r[2], &r[2], &r[3]);
2936       fetch_source(mach, &r[3], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2937       micro_add(&d[0], &r[2], &r[3]);
2938    }
2939    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_YW) {
2940       fetch_source(mach, &r[2], &inst->Src[2], TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
2941       micro_mul(&r[2], &r[2], &r[0]);
2942       fetch_source(mach, &r[3], &inst->Src[2], TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
2943       micro_mul(&r[3], &r[3], &r[1]);
2944       micro_add(&r[2], &r[2], &r[3]);
2945       fetch_source(mach, &r[3], &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
2946       micro_add(&d[1], &r[2], &r[3]);
2947    }
2948    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
2949       store_dest(mach, &d[0], &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2950    }
2951    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
2952       store_dest(mach, &d[1], &inst->Dst[0], inst, TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
2953    }
2954    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
2955       store_dest(mach, &d[0], &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
2956    }
2957    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
2958       store_dest(mach, &d[1], &inst->Dst[0], inst, TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
2959    }
2960 }
2961
2962 static void
2963 exec_rfl(struct tgsi_exec_machine *mach,
2964          const struct tgsi_full_instruction *inst)
2965 {
2966    union tgsi_exec_channel r[9];
2967
2968    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XYZ) {
2969       /* r0 = dp3(src0, src0) */
2970       fetch_source(mach, &r[2], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2971       micro_mul(&r[0], &r[2], &r[2]);
2972       fetch_source(mach, &r[4], &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
2973       micro_mul(&r[8], &r[4], &r[4]);
2974       micro_add(&r[0], &r[0], &r[8]);
2975       fetch_source(mach, &r[6], &inst->Src[0], TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
2976       micro_mul(&r[8], &r[6], &r[6]);
2977       micro_add(&r[0], &r[0], &r[8]);
2978
2979       /* r1 = dp3(src0, src1) */
2980       fetch_source(mach, &r[3], &inst->Src[1], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2981       micro_mul(&r[1], &r[2], &r[3]);
2982       fetch_source(mach, &r[5], &inst->Src[1], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
2983       micro_mul(&r[8], &r[4], &r[5]);
2984       micro_add(&r[1], &r[1], &r[8]);
2985       fetch_source(mach, &r[7], &inst->Src[1], TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
2986       micro_mul(&r[8], &r[6], &r[7]);
2987       micro_add(&r[1], &r[1], &r[8]);
2988
2989       /* r1 = 2 * r1 / r0 */
2990       micro_add(&r[1], &r[1], &r[1]);
2991       micro_div(&r[1], &r[1], &r[0]);
2992
2993       if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
2994          micro_mul(&r[2], &r[2], &r[1]);
2995          micro_sub(&r[2], &r[2], &r[3]);
2996          store_dest(mach, &r[2], &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
2997       }
2998       if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
2999          micro_mul(&r[4], &r[4], &r[1]);
3000          micro_sub(&r[4], &r[4], &r[5]);
3001          store_dest(mach, &r[4], &inst->Dst[0], inst, TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
3002       }
3003       if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
3004          micro_mul(&r[6], &r[6], &r[1]);
3005          micro_sub(&r[6], &r[6], &r[7]);
3006          store_dest(mach, &r[6], &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
3007       }
3008    }
3009    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
3010       store_dest(mach, &OneVec, &inst->Dst[0], inst, TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
3011    }
3012 }
3013
3014 static void
3015 exec_xpd(struct tgsi_exec_machine *mach,
3016          const struct tgsi_full_instruction *inst)
3017 {
3018    union tgsi_exec_channel r[6];
3019    union tgsi_exec_channel d[3];
3020
3021    fetch_source(mach, &r[0], &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
3022    fetch_source(mach, &r[1], &inst->Src[1], TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
3023
3024    micro_mul(&r[2], &r[0], &r[1]);
3025
3026    fetch_source(mach, &r[3], &inst->Src[0], TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
3027    fetch_source(mach, &r[4], &inst->Src[1], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
3028
3029    micro_mul(&r[5], &r[3], &r[4] );
3030    micro_sub(&d[TGSI_CHAN_X], &r[2], &r[5]);
3031
3032    fetch_source(mach, &r[2], &inst->Src[1], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
3033
3034    micro_mul(&r[3], &r[3], &r[2]);
3035
3036    fetch_source(mach, &r[5], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
3037
3038    micro_mul(&r[1], &r[1], &r[5]);
3039    micro_sub(&d[TGSI_CHAN_Y], &r[3], &r[1]);
3040
3041    micro_mul(&r[5], &r[5], &r[4]);
3042    micro_mul(&r[0], &r[0], &r[2]);
3043    micro_sub(&d[TGSI_CHAN_Z], &r[5], &r[0]);
3044
3045    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
3046       store_dest(mach, &d[TGSI_CHAN_X], &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
3047    }
3048    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
3049       store_dest(mach, &d[TGSI_CHAN_Y], &inst->Dst[0], inst, TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
3050    }
3051    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
3052       store_dest(mach, &d[TGSI_CHAN_Z], &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
3053    }
3054    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
3055       store_dest(mach, &OneVec, &inst->Dst[0], inst, TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
3056    }
3057 }
3058
3059 static void
3060 exec_dst(struct tgsi_exec_machine *mach,
3061          const struct tgsi_full_instruction *inst)
3062 {
3063    union tgsi_exec_channel r[2];
3064    union tgsi_exec_channel d[4];
3065
3066    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
3067       fetch_source(mach, &r[0], &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
3068       fetch_source(mach, &r[1], &inst->Src[1], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
3069       micro_mul(&d[TGSI_CHAN_Y], &r[0], &r[1]);
3070    }
3071    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
3072       fetch_source(mach, &d[TGSI_CHAN_Z], &inst->Src[0], TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
3073    }
3074    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
3075       fetch_source(mach, &d[TGSI_CHAN_W], &inst->Src[1], TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
3076    }
3077
3078    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
3079       store_dest(mach, &OneVec, &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
3080    }
3081    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
3082       store_dest(mach, &d[TGSI_CHAN_Y], &inst->Dst[0], inst, TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
3083    }
3084    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
3085       store_dest(mach, &d[TGSI_CHAN_Z], &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
3086    }
3087    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
3088       store_dest(mach, &d[TGSI_CHAN_W], &inst->Dst[0], inst, TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
3089    }
3090 }
3091
3092 static void
3093 exec_log(struct tgsi_exec_machine *mach,
3094          const struct tgsi_full_instruction *inst)
3095 {
3096    union tgsi_exec_channel r[3];
3097
3098    fetch_source(mach, &r[0], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
3099    micro_abs(&r[2], &r[0]);  /* r2 = abs(r0) */
3100    micro_lg2(&r[1], &r[2]);  /* r1 = lg2(r2) */
3101    micro_flr(&r[0], &r[1]);  /* r0 = floor(r1) */
3102    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
3103       store_dest(mach, &r[0], &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
3104    }
3105    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
3106       micro_exp2(&r[0], &r[0]);       /* r0 = 2 ^ r0 */
3107       micro_div(&r[0], &r[2], &r[0]); /* r0 = r2 / r0 */
3108       store_dest(mach, &r[0], &inst->Dst[0], inst, TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
3109    }
3110    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
3111       store_dest(mach, &r[1], &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
3112    }
3113    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
3114       store_dest(mach, &OneVec, &inst->Dst[0], inst, TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
3115    }
3116 }
3117
3118 static void
3119 exec_exp(struct tgsi_exec_machine *mach,
3120          const struct tgsi_full_instruction *inst)
3121 {
3122    union tgsi_exec_channel r[3];
3123
3124    fetch_source(mach, &r[0], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
3125    micro_flr(&r[1], &r[0]);  /* r1 = floor(r0) */
3126    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
3127       micro_exp2(&r[2], &r[1]);       /* r2 = 2 ^ r1 */
3128       store_dest(mach, &r[2], &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
3129    }
3130    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
3131       micro_sub(&r[2], &r[0], &r[1]); /* r2 = r0 - r1 */
3132       store_dest(mach, &r[2], &inst->Dst[0], inst, TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
3133    }
3134    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
3135       micro_exp2(&r[2], &r[0]);       /* r2 = 2 ^ r0 */
3136       store_dest(mach, &r[2], &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
3137    }
3138    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
3139       store_dest(mach, &OneVec, &inst->Dst[0], inst, TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
3140    }
3141 }
3142
3143 static void
3144 exec_lit(struct tgsi_exec_machine *mach,
3145          const struct tgsi_full_instruction *inst)
3146 {
3147    union tgsi_exec_channel r[3];
3148    union tgsi_exec_channel d[3];
3149
3150    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_YZ) {
3151       fetch_source(mach, &r[0], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
3152       if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
3153          fetch_source(mach, &r[1], &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
3154          micro_max(&r[1], &r[1], &ZeroVec);
3155
3156          fetch_source(mach, &r[2], &inst->Src[0], TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
3157          micro_min(&r[2], &r[2], &P128Vec);
3158          micro_max(&r[2], &r[2], &M128Vec);
3159          micro_pow(&r[1], &r[1], &r[2]);
3160          micro_lt(&d[TGSI_CHAN_Z], &ZeroVec, &r[0], &r[1], &ZeroVec);
3161          store_dest(mach, &d[TGSI_CHAN_Z], &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
3162       }
3163       if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
3164          micro_max(&d[TGSI_CHAN_Y], &r[0], &ZeroVec);
3165          store_dest(mach, &d[TGSI_CHAN_Y], &inst->Dst[0], inst, TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
3166       }
3167    }
3168    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
3169       store_dest(mach, &OneVec, &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
3170    }
3171
3172    if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
3173       store_dest(mach, &OneVec, &inst->Dst[0], inst, TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
3174    }
3175 }
3176
3177 static void
3178 exec_break(struct tgsi_exec_machine *mach)
3179 {
3180    if (mach->BreakType == TGSI_EXEC_BREAK_INSIDE_LOOP) {
3181       /* turn off loop channels for each enabled exec channel */
3182       mach->LoopMask &= ~mach->ExecMask;
3183       /* Todo: if mach->LoopMask == 0, jump to end of loop */
3184       UPDATE_EXEC_MASK(mach);
3185    } else {
3186       assert(mach->BreakType == TGSI_EXEC_BREAK_INSIDE_SWITCH);
3187
3188       mach->Switch.mask = 0x0;
3189
3190       UPDATE_EXEC_MASK(mach);
3191    }
3192 }
3193
3194 static void
3195 exec_switch(struct tgsi_exec_machine *mach,
3196             const struct tgsi_full_instruction *inst)
3197 {
3198    assert(mach->SwitchStackTop < TGSI_EXEC_MAX_SWITCH_NESTING);
3199    assert(mach->BreakStackTop < TGSI_EXEC_MAX_BREAK_STACK);
3200
3201    mach->SwitchStack[mach->SwitchStackTop++] = mach->Switch;
3202    fetch_source(mach, &mach->Switch.selector, &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_UINT);
3203    mach->Switch.mask = 0x0;
3204    mach->Switch.defaultMask = 0x0;
3205
3206    mach->BreakStack[mach->BreakStackTop++] = mach->BreakType;
3207    mach->BreakType = TGSI_EXEC_BREAK_INSIDE_SWITCH;
3208
3209    UPDATE_EXEC_MASK(mach);
3210 }
3211
3212 static void
3213 exec_case(struct tgsi_exec_machine *mach,
3214           const struct tgsi_full_instruction *inst)
3215 {
3216    uint prevMask = mach->SwitchStack[mach->SwitchStackTop - 1].mask;
3217    union tgsi_exec_channel src;
3218    uint mask = 0;
3219
3220    fetch_source(mach, &src, &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_UINT);
3221
3222    if (mach->Switch.selector.u[0] == src.u[0]) {
3223       mask |= 0x1;
3224    }
3225    if (mach->Switch.selector.u[1] == src.u[1]) {
3226       mask |= 0x2;
3227    }
3228    if (mach->Switch.selector.u[2] == src.u[2]) {
3229       mask |= 0x4;
3230    }
3231    if (mach->Switch.selector.u[3] == src.u[3]) {
3232       mask |= 0x8;
3233    }
3234
3235    mach->Switch.defaultMask |= mask;
3236
3237    mach->Switch.mask |= mask & prevMask;
3238
3239    UPDATE_EXEC_MASK(mach);
3240 }
3241
3242 static void
3243 exec_default(struct tgsi_exec_machine *mach)
3244 {
3245    uint prevMask = mach->SwitchStack[mach->SwitchStackTop - 1].mask;
3246
3247    mach->Switch.mask |= ~mach->Switch.defaultMask & prevMask;
3248
3249    UPDATE_EXEC_MASK(mach);
3250 }
3251
3252 static void
3253 exec_endswitch(struct tgsi_exec_machine *mach)
3254 {
3255    mach->Switch = mach->SwitchStack[--mach->SwitchStackTop];
3256    mach->BreakType = mach->BreakStack[--mach->BreakStackTop];
3257
3258    UPDATE_EXEC_MASK(mach);
3259 }
3260
3261 static void
3262 micro_i2f(union tgsi_exec_channel *dst,
3263           const union tgsi_exec_channel *src)
3264 {
3265    dst->f[0] = (float)src->i[0];
3266    dst->f[1] = (float)src->i[1];
3267    dst->f[2] = (float)src->i[2];
3268    dst->f[3] = (float)src->i[3];
3269 }
3270
3271 static void
3272 micro_not(union tgsi_exec_channel *dst,
3273           const union tgsi_exec_channel *src)
3274 {
3275    dst->u[0] = ~src->u[0];
3276    dst->u[1] = ~src->u[1];
3277    dst->u[2] = ~src->u[2];
3278    dst->u[3] = ~src->u[3];
3279 }
3280
3281 static void
3282 micro_shl(union tgsi_exec_channel *dst,
3283           const union tgsi_exec_channel *src0,
3284           const union tgsi_exec_channel *src1)
3285 {
3286    dst->u[0] = src0->u[0] << src1->u[0];
3287    dst->u[1] = src0->u[1] << src1->u[1];
3288    dst->u[2] = src0->u[2] << src1->u[2];
3289    dst->u[3] = src0->u[3] << src1->u[3];
3290 }
3291
3292 static void
3293 micro_and(union tgsi_exec_channel *dst,
3294           const union tgsi_exec_channel *src0,
3295           const union tgsi_exec_channel *src1)
3296 {
3297    dst->u[0] = src0->u[0] & src1->u[0];
3298    dst->u[1] = src0->u[1] & src1->u[1];
3299    dst->u[2] = src0->u[2] & src1->u[2];
3300    dst->u[3] = src0->u[3] & src1->u[3];
3301 }
3302
3303 static void
3304 micro_or(union tgsi_exec_channel *dst,
3305          const union tgsi_exec_channel *src0,
3306          const union tgsi_exec_channel *src1)
3307 {
3308    dst->u[0] = src0->u[0] | src1->u[0];
3309    dst->u[1] = src0->u[1] | src1->u[1];
3310    dst->u[2] = src0->u[2] | src1->u[2];
3311    dst->u[3] = src0->u[3] | src1->u[3];
3312 }
3313
3314 static void
3315 micro_xor(union tgsi_exec_channel *dst,
3316           const union tgsi_exec_channel *src0,
3317           const union tgsi_exec_channel *src1)
3318 {
3319    dst->u[0] = src0->u[0] ^ src1->u[0];
3320    dst->u[1] = src0->u[1] ^ src1->u[1];
3321    dst->u[2] = src0->u[2] ^ src1->u[2];
3322    dst->u[3] = src0->u[3] ^ src1->u[3];
3323 }
3324
3325 static void
3326 micro_mod(union tgsi_exec_channel *dst,
3327           const union tgsi_exec_channel *src0,
3328           const union tgsi_exec_channel *src1)
3329 {
3330    dst->i[0] = src0->i[0] % src1->i[0];
3331    dst->i[1] = src0->i[1] % src1->i[1];
3332    dst->i[2] = src0->i[2] % src1->i[2];
3333    dst->i[3] = src0->i[3] % src1->i[3];
3334 }
3335
3336 static void
3337 micro_f2i(union tgsi_exec_channel *dst,
3338           const union tgsi_exec_channel *src)
3339 {
3340    dst->i[0] = (int)src->f[0];
3341    dst->i[1] = (int)src->f[1];
3342    dst->i[2] = (int)src->f[2];
3343    dst->i[3] = (int)src->f[3];
3344 }
3345
3346 static void
3347 micro_idiv(union tgsi_exec_channel *dst,
3348            const union tgsi_exec_channel *src0,
3349            const union tgsi_exec_channel *src1)
3350 {
3351    dst->i[0] = src0->i[0] / src1->i[0];
3352    dst->i[1] = src0->i[1] / src1->i[1];
3353    dst->i[2] = src0->i[2] / src1->i[2];
3354    dst->i[3] = src0->i[3] / src1->i[3];
3355 }
3356
3357 static void
3358 micro_imax(union tgsi_exec_channel *dst,
3359            const union tgsi_exec_channel *src0,
3360            const union tgsi_exec_channel *src1)
3361 {
3362    dst->i[0] = src0->i[0] > src1->i[0] ? src0->i[0] : src1->i[0];
3363    dst->i[1] = src0->i[1] > src1->i[1] ? src0->i[1] : src1->i[1];
3364    dst->i[2] = src0->i[2] > src1->i[2] ? src0->i[2] : src1->i[2];
3365    dst->i[3] = src0->i[3] > src1->i[3] ? src0->i[3] : src1->i[3];
3366 }
3367
3368 static void
3369 micro_imin(union tgsi_exec_channel *dst,
3370            const union tgsi_exec_channel *src0,
3371            const union tgsi_exec_channel *src1)
3372 {
3373    dst->i[0] = src0->i[0] < src1->i[0] ? src0->i[0] : src1->i[0];
3374    dst->i[1] = src0->i[1] < src1->i[1] ? src0->i[1] : src1->i[1];
3375    dst->i[2] = src0->i[2] < src1->i[2] ? src0->i[2] : src1->i[2];
3376    dst->i[3] = src0->i[3] < src1->i[3] ? src0->i[3] : src1->i[3];
3377 }
3378
3379 static void
3380 micro_isge(union tgsi_exec_channel *dst,
3381            const union tgsi_exec_channel *src0,
3382            const union tgsi_exec_channel *src1)
3383 {
3384    dst->i[0] = src0->i[0] >= src1->i[0] ? -1 : 0;
3385    dst->i[1] = src0->i[1] >= src1->i[1] ? -1 : 0;
3386    dst->i[2] = src0->i[2] >= src1->i[2] ? -1 : 0;
3387    dst->i[3] = src0->i[3] >= src1->i[3] ? -1 : 0;
3388 }
3389
3390 static void
3391 micro_ishr(union tgsi_exec_channel *dst,
3392            const union tgsi_exec_channel *src0,
3393            const union tgsi_exec_channel *src1)
3394 {
3395    dst->i[0] = src0->i[0] >> src1->i[0];
3396    dst->i[1] = src0->i[1] >> src1->i[1];
3397    dst->i[2] = src0->i[2] >> src1->i[2];
3398    dst->i[3] = src0->i[3] >> src1->i[3];
3399 }
3400
3401 static void
3402 micro_islt(union tgsi_exec_channel *dst,
3403            const union tgsi_exec_channel *src0,
3404            const union tgsi_exec_channel *src1)
3405 {
3406    dst->i[0] = src0->i[0] < src1->i[0] ? -1 : 0;
3407    dst->i[1] = src0->i[1] < src1->i[1] ? -1 : 0;
3408    dst->i[2] = src0->i[2] < src1->i[2] ? -1 : 0;
3409    dst->i[3] = src0->i[3] < src1->i[3] ? -1 : 0;
3410 }
3411
3412 static void
3413 micro_f2u(union tgsi_exec_channel *dst,
3414           const union tgsi_exec_channel *src)
3415 {
3416    dst->u[0] = (uint)src->f[0];
3417    dst->u[1] = (uint)src->f[1];
3418    dst->u[2] = (uint)src->f[2];
3419    dst->u[3] = (uint)src->f[3];
3420 }
3421
3422 static void
3423 micro_u2f(union tgsi_exec_channel *dst,
3424           const union tgsi_exec_channel *src)
3425 {
3426    dst->f[0] = (float)src->u[0];
3427    dst->f[1] = (float)src->u[1];
3428    dst->f[2] = (float)src->u[2];
3429    dst->f[3] = (float)src->u[3];
3430 }
3431
3432 static void
3433 micro_uadd(union tgsi_exec_channel *dst,
3434            const union tgsi_exec_channel *src0,
3435            const union tgsi_exec_channel *src1)
3436 {
3437    dst->u[0] = src0->u[0] + src1->u[0];
3438    dst->u[1] = src0->u[1] + src1->u[1];
3439    dst->u[2] = src0->u[2] + src1->u[2];
3440    dst->u[3] = src0->u[3] + src1->u[3];
3441 }
3442
3443 static void
3444 micro_udiv(union tgsi_exec_channel *dst,
3445            const union tgsi_exec_channel *src0,
3446            const union tgsi_exec_channel *src1)
3447 {
3448    dst->u[0] = src1->u[0] ? src0->u[0] / src1->u[0] : ~0u;
3449    dst->u[1] = src1->u[1] ? src0->u[1] / src1->u[1] : ~0u;
3450    dst->u[2] = src1->u[2] ? src0->u[2] / src1->u[2] : ~0u;
3451    dst->u[3] = src1->u[3] ? src0->u[3] / src1->u[3] : ~0u;
3452 }
3453
3454 static void
3455 micro_umad(union tgsi_exec_channel *dst,
3456            const union tgsi_exec_channel *src0,
3457            const union tgsi_exec_channel *src1,
3458            const union tgsi_exec_channel *src2)
3459 {
3460    dst->u[0] = src0->u[0] * src1->u[0] + src2->u[0];
3461    dst->u[1] = src0->u[1] * src1->u[1] + src2->u[1];
3462    dst->u[2] = src0->u[2] * src1->u[2] + src2->u[2];
3463    dst->u[3] = src0->u[3] * src1->u[3] + src2->u[3];
3464 }
3465
3466 static void
3467 micro_umax(union tgsi_exec_channel *dst,
3468            const union tgsi_exec_channel *src0,
3469            const union tgsi_exec_channel *src1)
3470 {
3471    dst->u[0] = src0->u[0] > src1->u[0] ? src0->u[0] : src1->u[0];
3472    dst->u[1] = src0->u[1] > src1->u[1] ? src0->u[1] : src1->u[1];
3473    dst->u[2] = src0->u[2] > src1->u[2] ? src0->u[2] : src1->u[2];
3474    dst->u[3] = src0->u[3] > src1->u[3] ? src0->u[3] : src1->u[3];
3475 }
3476
3477 static void
3478 micro_umin(union tgsi_exec_channel *dst,
3479            const union tgsi_exec_channel *src0,
3480            const union tgsi_exec_channel *src1)
3481 {
3482    dst->u[0] = src0->u[0] < src1->u[0] ? src0->u[0] : src1->u[0];
3483    dst->u[1] = src0->u[1] < src1->u[1] ? src0->u[1] : src1->u[1];
3484    dst->u[2] = src0->u[2] < src1->u[2] ? src0->u[2] : src1->u[2];
3485    dst->u[3] = src0->u[3] < src1->u[3] ? src0->u[3] : src1->u[3];
3486 }
3487
3488 static void
3489 micro_umod(union tgsi_exec_channel *dst,
3490            const union tgsi_exec_channel *src0,
3491            const union tgsi_exec_channel *src1)
3492 {
3493    dst->u[0] = src1->u[0] ? src0->u[0] % src1->u[0] : ~0u;
3494    dst->u[1] = src1->u[1] ? src0->u[1] % src1->u[1] : ~0u;
3495    dst->u[2] = src1->u[2] ? src0->u[2] % src1->u[2] : ~0u;
3496    dst->u[3] = src1->u[3] ? src0->u[3] % src1->u[3] : ~0u;
3497 }
3498
3499 static void
3500 micro_umul(union tgsi_exec_channel *dst,
3501            const union tgsi_exec_channel *src0,
3502            const union tgsi_exec_channel *src1)
3503 {
3504    dst->u[0] = src0->u[0] * src1->u[0];
3505    dst->u[1] = src0->u[1] * src1->u[1];
3506    dst->u[2] = src0->u[2] * src1->u[2];
3507    dst->u[3] = src0->u[3] * src1->u[3];
3508 }
3509
3510 static void
3511 micro_useq(union tgsi_exec_channel *dst,
3512            const union tgsi_exec_channel *src0,
3513            const union tgsi_exec_channel *src1)
3514 {
3515    dst->u[0] = src0->u[0] == src1->u[0] ? ~0 : 0;
3516    dst->u[1] = src0->u[1] == src1->u[1] ? ~0 : 0;
3517    dst->u[2] = src0->u[2] == src1->u[2] ? ~0 : 0;
3518    dst->u[3] = src0->u[3] == src1->u[3] ? ~0 : 0;
3519 }
3520
3521 static void
3522 micro_usge(union tgsi_exec_channel *dst,
3523            const union tgsi_exec_channel *src0,
3524            const union tgsi_exec_channel *src1)
3525 {
3526    dst->u[0] = src0->u[0] >= src1->u[0] ? ~0 : 0;
3527    dst->u[1] = src0->u[1] >= src1->u[1] ? ~0 : 0;
3528    dst->u[2] = src0->u[2] >= src1->u[2] ? ~0 : 0;
3529    dst->u[3] = src0->u[3] >= src1->u[3] ? ~0 : 0;
3530 }
3531
3532 static void
3533 micro_ushr(union tgsi_exec_channel *dst,
3534            const union tgsi_exec_channel *src0,
3535            const union tgsi_exec_channel *src1)
3536 {
3537    dst->u[0] = src0->u[0] >> src1->u[0];
3538    dst->u[1] = src0->u[1] >> src1->u[1];
3539    dst->u[2] = src0->u[2] >> src1->u[2];
3540    dst->u[3] = src0->u[3] >> src1->u[3];
3541 }
3542
3543 static void
3544 micro_uslt(union tgsi_exec_channel *dst,
3545            const union tgsi_exec_channel *src0,
3546            const union tgsi_exec_channel *src1)
3547 {
3548    dst->u[0] = src0->u[0] < src1->u[0] ? ~0 : 0;
3549    dst->u[1] = src0->u[1] < src1->u[1] ? ~0 : 0;
3550    dst->u[2] = src0->u[2] < src1->u[2] ? ~0 : 0;
3551    dst->u[3] = src0->u[3] < src1->u[3] ? ~0 : 0;
3552 }
3553
3554 static void
3555 micro_usne(union tgsi_exec_channel *dst,
3556            const union tgsi_exec_channel *src0,
3557            const union tgsi_exec_channel *src1)
3558 {
3559    dst->u[0] = src0->u[0] != src1->u[0] ? ~0 : 0;
3560    dst->u[1] = src0->u[1] != src1->u[1] ? ~0 : 0;
3561    dst->u[2] = src0->u[2] != src1->u[2] ? ~0 : 0;
3562    dst->u[3] = src0->u[3] != src1->u[3] ? ~0 : 0;
3563 }
3564
3565 static void
3566 micro_uarl(union tgsi_exec_channel *dst,
3567            const union tgsi_exec_channel *src)
3568 {
3569    dst->i[0] = src->u[0];
3570    dst->i[1] = src->u[1];
3571    dst->i[2] = src->u[2];
3572    dst->i[3] = src->u[3];
3573 }
3574
3575 static void
3576 micro_ucmp(union tgsi_exec_channel *dst,
3577            const union tgsi_exec_channel *src0,
3578            const union tgsi_exec_channel *src1,
3579            const union tgsi_exec_channel *src2)
3580 {
3581    dst->u[0] = src0->u[0] ? src1->u[0] : src2->u[0];
3582    dst->u[1] = src0->u[1] ? src1->u[1] : src2->u[1];
3583    dst->u[2] = src0->u[2] ? src1->u[2] : src2->u[2];
3584    dst->u[3] = src0->u[3] ? src1->u[3] : src2->u[3];
3585 }
3586
3587 static void
3588 exec_instruction(
3589    struct tgsi_exec_machine *mach,
3590    const struct tgsi_full_instruction *inst,
3591    int *pc )
3592 {
3593    union tgsi_exec_channel r[10];
3594
3595    (*pc)++;
3596
3597    switch (inst->Instruction.Opcode) {
3598    case TGSI_OPCODE_ARL:
3599       exec_vector_unary(mach, inst, micro_arl, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_FLOAT);
3600       break;
3601
3602    case TGSI_OPCODE_MOV:
3603       exec_vector_unary(mach, inst, micro_mov, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_FLOAT);
3604       break;
3605
3606    case TGSI_OPCODE_LIT:
3607       exec_lit(mach, inst);
3608       break;
3609
3610    case TGSI_OPCODE_RCP:
3611       exec_scalar_unary(mach, inst, micro_rcp, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3612       break;
3613
3614    case TGSI_OPCODE_RSQ:
3615       exec_scalar_unary(mach, inst, micro_rsq, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3616       break;
3617
3618    case TGSI_OPCODE_EXP:
3619       exec_exp(mach, inst);
3620       break;
3621
3622    case TGSI_OPCODE_LOG:
3623       exec_log(mach, inst);
3624       break;
3625
3626    case TGSI_OPCODE_MUL:
3627       exec_vector_binary(mach, inst, micro_mul, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3628       break;
3629
3630    case TGSI_OPCODE_ADD:
3631       exec_vector_binary(mach, inst, micro_add, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3632       break;
3633
3634    case TGSI_OPCODE_DP3:
3635       exec_dp3(mach, inst);
3636       break;
3637
3638    case TGSI_OPCODE_DP4:
3639       exec_dp4(mach, inst);
3640       break;
3641
3642    case TGSI_OPCODE_DST:
3643       exec_dst(mach, inst);
3644       break;
3645
3646    case TGSI_OPCODE_MIN:
3647       exec_vector_binary(mach, inst, micro_min, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3648       break;
3649
3650    case TGSI_OPCODE_MAX:
3651       exec_vector_binary(mach, inst, micro_max, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3652       break;
3653
3654    case TGSI_OPCODE_SLT:
3655       exec_vector_binary(mach, inst, micro_slt, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3656       break;
3657
3658    case TGSI_OPCODE_SGE:
3659       exec_vector_binary(mach, inst, micro_sge, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3660       break;
3661
3662    case TGSI_OPCODE_MAD:
3663       exec_vector_trinary(mach, inst, micro_mad, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3664       break;
3665
3666    case TGSI_OPCODE_SUB:
3667       exec_vector_binary(mach, inst, micro_sub, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3668       break;
3669
3670    case TGSI_OPCODE_LRP:
3671       exec_vector_trinary(mach, inst, micro_lrp, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3672       break;
3673
3674    case TGSI_OPCODE_CND:
3675       exec_vector_trinary(mach, inst, micro_cnd, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3676       break;
3677
3678    case TGSI_OPCODE_SQRT:
3679       exec_vector_unary(mach, inst, micro_sqrt, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3680       break;
3681
3682    case TGSI_OPCODE_DP2A:
3683       exec_dp2a(mach, inst);
3684       break;
3685
3686    case TGSI_OPCODE_FRC:
3687       exec_vector_unary(mach, inst, micro_frc, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3688       break;
3689
3690    case TGSI_OPCODE_CLAMP:
3691       exec_vector_trinary(mach, inst, micro_clamp, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3692       break;
3693
3694    case TGSI_OPCODE_FLR:
3695       exec_vector_unary(mach, inst, micro_flr, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3696       break;
3697
3698    case TGSI_OPCODE_ROUND:
3699       exec_vector_unary(mach, inst, micro_rnd, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3700       break;
3701
3702    case TGSI_OPCODE_EX2:
3703       exec_scalar_unary(mach, inst, micro_exp2, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3704       break;
3705
3706    case TGSI_OPCODE_LG2:
3707       exec_scalar_unary(mach, inst, micro_lg2, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3708       break;
3709
3710    case TGSI_OPCODE_POW:
3711       exec_scalar_binary(mach, inst, micro_pow, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3712       break;
3713
3714    case TGSI_OPCODE_XPD:
3715       exec_xpd(mach, inst);
3716       break;
3717
3718    case TGSI_OPCODE_ABS:
3719       exec_vector_unary(mach, inst, micro_abs, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3720       break;
3721
3722    case TGSI_OPCODE_RCC:
3723       exec_scalar_unary(mach, inst, micro_rcc, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3724       break;
3725
3726    case TGSI_OPCODE_DPH:
3727       exec_dph(mach, inst);
3728       break;
3729
3730    case TGSI_OPCODE_COS:
3731       exec_scalar_unary(mach, inst, micro_cos, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3732       break;
3733
3734    case TGSI_OPCODE_DDX:
3735       exec_vector_unary(mach, inst, micro_ddx, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3736       break;
3737
3738    case TGSI_OPCODE_DDY:
3739       exec_vector_unary(mach, inst, micro_ddy, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3740       break;
3741
3742    case TGSI_OPCODE_KILP:
3743       exec_kilp (mach, inst);
3744       break;
3745
3746    case TGSI_OPCODE_KIL:
3747       exec_kil (mach, inst);
3748       break;
3749
3750    case TGSI_OPCODE_PK2H:
3751       assert (0);
3752       break;
3753
3754    case TGSI_OPCODE_PK2US:
3755       assert (0);
3756       break;
3757
3758    case TGSI_OPCODE_PK4B:
3759       assert (0);
3760       break;
3761
3762    case TGSI_OPCODE_PK4UB:
3763       assert (0);
3764       break;
3765
3766    case TGSI_OPCODE_RFL:
3767       exec_rfl(mach, inst);
3768       break;
3769
3770    case TGSI_OPCODE_SEQ:
3771       exec_vector_binary(mach, inst, micro_seq, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3772       break;
3773
3774    case TGSI_OPCODE_SFL:
3775       exec_vector(mach, inst, micro_sfl, TGSI_EXEC_DATA_FLOAT);
3776       break;
3777
3778    case TGSI_OPCODE_SGT:
3779       exec_vector_binary(mach, inst, micro_sgt, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3780       break;
3781
3782    case TGSI_OPCODE_SIN:
3783       exec_scalar_unary(mach, inst, micro_sin, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3784       break;
3785
3786    case TGSI_OPCODE_SLE:
3787       exec_vector_binary(mach, inst, micro_sle, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3788       break;
3789
3790    case TGSI_OPCODE_SNE:
3791       exec_vector_binary(mach, inst, micro_sne, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3792       break;
3793
3794    case TGSI_OPCODE_STR:
3795       exec_vector(mach, inst, micro_str, TGSI_EXEC_DATA_FLOAT);
3796       break;
3797
3798    case TGSI_OPCODE_TEX:
3799       /* simple texture lookup */
3800       /* src[0] = texcoord */
3801       /* src[1] = sampler unit */
3802       exec_tex(mach, inst, TEX_MODIFIER_NONE, 1);
3803       break;
3804
3805    case TGSI_OPCODE_TXB:
3806       /* Texture lookup with lod bias */
3807       /* src[0] = texcoord (src[0].w = LOD bias) */
3808       /* src[1] = sampler unit */
3809       exec_tex(mach, inst, TEX_MODIFIER_LOD_BIAS, 1);
3810       break;
3811
3812    case TGSI_OPCODE_TXD:
3813       /* Texture lookup with explict partial derivatives */
3814       /* src[0] = texcoord */
3815       /* src[1] = d[strq]/dx */
3816       /* src[2] = d[strq]/dy */
3817       /* src[3] = sampler unit */
3818       exec_txd(mach, inst);
3819       break;
3820
3821    case TGSI_OPCODE_TXL:
3822       /* Texture lookup with explit LOD */
3823       /* src[0] = texcoord (src[0].w = LOD) */
3824       /* src[1] = sampler unit */
3825       exec_tex(mach, inst, TEX_MODIFIER_EXPLICIT_LOD, 1);
3826       break;
3827
3828    case TGSI_OPCODE_TXP:
3829       /* Texture lookup with projection */
3830       /* src[0] = texcoord (src[0].w = projection) */
3831       /* src[1] = sampler unit */
3832       exec_tex(mach, inst, TEX_MODIFIER_PROJECTED, 1);
3833       break;
3834
3835    case TGSI_OPCODE_UP2H:
3836       assert (0);
3837       break;
3838
3839    case TGSI_OPCODE_UP2US:
3840       assert (0);
3841       break;
3842
3843    case TGSI_OPCODE_UP4B:
3844       assert (0);
3845       break;
3846
3847    case TGSI_OPCODE_UP4UB:
3848       assert (0);
3849       break;
3850
3851    case TGSI_OPCODE_X2D:
3852       exec_x2d(mach, inst);
3853       break;
3854
3855    case TGSI_OPCODE_ARA:
3856       assert (0);
3857       break;
3858
3859    case TGSI_OPCODE_ARR:
3860       exec_vector_unary(mach, inst, micro_arr, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_FLOAT);
3861       break;
3862
3863    case TGSI_OPCODE_BRA:
3864       assert (0);
3865       break;
3866
3867    case TGSI_OPCODE_CAL:
3868       /* skip the call if no execution channels are enabled */
3869       if (mach->ExecMask) {
3870          /* do the call */
3871
3872          /* First, record the depths of the execution stacks.
3873           * This is important for deeply nested/looped return statements.
3874           * We have to unwind the stacks by the correct amount.  For a
3875           * real code generator, we could determine the number of entries
3876           * to pop off each stack with simple static analysis and avoid
3877           * implementing this data structure at run time.
3878           */
3879          mach->CallStack[mach->CallStackTop].CondStackTop = mach->CondStackTop;
3880          mach->CallStack[mach->CallStackTop].LoopStackTop = mach->LoopStackTop;
3881          mach->CallStack[mach->CallStackTop].ContStackTop = mach->ContStackTop;
3882          mach->CallStack[mach->CallStackTop].SwitchStackTop = mach->SwitchStackTop;
3883          mach->CallStack[mach->CallStackTop].BreakStackTop = mach->BreakStackTop;
3884          /* note that PC was already incremented above */
3885          mach->CallStack[mach->CallStackTop].ReturnAddr = *pc;
3886
3887          mach->CallStackTop++;
3888
3889          /* Second, push the Cond, Loop, Cont, Func stacks */
3890          assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING);
3891          assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
3892          assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
3893          assert(mach->SwitchStackTop < TGSI_EXEC_MAX_SWITCH_NESTING);
3894          assert(mach->BreakStackTop < TGSI_EXEC_MAX_BREAK_STACK);
3895          assert(mach->FuncStackTop < TGSI_EXEC_MAX_CALL_NESTING);
3896
3897          mach->CondStack[mach->CondStackTop++] = mach->CondMask;
3898          mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
3899          mach->ContStack[mach->ContStackTop++] = mach->ContMask;
3900          mach->SwitchStack[mach->SwitchStackTop++] = mach->Switch;
3901          mach->BreakStack[mach->BreakStackTop++] = mach->BreakType;
3902          mach->FuncStack[mach->FuncStackTop++] = mach->FuncMask;
3903
3904          /* Finally, jump to the subroutine */
3905          *pc = inst->Label.Label;
3906       }
3907       break;
3908
3909    case TGSI_OPCODE_RET:
3910       mach->FuncMask &= ~mach->ExecMask;
3911       UPDATE_EXEC_MASK(mach);
3912
3913       if (mach->FuncMask == 0x0) {
3914          /* really return now (otherwise, keep executing */
3915
3916          if (mach->CallStackTop == 0) {
3917             /* returning from main() */
3918             mach->CondStackTop = 0;
3919             mach->LoopStackTop = 0;
3920             *pc = -1;
3921             return;
3922          }
3923
3924          assert(mach->CallStackTop > 0);
3925          mach->CallStackTop--;
3926
3927          mach->CondStackTop = mach->CallStack[mach->CallStackTop].CondStackTop;
3928          mach->CondMask = mach->CondStack[mach->CondStackTop];
3929
3930          mach->LoopStackTop = mach->CallStack[mach->CallStackTop].LoopStackTop;
3931          mach->LoopMask = mach->LoopStack[mach->LoopStackTop];
3932
3933          mach->ContStackTop = mach->CallStack[mach->CallStackTop].ContStackTop;
3934          mach->ContMask = mach->ContStack[mach->ContStackTop];
3935
3936          mach->SwitchStackTop = mach->CallStack[mach->CallStackTop].SwitchStackTop;
3937          mach->Switch = mach->SwitchStack[mach->SwitchStackTop];
3938
3939          mach->BreakStackTop = mach->CallStack[mach->CallStackTop].BreakStackTop;
3940          mach->BreakType = mach->BreakStack[mach->BreakStackTop];
3941
3942          assert(mach->FuncStackTop > 0);
3943          mach->FuncMask = mach->FuncStack[--mach->FuncStackTop];
3944
3945          *pc = mach->CallStack[mach->CallStackTop].ReturnAddr;
3946
3947          UPDATE_EXEC_MASK(mach);
3948       }
3949       break;
3950
3951    case TGSI_OPCODE_SSG:
3952       exec_vector_unary(mach, inst, micro_sgn, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3953       break;
3954
3955    case TGSI_OPCODE_CMP:
3956       exec_vector_trinary(mach, inst, micro_cmp, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3957       break;
3958
3959    case TGSI_OPCODE_SCS:
3960       exec_scs(mach, inst);
3961       break;
3962
3963    case TGSI_OPCODE_NRM:
3964       exec_nrm3(mach, inst);
3965       break;
3966
3967    case TGSI_OPCODE_NRM4:
3968       exec_nrm4(mach, inst);
3969       break;
3970
3971    case TGSI_OPCODE_DIV:
3972       exec_vector_binary(mach, inst, micro_div, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
3973       break;
3974
3975    case TGSI_OPCODE_DP2:
3976       exec_dp2(mach, inst);
3977       break;
3978
3979    case TGSI_OPCODE_IF:
3980       /* push CondMask */
3981       assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING);
3982       mach->CondStack[mach->CondStackTop++] = mach->CondMask;
3983       FETCH( &r[0], 0, TGSI_CHAN_X );
3984       /* update CondMask */
3985       if( ! r[0].f[0] ) {
3986          mach->CondMask &= ~0x1;
3987       }
3988       if( ! r[0].f[1] ) {
3989          mach->CondMask &= ~0x2;
3990       }
3991       if( ! r[0].f[2] ) {
3992          mach->CondMask &= ~0x4;
3993       }
3994       if( ! r[0].f[3] ) {
3995          mach->CondMask &= ~0x8;
3996       }
3997       UPDATE_EXEC_MASK(mach);
3998       /* Todo: If CondMask==0, jump to ELSE */
3999       break;
4000
4001    case TGSI_OPCODE_UIF:
4002       /* push CondMask */
4003       assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING);
4004       mach->CondStack[mach->CondStackTop++] = mach->CondMask;
4005       IFETCH( &r[0], 0, TGSI_CHAN_X );
4006       /* update CondMask */
4007       if( ! r[0].u[0] ) {
4008          mach->CondMask &= ~0x1;
4009       }
4010       if( ! r[0].u[1] ) {
4011          mach->CondMask &= ~0x2;
4012       }
4013       if( ! r[0].u[2] ) {
4014          mach->CondMask &= ~0x4;
4015       }
4016       if( ! r[0].u[3] ) {
4017          mach->CondMask &= ~0x8;
4018       }
4019       UPDATE_EXEC_MASK(mach);
4020       /* Todo: If CondMask==0, jump to ELSE */
4021       break;
4022
4023    case TGSI_OPCODE_ELSE:
4024       /* invert CondMask wrt previous mask */
4025       {
4026          uint prevMask;
4027          assert(mach->CondStackTop > 0);
4028          prevMask = mach->CondStack[mach->CondStackTop - 1];
4029          mach->CondMask = ~mach->CondMask & prevMask;
4030          UPDATE_EXEC_MASK(mach);
4031          /* Todo: If CondMask==0, jump to ENDIF */
4032       }
4033       break;
4034
4035    case TGSI_OPCODE_ENDIF:
4036       /* pop CondMask */
4037       assert(mach->CondStackTop > 0);
4038       mach->CondMask = mach->CondStack[--mach->CondStackTop];
4039       UPDATE_EXEC_MASK(mach);
4040       break;
4041
4042    case TGSI_OPCODE_END:
4043       /* make sure we end primitives which haven't
4044        * been explicitly emitted */
4045       conditional_emit_primitive(mach);
4046       /* halt execution */
4047       *pc = -1;
4048       break;
4049
4050    case TGSI_OPCODE_PUSHA:
4051       assert (0);
4052       break;
4053
4054    case TGSI_OPCODE_POPA:
4055       assert (0);
4056       break;
4057
4058    case TGSI_OPCODE_CEIL:
4059       exec_vector_unary(mach, inst, micro_ceil, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
4060       break;
4061
4062    case TGSI_OPCODE_I2F:
4063       exec_vector_unary(mach, inst, micro_i2f, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_INT);
4064       break;
4065
4066    case TGSI_OPCODE_NOT:
4067       exec_vector_unary(mach, inst, micro_not, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4068       break;
4069
4070    case TGSI_OPCODE_TRUNC:
4071       exec_vector_unary(mach, inst, micro_trunc, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
4072       break;
4073
4074    case TGSI_OPCODE_SHL:
4075       exec_vector_binary(mach, inst, micro_shl, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4076       break;
4077
4078    case TGSI_OPCODE_AND:
4079       exec_vector_binary(mach, inst, micro_and, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4080       break;
4081
4082    case TGSI_OPCODE_OR:
4083       exec_vector_binary(mach, inst, micro_or, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4084       break;
4085
4086    case TGSI_OPCODE_MOD:
4087       exec_vector_binary(mach, inst, micro_mod, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
4088       break;
4089
4090    case TGSI_OPCODE_XOR:
4091       exec_vector_binary(mach, inst, micro_xor, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4092       break;
4093
4094    case TGSI_OPCODE_SAD:
4095       assert (0);
4096       break;
4097
4098    case TGSI_OPCODE_TXF:
4099       exec_txf(mach, inst);
4100       break;
4101
4102    case TGSI_OPCODE_TXQ:
4103       exec_txq(mach, inst);
4104       break;
4105
4106    case TGSI_OPCODE_EMIT:
4107       emit_vertex(mach);
4108       break;
4109
4110    case TGSI_OPCODE_ENDPRIM:
4111       emit_primitive(mach);
4112       break;
4113
4114    case TGSI_OPCODE_BGNLOOP:
4115       /* push LoopMask and ContMasks */
4116       assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
4117       assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
4118       assert(mach->LoopLabelStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
4119       assert(mach->BreakStackTop < TGSI_EXEC_MAX_BREAK_STACK);
4120
4121       mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
4122       mach->ContStack[mach->ContStackTop++] = mach->ContMask;
4123       mach->LoopLabelStack[mach->LoopLabelStackTop++] = *pc - 1;
4124       mach->BreakStack[mach->BreakStackTop++] = mach->BreakType;
4125       mach->BreakType = TGSI_EXEC_BREAK_INSIDE_LOOP;
4126       break;
4127
4128    case TGSI_OPCODE_ENDLOOP:
4129       /* Restore ContMask, but don't pop */
4130       assert(mach->ContStackTop > 0);
4131       mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
4132       UPDATE_EXEC_MASK(mach);
4133       if (mach->ExecMask) {
4134          /* repeat loop: jump to instruction just past BGNLOOP */
4135          assert(mach->LoopLabelStackTop > 0);
4136          *pc = mach->LoopLabelStack[mach->LoopLabelStackTop - 1] + 1;
4137       }
4138       else {
4139          /* exit loop: pop LoopMask */
4140          assert(mach->LoopStackTop > 0);
4141          mach->LoopMask = mach->LoopStack[--mach->LoopStackTop];
4142          /* pop ContMask */
4143          assert(mach->ContStackTop > 0);
4144          mach->ContMask = mach->ContStack[--mach->ContStackTop];
4145          assert(mach->LoopLabelStackTop > 0);
4146          --mach->LoopLabelStackTop;
4147
4148          mach->BreakType = mach->BreakStack[--mach->BreakStackTop];
4149       }
4150       UPDATE_EXEC_MASK(mach);
4151       break;
4152
4153    case TGSI_OPCODE_BRK:
4154       exec_break(mach);
4155       break;
4156
4157    case TGSI_OPCODE_CONT:
4158       /* turn off cont channels for each enabled exec channel */
4159       mach->ContMask &= ~mach->ExecMask;
4160       /* Todo: if mach->LoopMask == 0, jump to end of loop */
4161       UPDATE_EXEC_MASK(mach);
4162       break;
4163
4164    case TGSI_OPCODE_BGNSUB:
4165       /* no-op */
4166       break;
4167
4168    case TGSI_OPCODE_ENDSUB:
4169       /*
4170        * XXX: This really should be a no-op. We should never reach this opcode.
4171        */
4172
4173       assert(mach->CallStackTop > 0);
4174       mach->CallStackTop--;
4175
4176       mach->CondStackTop = mach->CallStack[mach->CallStackTop].CondStackTop;
4177       mach->CondMask = mach->CondStack[mach->CondStackTop];
4178
4179       mach->LoopStackTop = mach->CallStack[mach->CallStackTop].LoopStackTop;
4180       mach->LoopMask = mach->LoopStack[mach->LoopStackTop];
4181
4182       mach->ContStackTop = mach->CallStack[mach->CallStackTop].ContStackTop;
4183       mach->ContMask = mach->ContStack[mach->ContStackTop];
4184
4185       mach->SwitchStackTop = mach->CallStack[mach->CallStackTop].SwitchStackTop;
4186       mach->Switch = mach->SwitchStack[mach->SwitchStackTop];
4187
4188       mach->BreakStackTop = mach->CallStack[mach->CallStackTop].BreakStackTop;
4189       mach->BreakType = mach->BreakStack[mach->BreakStackTop];
4190
4191       assert(mach->FuncStackTop > 0);
4192       mach->FuncMask = mach->FuncStack[--mach->FuncStackTop];
4193
4194       *pc = mach->CallStack[mach->CallStackTop].ReturnAddr;
4195
4196       UPDATE_EXEC_MASK(mach);
4197       break;
4198
4199    case TGSI_OPCODE_NOP:
4200       break;
4201
4202    case TGSI_OPCODE_BREAKC:
4203       FETCH(&r[0], 0, TGSI_CHAN_X);
4204       /* update CondMask */
4205       if (r[0].u[0] && (mach->ExecMask & 0x1)) {
4206          mach->LoopMask &= ~0x1;
4207       }
4208       if (r[0].u[1] && (mach->ExecMask & 0x2)) {
4209          mach->LoopMask &= ~0x2;
4210       }
4211       if (r[0].u[2] && (mach->ExecMask & 0x4)) {
4212          mach->LoopMask &= ~0x4;
4213       }
4214       if (r[0].u[3] && (mach->ExecMask & 0x8)) {
4215          mach->LoopMask &= ~0x8;
4216       }
4217       /* Todo: if mach->LoopMask == 0, jump to end of loop */
4218       UPDATE_EXEC_MASK(mach);
4219       break;
4220
4221    case TGSI_OPCODE_F2I:
4222       exec_vector_unary(mach, inst, micro_f2i, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_FLOAT);
4223       break;
4224
4225    case TGSI_OPCODE_IDIV:
4226       exec_vector_binary(mach, inst, micro_idiv, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
4227       break;
4228
4229    case TGSI_OPCODE_IMAX:
4230       exec_vector_binary(mach, inst, micro_imax, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
4231       break;
4232
4233    case TGSI_OPCODE_IMIN:
4234       exec_vector_binary(mach, inst, micro_imin, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
4235       break;
4236
4237    case TGSI_OPCODE_INEG:
4238       exec_vector_unary(mach, inst, micro_ineg, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
4239       break;
4240
4241    case TGSI_OPCODE_ISGE:
4242       exec_vector_binary(mach, inst, micro_isge, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
4243       break;
4244
4245    case TGSI_OPCODE_ISHR:
4246       exec_vector_binary(mach, inst, micro_ishr, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
4247       break;
4248
4249    case TGSI_OPCODE_ISLT:
4250       exec_vector_binary(mach, inst, micro_islt, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
4251       break;
4252
4253    case TGSI_OPCODE_F2U:
4254       exec_vector_unary(mach, inst, micro_f2u, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_FLOAT);
4255       break;
4256
4257    case TGSI_OPCODE_U2F:
4258       exec_vector_unary(mach, inst, micro_u2f, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_UINT);
4259       break;
4260
4261    case TGSI_OPCODE_UADD:
4262       exec_vector_binary(mach, inst, micro_uadd, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
4263       break;
4264
4265    case TGSI_OPCODE_UDIV:
4266       exec_vector_binary(mach, inst, micro_udiv, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4267       break;
4268
4269    case TGSI_OPCODE_UMAD:
4270       exec_vector_trinary(mach, inst, micro_umad, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4271       break;
4272
4273    case TGSI_OPCODE_UMAX:
4274       exec_vector_binary(mach, inst, micro_umax, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4275       break;
4276
4277    case TGSI_OPCODE_UMIN:
4278       exec_vector_binary(mach, inst, micro_umin, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4279       break;
4280
4281    case TGSI_OPCODE_UMOD:
4282       exec_vector_binary(mach, inst, micro_umod, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4283       break;
4284
4285    case TGSI_OPCODE_UMUL:
4286       exec_vector_binary(mach, inst, micro_umul, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4287       break;
4288
4289    case TGSI_OPCODE_USEQ:
4290       exec_vector_binary(mach, inst, micro_useq, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4291       break;
4292
4293    case TGSI_OPCODE_USGE:
4294       exec_vector_binary(mach, inst, micro_usge, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4295       break;
4296
4297    case TGSI_OPCODE_USHR:
4298       exec_vector_binary(mach, inst, micro_ushr, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4299       break;
4300
4301    case TGSI_OPCODE_USLT:
4302       exec_vector_binary(mach, inst, micro_uslt, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4303       break;
4304
4305    case TGSI_OPCODE_USNE:
4306       exec_vector_binary(mach, inst, micro_usne, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4307       break;
4308
4309    case TGSI_OPCODE_SWITCH:
4310       exec_switch(mach, inst);
4311       break;
4312
4313    case TGSI_OPCODE_CASE:
4314       exec_case(mach, inst);
4315       break;
4316
4317    case TGSI_OPCODE_DEFAULT:
4318       exec_default(mach);
4319       break;
4320
4321    case TGSI_OPCODE_ENDSWITCH:
4322       exec_endswitch(mach);
4323       break;
4324
4325    case TGSI_OPCODE_SAMPLE_I:
4326       exec_txf(mach, inst);
4327       break;
4328
4329    case TGSI_OPCODE_SAMPLE_I_MS:
4330       assert(0);
4331       break;
4332
4333    case TGSI_OPCODE_SAMPLE:
4334       exec_sample(mach, inst, TEX_MODIFIER_NONE, FALSE);
4335       break;
4336
4337    case TGSI_OPCODE_SAMPLE_B:
4338       exec_sample(mach, inst, TEX_MODIFIER_LOD_BIAS, FALSE);
4339       break;
4340
4341    case TGSI_OPCODE_SAMPLE_C:
4342       exec_sample(mach, inst, TEX_MODIFIER_NONE, TRUE);
4343       break;
4344
4345    case TGSI_OPCODE_SAMPLE_C_LZ:
4346       exec_sample(mach, inst, TEX_MODIFIER_LEVEL_ZERO, TRUE);
4347       break;
4348
4349    case TGSI_OPCODE_SAMPLE_D:
4350       exec_sample_d(mach, inst);
4351       break;
4352
4353    case TGSI_OPCODE_SAMPLE_L:
4354       exec_sample(mach, inst, TEX_MODIFIER_EXPLICIT_LOD, FALSE);
4355       break;
4356
4357    case TGSI_OPCODE_GATHER4:
4358       assert(0);
4359       break;
4360
4361    case TGSI_OPCODE_SVIEWINFO:
4362       exec_txq(mach, inst);
4363       break;
4364
4365    case TGSI_OPCODE_SAMPLE_POS:
4366       assert(0);
4367       break;
4368
4369    case TGSI_OPCODE_SAMPLE_INFO:
4370       assert(0);
4371       break;
4372
4373    case TGSI_OPCODE_UARL:
4374       exec_vector_unary(mach, inst, micro_uarl, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_UINT);
4375       break;
4376
4377    case TGSI_OPCODE_UCMP:
4378       exec_vector_trinary(mach, inst, micro_ucmp, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
4379       break;
4380
4381    case TGSI_OPCODE_IABS:
4382       exec_vector_unary(mach, inst, micro_iabs, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
4383       break;
4384
4385    case TGSI_OPCODE_ISSG:
4386       exec_vector_unary(mach, inst, micro_isgn, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
4387       break;
4388
4389    case TGSI_OPCODE_TEX2:
4390       /* simple texture lookup */
4391       /* src[0] = texcoord */
4392       /* src[1] = compare */
4393       /* src[2] = sampler unit */
4394       exec_tex(mach, inst, TEX_MODIFIER_NONE, 2);
4395       break;
4396    case TGSI_OPCODE_TXB2:
4397       /* simple texture lookup */
4398       /* src[0] = texcoord */
4399       /* src[1] = bias */
4400       /* src[2] = sampler unit */
4401       exec_tex(mach, inst, TEX_MODIFIER_LOD_BIAS, 2);
4402       break;
4403    case TGSI_OPCODE_TXL2:
4404       /* simple texture lookup */
4405       /* src[0] = texcoord */
4406       /* src[1] = lod */
4407       /* src[2] = sampler unit */
4408       exec_tex(mach, inst, TEX_MODIFIER_EXPLICIT_LOD, 2);
4409       break;
4410    default:
4411       assert( 0 );
4412    }
4413 }
4414
4415
4416 /**
4417  * Run TGSI interpreter.
4418  * \return bitmask of "alive" quad components
4419  */
4420 uint
4421 tgsi_exec_machine_run( struct tgsi_exec_machine *mach )
4422 {
4423    uint i;
4424    int pc = 0;
4425    uint default_mask = 0xf;
4426
4427    mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0;
4428    mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] = 0;
4429
4430    if( mach->Processor == TGSI_PROCESSOR_GEOMETRY ) {
4431       mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0] = 0;
4432       mach->Primitives[0] = 0;
4433       /* GS runs on a single primitive for now */
4434       default_mask = 0x1;
4435    }
4436
4437    mach->CondMask = default_mask;
4438    mach->LoopMask = default_mask;
4439    mach->ContMask = default_mask;
4440    mach->FuncMask = default_mask;
4441    mach->ExecMask = default_mask;
4442
4443    mach->Switch.mask = default_mask;
4444
4445    assert(mach->CondStackTop == 0);
4446    assert(mach->LoopStackTop == 0);
4447    assert(mach->ContStackTop == 0);
4448    assert(mach->SwitchStackTop == 0);
4449    assert(mach->BreakStackTop == 0);
4450    assert(mach->CallStackTop == 0);
4451
4452
4453    /* execute declarations (interpolants) */
4454    for (i = 0; i < mach->NumDeclarations; i++) {
4455       exec_declaration( mach, mach->Declarations+i );
4456    }
4457
4458    {
4459 #if DEBUG_EXECUTION
4460       struct tgsi_exec_vector temps[TGSI_EXEC_NUM_TEMPS + TGSI_EXEC_NUM_TEMP_EXTRAS];
4461       struct tgsi_exec_vector outputs[PIPE_MAX_ATTRIBS];
4462       uint inst = 1;
4463
4464       memset(mach->Temps, 0, sizeof(temps));
4465       memset(mach->Outputs, 0, sizeof(outputs));
4466       memset(temps, 0, sizeof(temps));
4467       memset(outputs, 0, sizeof(outputs));
4468 #endif
4469
4470       /* execute instructions, until pc is set to -1 */
4471       while (pc != -1) {
4472
4473 #if DEBUG_EXECUTION
4474          uint i;
4475
4476          tgsi_dump_instruction(&mach->Instructions[pc], inst++);
4477 #endif
4478
4479          assert(pc < (int) mach->NumInstructions);
4480          exec_instruction(mach, mach->Instructions + pc, &pc);
4481
4482 #if DEBUG_EXECUTION
4483          for (i = 0; i < TGSI_EXEC_NUM_TEMPS + TGSI_EXEC_NUM_TEMP_EXTRAS; i++) {
4484             if (memcmp(&temps[i], &mach->Temps[i], sizeof(temps[i]))) {
4485                uint j;
4486
4487                memcpy(&temps[i], &mach->Temps[i], sizeof(temps[i]));
4488                debug_printf("TEMP[%2u] = ", i);
4489                for (j = 0; j < 4; j++) {
4490                   if (j > 0) {
4491                      debug_printf("           ");
4492                   }
4493                   debug_printf("(%6f %u, %6f %u, %6f %u, %6f %u)\n",
4494                                temps[i].xyzw[0].f[j], temps[i].xyzw[0].u[j],
4495                                temps[i].xyzw[1].f[j], temps[i].xyzw[1].u[j],
4496                                temps[i].xyzw[2].f[j], temps[i].xyzw[2].u[j],
4497                                temps[i].xyzw[3].f[j], temps[i].xyzw[3].u[j]);
4498                }
4499             }
4500          }
4501          for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
4502             if (memcmp(&outputs[i], &mach->Outputs[i], sizeof(outputs[i]))) {
4503                uint j;
4504
4505                memcpy(&outputs[i], &mach->Outputs[i], sizeof(outputs[i]));
4506                debug_printf("OUT[%2u] =  ", i);
4507                for (j = 0; j < 4; j++) {
4508                   if (j > 0) {
4509                      debug_printf("           ");
4510                   }
4511                   debug_printf("(%6f %u, %6f %u, %6f %u, %6f %u)\n",
4512                                outputs[i].xyzw[0].f[j], outputs[i].xyzw[0].u[j],
4513                                outputs[i].xyzw[1].f[j], outputs[i].xyzw[1].u[j],
4514                                outputs[i].xyzw[2].f[j], outputs[i].xyzw[2].u[j],
4515                                outputs[i].xyzw[3].f[j], outputs[i].xyzw[3].u[j]);
4516                }
4517             }
4518          }
4519 #endif
4520       }
4521    }
4522
4523 #if 0
4524    /* we scale from floats in [0,1] to Zbuffer ints in sp_quad_depth_test.c */
4525    if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) {
4526       /*
4527        * Scale back depth component.
4528        */
4529       for (i = 0; i < 4; i++)
4530          mach->Outputs[0].xyzw[2].f[i] *= ctx->DrawBuffer->_DepthMaxF;
4531    }
4532 #endif
4533
4534    /* Strictly speaking, these assertions aren't really needed but they
4535     * can potentially catch some bugs in the control flow code.
4536     */
4537    assert(mach->CondStackTop == 0);
4538    assert(mach->LoopStackTop == 0);
4539    assert(mach->ContStackTop == 0);
4540    assert(mach->SwitchStackTop == 0);
4541    assert(mach->BreakStackTop == 0);
4542    assert(mach->CallStackTop == 0);
4543
4544    return ~mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0];
4545 }