code tweaks, remove old comments
[mesa.git] / src / mesa / shader / slang / slang_execute.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 2005-2006 Brian Paul 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 "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file slang_execute.c
27 * intermediate code interpreter
28 * \author Michal Krol
29 */
30
31 #include "imports.h"
32 #include "slang_compile.h"
33 #include "slang_execute.h"
34 #include "slang_library_noise.h"
35 #include "slang_library_texsample.h"
36
37 #define DEBUG_SLANG 0
38
39 GLvoid slang_machine_ctr (slang_machine *self)
40 {
41 slang_machine_init (self);
42 self->infolog = NULL;
43 #if defined(USE_X86_ASM) || defined(SLANG_X86)
44 self->x86.compiled_func = NULL;
45 #endif
46 }
47
48 GLvoid slang_machine_dtr (slang_machine *self)
49 {
50 if (self->infolog != NULL) {
51 slang_info_log_destruct (self->infolog);
52 slang_alloc_free (self->infolog);
53 }
54 #if defined(USE_X86_ASM) || defined(SLANG_X86)
55 if (self->x86.compiled_func != NULL)
56 _mesa_exec_free (self->x86.compiled_func);
57 #endif
58 }
59
60 void slang_machine_init (slang_machine *mach)
61 {
62 mach->ip = 0;
63 mach->sp = SLANG_MACHINE_STACK_SIZE;
64 mach->bp = 0;
65 mach->kill = 0;
66 mach->exit = 0;
67 }
68
69 #if DEBUG_SLANG
70
71 static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i)
72 {
73 fprintf (f, "%.5u:\t", i);
74
75 switch (a->type)
76 {
77 /* core */
78 case slang_asm_none:
79 fprintf (f, "none");
80 break;
81 case slang_asm_float_copy:
82 fprintf (f, "float_copy\t%d, %d", a->param[0], a->param[1]);
83 break;
84 case slang_asm_float_move:
85 fprintf (f, "float_move\t%d, %d", a->param[0], a->param[1]);
86 break;
87 case slang_asm_float_push:
88 fprintf (f, "float_push\t%f", a->literal);
89 break;
90 case slang_asm_float_deref:
91 fprintf (f, "float_deref");
92 break;
93 case slang_asm_float_add:
94 fprintf (f, "float_add");
95 break;
96 case slang_asm_float_multiply:
97 fprintf (f, "float_multiply");
98 break;
99 case slang_asm_float_divide:
100 fprintf (f, "float_divide");
101 break;
102 case slang_asm_float_negate:
103 fprintf (f, "float_negate");
104 break;
105 case slang_asm_float_less:
106 fprintf (f, "float_less");
107 break;
108 case slang_asm_float_equal_exp:
109 fprintf (f, "float_equal");
110 break;
111 case slang_asm_float_equal_int:
112 fprintf (f, "float_equal\t%d, %d", a->param[0], a->param[1]);
113 break;
114 case slang_asm_float_to_int:
115 fprintf (f, "float_to_int");
116 break;
117 case slang_asm_float_sine:
118 fprintf (f, "float_sine");
119 break;
120 case slang_asm_float_arcsine:
121 fprintf (f, "float_arcsine");
122 break;
123 case slang_asm_float_arctan:
124 fprintf (f, "float_arctan");
125 break;
126 case slang_asm_float_power:
127 fprintf (f, "float_power");
128 break;
129 case slang_asm_float_log2:
130 fprintf (f, "float_log2");
131 break;
132 case slang_asm_float_floor:
133 fprintf (f, "float_floor");
134 break;
135 case slang_asm_float_ceil:
136 fprintf (f, "float_ceil");
137 break;
138 case slang_asm_float_noise1:
139 fprintf (f, "float_noise1");
140 break;
141 case slang_asm_float_noise2:
142 fprintf (f, "float_noise2");
143 break;
144 case slang_asm_float_noise3:
145 fprintf (f, "float_noise3");
146 break;
147 case slang_asm_float_noise4:
148 fprintf (f, "float_noise4");
149 break;
150 case slang_asm_int_copy:
151 fprintf (f, "int_copy\t%d, %d", a->param[0], a->param[1]);
152 break;
153 case slang_asm_int_move:
154 fprintf (f, "int_move\t%d, %d", a->param[0], a->param[1]);
155 break;
156 case slang_asm_int_push:
157 fprintf (f, "int_push\t%d", (GLint) a->literal);
158 break;
159 case slang_asm_int_deref:
160 fprintf (f, "int_deref");
161 break;
162 case slang_asm_int_to_float:
163 fprintf (f, "int_to_float");
164 break;
165 case slang_asm_int_to_addr:
166 fprintf (f, "int_to_addr");
167 break;
168 case slang_asm_bool_copy:
169 fprintf (f, "bool_copy\t%d, %d", a->param[0], a->param[1]);
170 break;
171 case slang_asm_bool_move:
172 fprintf (f, "bool_move\t%d, %d", a->param[0], a->param[1]);
173 break;
174 case slang_asm_bool_push:
175 fprintf (f, "bool_push\t%d", a->literal != 0.0f);
176 break;
177 case slang_asm_bool_deref:
178 fprintf (f, "bool_deref");
179 break;
180 case slang_asm_addr_copy:
181 fprintf (f, "addr_copy");
182 break;
183 case slang_asm_addr_push:
184 fprintf (f, "addr_push\t%u", a->param[0]);
185 break;
186 case slang_asm_addr_deref:
187 fprintf (f, "addr_deref");
188 break;
189 case slang_asm_addr_add:
190 fprintf (f, "addr_add");
191 break;
192 case slang_asm_addr_multiply:
193 fprintf (f, "addr_multiply");
194 break;
195 case slang_asm_vec4_tex1d:
196 fprintf (f, "vec4_tex1d");
197 break;
198 case slang_asm_vec4_tex2d:
199 fprintf (f, "vec4_tex2d");
200 break;
201 case slang_asm_vec4_tex3d:
202 fprintf (f, "vec4_tex3d");
203 break;
204 case slang_asm_vec4_texcube:
205 fprintf (f, "vec4_texcube");
206 break;
207 case slang_asm_vec4_shad1d:
208 fprintf (f, "vec4_shad1d");
209 break;
210 case slang_asm_vec4_shad2d:
211 fprintf (f, "vec4_shad2d");
212 break;
213 case slang_asm_jump:
214 fprintf (f, "jump\t%u", a->param[0]);
215 break;
216 case slang_asm_jump_if_zero:
217 fprintf (f, "jump_if_zero\t%u", a->param[0]);
218 break;
219 case slang_asm_enter:
220 fprintf (f, "enter\t%u", a->param[0]);
221 break;
222 case slang_asm_leave:
223 fprintf (f, "leave");
224 break;
225 case slang_asm_local_alloc:
226 fprintf (f, "local_alloc\t%u", a->param[0]);
227 break;
228 case slang_asm_local_free:
229 fprintf (f, "local_free\t%u", a->param[0]);
230 break;
231 case slang_asm_local_addr:
232 fprintf (f, "local_addr\t%u, %u", a->param[0], a->param[1]);
233 break;
234 case slang_asm_global_addr:
235 fprintf (f, "global_addr\t%u", a->param[0]);
236 break;
237 case slang_asm_call:
238 fprintf (f, "call\t%u", a->param[0]);
239 break;
240 case slang_asm_return:
241 fprintf (f, "return");
242 break;
243 case slang_asm_discard:
244 fprintf (f, "discard");
245 break;
246 case slang_asm_exit:
247 fprintf (f, "exit");
248 break;
249 /* GL_MESA_shader_debug */
250 case slang_asm_float_print:
251 fprintf (f, "float_print");
252 break;
253 case slang_asm_int_print:
254 fprintf (f, "int_print");
255 break;
256 case slang_asm_bool_print:
257 fprintf (f, "bool_print");
258 break;
259 /* vec4 */
260 case slang_asm_float_to_vec4:
261 fprintf (f, "float_to_vec4");
262 break;
263 case slang_asm_vec4_add:
264 fprintf (f, "vec4_add");
265 break;
266 case slang_asm_vec4_subtract:
267 fprintf (f, "vec4_subtract");
268 break;
269 case slang_asm_vec4_multiply:
270 fprintf (f, "vec4_multiply");
271 break;
272 case slang_asm_vec4_divide:
273 fprintf (f, "vec4_divide");
274 break;
275 case slang_asm_vec4_negate:
276 fprintf (f, "vec4_negate");
277 break;
278 case slang_asm_vec4_dot:
279 fprintf (f, "vec4_dot");
280 break;
281 case slang_asm_vec4_copy:
282 fprintf (f, "vec4_copy");
283 break;
284 case slang_asm_vec4_deref:
285 fprintf (f, "vec4_deref");
286 break;
287 case slang_asm_vec4_equal_int:
288 fprintf (f, "vec4_equal");
289 break;
290 default:
291 break;
292 }
293
294 fprintf (f, "\n");
295 }
296
297 static void dump (const slang_assembly_file *file)
298 {
299 unsigned int i;
300 static unsigned int counter = 0;
301 FILE *f;
302 char filename[256];
303
304 counter++;
305 _mesa_sprintf (filename, "~mesa-slang-assembly-dump-(%u).txt", counter);
306 f = fopen (filename, "w");
307 if (f == NULL)
308 return;
309
310 for (i = 0; i < file->count; i++)
311 dump_instruction (f, file->code + i, i);
312
313 fclose (f);
314 }
315
316 #endif
317
318 static GLvoid
319 ensure_infolog_created (slang_info_log **infolog)
320 {
321 if (*infolog == NULL) {
322 *infolog = slang_alloc_malloc (sizeof (slang_info_log));
323 if (*infolog == NULL)
324 return;
325 slang_info_log_construct (*infolog);
326 }
327 }
328
329 GLboolean
330 _slang_execute2 (const slang_assembly_file *file, slang_machine *mach)
331 {
332 slang_machine_slot *stack;
333
334 #if DEBUG_SLANG
335 static unsigned int counter = 0;
336 char filename[256];
337 FILE *f;
338 #endif
339
340 /* assume 32-bit floats and uints; should work fine also on 64-bit platforms */
341 static_assert(sizeof (GLfloat) == 4);
342 static_assert(sizeof (GLuint) == 4);
343
344 #if DEBUG_SLANG
345 dump (file);
346 counter++;
347 _mesa_sprintf (filename, "~mesa-slang-assembly-exec-(%u).txt", counter);
348 f = fopen (filename, "w");
349 #endif
350
351 #if defined(USE_X86_ASM) || defined(SLANG_X86)
352 if (mach->x86.compiled_func != NULL)
353 {
354 mach->x86.compiled_func (mach);
355 return GL_TRUE;
356 }
357 #endif
358
359 stack = mach->mem + SLANG_MACHINE_GLOBAL_SIZE;
360
361 while (!mach->exit)
362 {
363 slang_assembly *a = &file->code[mach->ip];
364
365 #if DEBUG_SLANG
366 if (f != NULL && a->type != slang_asm_none)
367 {
368 unsigned int i;
369
370 dump_instruction (f, file->code + mach->ip, mach->ip);
371 fprintf (f, "\t\tsp=%u bp=%u\n", mach->sp, mach->bp);
372 for (i = mach->sp; i < SLANG_MACHINE_STACK_SIZE; i++)
373 fprintf (f, "\t%.5u\t%6f\t%u\n", i, stack[i]._float, stack[i]._addr);
374 fflush (f);
375 }
376 #endif
377
378 mach->ip++;
379
380 switch (a->type)
381 {
382 /* core */
383 case slang_asm_none:
384 break;
385 case slang_asm_float_copy:
386 case slang_asm_int_copy:
387 case slang_asm_bool_copy:
388 mach->mem[(stack[mach->sp + a->param[0] / 4]._addr + a->param[1]) / 4]._float =
389 stack[mach->sp]._float;
390 mach->sp++;
391 break;
392 case slang_asm_float_move:
393 case slang_asm_int_move:
394 case slang_asm_bool_move:
395 stack[mach->sp + a->param[0] / 4]._float =
396 stack[mach->sp + (stack[mach->sp]._addr + a->param[1]) / 4]._float;
397 break;
398 case slang_asm_float_push:
399 case slang_asm_int_push:
400 case slang_asm_bool_push:
401 mach->sp--;
402 stack[mach->sp]._float = a->literal;
403 break;
404 case slang_asm_float_deref:
405 case slang_asm_int_deref:
406 case slang_asm_bool_deref:
407 stack[mach->sp]._float = mach->mem[stack[mach->sp]._addr / 4]._float;
408 break;
409 case slang_asm_float_add:
410 stack[mach->sp + 1]._float += stack[mach->sp]._float;
411 mach->sp++;
412 break;
413 case slang_asm_float_multiply:
414 stack[mach->sp + 1]._float *= stack[mach->sp]._float;
415 mach->sp++;
416 break;
417 case slang_asm_float_divide:
418 stack[mach->sp + 1]._float /= stack[mach->sp]._float;
419 mach->sp++;
420 break;
421 case slang_asm_float_negate:
422 stack[mach->sp]._float = -stack[mach->sp]._float;
423 break;
424 case slang_asm_float_less:
425 stack[mach->sp + 1]._float =
426 stack[mach->sp + 1]._float < stack[mach->sp]._float ? (GLfloat) 1 : (GLfloat) 0;
427 mach->sp++;
428 break;
429 case slang_asm_float_equal_exp:
430 stack[mach->sp + 1]._float =
431 stack[mach->sp + 1]._float == stack[mach->sp]._float ? (GLfloat) 1 : (GLfloat) 0;
432 mach->sp++;
433 break;
434 case slang_asm_float_equal_int:
435 mach->sp--;
436 stack[mach->sp]._float = stack[mach->sp + 1 + a->param[0] / 4]._float ==
437 stack[mach->sp + 1 + a->param[1] / 4]._float ? (GLfloat) 1 : (GLfloat) 0;
438 break;
439 case slang_asm_float_to_int:
440 stack[mach->sp]._float = (GLfloat) (GLint) stack[mach->sp]._float;
441 break;
442 case slang_asm_float_sine:
443 stack[mach->sp]._float = (GLfloat) _mesa_sin (stack[mach->sp]._float);
444 break;
445 case slang_asm_float_arcsine:
446 stack[mach->sp]._float = _mesa_asinf (stack[mach->sp]._float);
447 break;
448 case slang_asm_float_arctan:
449 stack[mach->sp]._float = _mesa_atanf (stack[mach->sp]._float);
450 break;
451 case slang_asm_float_power:
452 stack[mach->sp + 1]._float =
453 (GLfloat) _mesa_pow (stack[mach->sp + 1]._float, stack[mach->sp]._float);
454 mach->sp++;
455 break;
456 case slang_asm_float_log2:
457 stack[mach->sp]._float = LOG2 (stack[mach->sp]._float);
458 break;
459 case slang_asm_float_floor:
460 stack[mach->sp]._float = FLOORF (stack[mach->sp]._float);
461 break;
462 case slang_asm_float_ceil:
463 stack[mach->sp]._float = CEILF (stack[mach->sp]._float);
464 break;
465 case slang_asm_float_noise1:
466 stack[mach->sp]._float = _slang_library_noise1 (stack[mach->sp]._float);
467 break;
468 case slang_asm_float_noise2:
469 stack[mach->sp + 1]._float = _slang_library_noise2 (stack[mach->sp]._float,
470 stack[mach->sp + 1]._float);
471 mach->sp++;
472 break;
473 case slang_asm_float_noise3:
474 stack[mach->sp + 2]._float = _slang_library_noise3 (stack[mach->sp]._float,
475 stack[mach->sp + 1]._float, stack[mach->sp + 2]._float);
476 mach->sp += 2;
477 break;
478 case slang_asm_float_noise4:
479 stack[mach->sp + 3]._float = _slang_library_noise4 (stack[mach->sp]._float,
480 stack[mach->sp + 1]._float, stack[mach->sp + 2]._float, stack[mach->sp + 3]._float);
481 mach->sp += 3;
482 break;
483 case slang_asm_int_to_float:
484 break;
485 case slang_asm_int_to_addr:
486 stack[mach->sp]._addr = (GLuint) (GLint) stack[mach->sp]._float;
487 break;
488 case slang_asm_addr_copy:
489 mach->mem[stack[mach->sp + 1]._addr / 4]._addr = stack[mach->sp]._addr;
490 mach->sp++;
491 break;
492 case slang_asm_addr_push:
493 case slang_asm_global_addr:
494 mach->sp--;
495 stack[mach->sp]._addr = a->param[0];
496 break;
497 case slang_asm_addr_deref:
498 stack[mach->sp]._addr = mach->mem[stack[mach->sp]._addr / 4]._addr;
499 break;
500 case slang_asm_addr_add:
501 stack[mach->sp + 1]._addr += stack[mach->sp]._addr;
502 mach->sp++;
503 break;
504 case slang_asm_addr_multiply:
505 stack[mach->sp + 1]._addr *= stack[mach->sp]._addr;
506 mach->sp++;
507 break;
508 case slang_asm_vec4_tex1d:
509 _slang_library_tex1d (stack[mach->sp]._float, stack[mach->sp + 1]._float,
510 stack[mach->sp + 2]._float, &mach->mem[stack[mach->sp + 3]._addr / 4]._float);
511 mach->sp += 3;
512 break;
513 case slang_asm_vec4_tex2d:
514 _slang_library_tex2d (stack[mach->sp]._float, stack[mach->sp + 1]._float,
515 stack[mach->sp + 2]._float, stack[mach->sp + 3]._float,
516 &mach->mem[stack[mach->sp + 4]._addr / 4]._float);
517 mach->sp += 4;
518 break;
519 case slang_asm_vec4_tex3d:
520 _slang_library_tex3d (stack[mach->sp]._float, stack[mach->sp + 1]._float,
521 stack[mach->sp + 2]._float, stack[mach->sp + 3]._float, stack[mach->sp + 4]._float,
522 &mach->mem[stack[mach->sp + 5]._addr / 4]._float);
523 mach->sp += 5;
524 break;
525 case slang_asm_vec4_texcube:
526 _slang_library_texcube (stack[mach->sp]._float, stack[mach->sp + 1]._float,
527 stack[mach->sp + 2]._float, stack[mach->sp + 3]._float, stack[mach->sp + 4]._float,
528 &mach->mem[stack[mach->sp + 5]._addr / 4]._float);
529 mach->sp += 5;
530 break;
531 case slang_asm_vec4_shad1d:
532 _slang_library_shad1d (stack[mach->sp]._float, stack[mach->sp + 1]._float,
533 stack[mach->sp + 2]._float, stack[mach->sp + 3]._float, stack[mach->sp + 4]._float,
534 &mach->mem[stack[mach->sp + 5]._addr / 4]._float);
535 mach->sp += 5;
536 break;
537 case slang_asm_vec4_shad2d:
538 _slang_library_shad2d (stack[mach->sp]._float, stack[mach->sp + 1]._float,
539 stack[mach->sp + 2]._float, stack[mach->sp + 3]._float, stack[mach->sp + 4]._float,
540 &mach->mem[stack[mach->sp + 5]._addr / 4]._float);
541 mach->sp += 5;
542 break;
543 case slang_asm_jump:
544 mach->ip = a->param[0];
545 break;
546 case slang_asm_jump_if_zero:
547 if (stack[mach->sp]._float == 0.0f)
548 mach->ip = a->param[0];
549 mach->sp++;
550 break;
551 case slang_asm_enter:
552 mach->sp--;
553 stack[mach->sp]._addr = mach->bp;
554 mach->bp = mach->sp + a->param[0] / 4;
555 break;
556 case slang_asm_leave:
557 mach->bp = stack[mach->sp]._addr;
558 mach->sp++;
559 break;
560 case slang_asm_local_alloc:
561 mach->sp -= a->param[0] / 4;
562 break;
563 case slang_asm_local_free:
564 mach->sp += a->param[0] / 4;
565 break;
566 case slang_asm_local_addr:
567 mach->sp--;
568 stack[mach->sp]._addr = SLANG_MACHINE_GLOBAL_SIZE * 4 + mach->bp * 4 -
569 (a->param[0] + a->param[1]) + 4;
570 break;
571 case slang_asm_call:
572 mach->sp--;
573 stack[mach->sp]._addr = mach->ip;
574 mach->ip = a->param[0];
575 break;
576 case slang_asm_return:
577 mach->ip = stack[mach->sp]._addr;
578 mach->sp++;
579 break;
580 case slang_asm_discard:
581 mach->kill = 1;
582 break;
583 case slang_asm_exit:
584 mach->exit = 1;
585 break;
586 /* GL_MESA_shader_debug */
587 case slang_asm_float_print:
588 _mesa_printf ("slang print: %f\n", stack[mach->sp]._float);
589 ensure_infolog_created (&mach->infolog);
590 slang_info_log_print (mach->infolog, "%f", stack[mach->sp]._float);
591 break;
592 case slang_asm_int_print:
593 _mesa_printf ("slang print: %d\n", (GLint) stack[mach->sp]._float);
594 ensure_infolog_created (&mach->infolog);
595 slang_info_log_print (mach->infolog, "%d", (GLint) (stack[mach->sp]._float));
596 break;
597 case slang_asm_bool_print:
598 _mesa_printf ("slang print: %s\n", (GLint) stack[mach->sp]._float ? "true" : "false");
599 ensure_infolog_created (&mach->infolog);
600 slang_info_log_print (mach->infolog, "%s",
601 (GLint) (stack[mach->sp]._float) ? "true" : "false");
602 break;
603 /* vec4 */
604 case slang_asm_float_to_vec4:
605 /* [vec4] | float > [vec4] */
606 {
607 GLuint da = stack[mach->sp + 1]._addr;
608 mach->mem[da / 4]._float = stack[mach->sp]._float;
609 mach->sp++;
610 }
611 break;
612 case slang_asm_vec4_add:
613 /* [vec4] | vec4 > [vec4] */
614 {
615 GLuint da = stack[mach->sp + 4]._addr;
616 mach->mem[da / 4]._float += stack[mach->sp]._float;
617 mach->mem[(da + 4) / 4]._float += stack[mach->sp + 1]._float;
618 mach->mem[(da + 8) / 4]._float += stack[mach->sp + 2]._float;
619 mach->mem[(da + 12) / 4]._float += stack[mach->sp + 3]._float;
620 mach->sp += 4;
621 }
622 break;
623 case slang_asm_vec4_subtract:
624 /* [vec4] | vec4 > [vec4] */
625 {
626 GLuint da = stack[mach->sp + 4]._addr;
627 mach->mem[da / 4]._float -= stack[mach->sp]._float;
628 mach->mem[(da + 4) / 4]._float -= stack[mach->sp + 1]._float;
629 mach->mem[(da + 8) / 4]._float -= stack[mach->sp + 2]._float;
630 mach->mem[(da + 12) / 4]._float -= stack[mach->sp + 3]._float;
631 mach->sp += 4;
632 }
633 break;
634 case slang_asm_vec4_multiply:
635 /* [vec4] | vec4 > [vec4] */
636 {
637 GLuint da = stack[mach->sp + 4]._addr;
638 mach->mem[da / 4]._float *= stack[mach->sp]._float;
639 mach->mem[(da + 4) / 4]._float *= stack[mach->sp + 1]._float;
640 mach->mem[(da + 8) / 4]._float *= stack[mach->sp + 2]._float;
641 mach->mem[(da + 12) / 4]._float *= stack[mach->sp + 3]._float;
642 mach->sp += 4;
643 }
644 break;
645 case slang_asm_vec4_divide:
646 /* [vec4] | vec4 > [vec4] */
647 {
648 GLuint da = stack[mach->sp + 4]._addr;
649 mach->mem[da / 4]._float /= stack[mach->sp]._float;
650 mach->mem[(da + 4) / 4]._float /= stack[mach->sp + 1]._float;
651 mach->mem[(da + 8) / 4]._float /= stack[mach->sp + 2]._float;
652 mach->mem[(da + 12) / 4]._float /= stack[mach->sp + 3]._float;
653 mach->sp += 4;
654 }
655 break;
656 case slang_asm_vec4_negate:
657 /* [vec4] > [vec4] */
658 {
659 GLuint da = stack[mach->sp]._addr;
660 mach->mem[da / 4]._float = -mach->mem[da / 4]._float;
661 mach->mem[(da + 4) / 4]._float = -mach->mem[(da + 4) / 4]._float;
662 mach->mem[(da + 8) / 4]._float = -mach->mem[(da + 8) / 4]._float;
663 mach->mem[(da + 12) / 4]._float = -mach->mem[(da + 12) / 4]._float;
664 }
665 break;
666 case slang_asm_vec4_dot:
667 /* [vec4] | vec4 > [float] */
668 {
669 GLuint da = stack[mach->sp + 4]._addr;
670 mach->mem[da / 4]._float =
671 mach->mem[da / 4]._float * stack[mach->sp]._float +
672 mach->mem[(da + 4) / 4]._float * stack[mach->sp + 1]._float +
673 mach->mem[(da + 8) / 4]._float * stack[mach->sp + 2]._float +
674 mach->mem[(da + 12) / 4]._float * stack[mach->sp + 3]._float;
675 mach->sp += 4;
676 }
677 break;
678 case slang_asm_vec4_copy:
679 /* [vec4] | vec4 > [vec4] */
680 {
681 GLuint da = stack[mach->sp + a->param[0] / 4]._addr + a->param[1];
682 mach->mem[da / 4]._float = stack[mach->sp]._float;
683 mach->mem[(da + 4) / 4]._float = stack[mach->sp + 1]._float;
684 mach->mem[(da + 8) / 4]._float = stack[mach->sp + 2]._float;
685 mach->mem[(da + 12) / 4]._float = stack[mach->sp + 3]._float;
686 mach->sp += 4;
687 }
688 break;
689 case slang_asm_vec4_deref:
690 /* [vec4] > vec4 */
691 {
692 GLuint sa = stack[mach->sp]._addr;
693 mach->sp -= 3;
694 stack[mach->sp]._float = mach->mem[sa / 4]._float;
695 stack[mach->sp + 1]._float = mach->mem[(sa + 4) / 4]._float;
696 stack[mach->sp + 2]._float = mach->mem[(sa + 8) / 4]._float;
697 stack[mach->sp + 3]._float = mach->mem[(sa + 12) / 4]._float;
698 }
699 break;
700 case slang_asm_vec4_equal_int:
701 {
702 GLuint sp0 = mach->sp + a->param[0] / 4;
703 GLuint sp1 = mach->sp + a->param[1] / 4;
704 mach->sp--;
705 if (stack[sp0]._float == stack[sp1]._float &&
706 stack[sp0 + 1]._float == stack[sp1 + 1]._float &&
707 stack[sp0 + 2]._float == stack[sp1 + 2]._float &&
708 stack[sp0 + 3]._float == stack[sp1 + 3]._float) {
709 stack[mach->sp]._float = 1.0f;
710 }
711 else {
712 stack[mach->sp]._float = 0.0f;
713 }
714 }
715 break;
716 default:
717 _mesa_problem(NULL, "bad slang opcode 0x%x", a->type);
718 return GL_FALSE;
719 }
720 }
721
722 #if DEBUG_SLANG
723 if (f != NULL)
724 fclose (f);
725 #endif
726
727 return GL_TRUE;
728 }
729