chmod a-x
[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
40 slang_machine_ctr(slang_machine * self)
41 {
42 slang_machine_init(self);
43 self->infolog = NULL;
44 #if defined(USE_X86_ASM) || defined(SLANG_X86)
45 self->x86.compiled_func = NULL;
46 #endif
47 }
48
49 GLvoid
50 slang_machine_dtr(slang_machine * self)
51 {
52 if (self->infolog != NULL) {
53 slang_info_log_destruct(self->infolog);
54 slang_alloc_free(self->infolog);
55 }
56 #if defined(USE_X86_ASM) || defined(SLANG_X86)
57 if (self->x86.compiled_func != NULL)
58 _mesa_exec_free(self->x86.compiled_func);
59 #endif
60 }
61
62
63 /**
64 * Initialize the shader virtual machine.
65 * NOTE: stack grows downward in memory.
66 */
67 void
68 slang_machine_init(slang_machine * mach)
69 {
70 mach->ip = 0;
71 mach->sp = SLANG_MACHINE_STACK_SIZE;
72 mach->bp = 0;
73 mach->kill = GL_FALSE;
74 mach->exit = GL_FALSE;
75 }
76
77 #if DEBUG_SLANG
78
79 static void
80 dump_instruction(FILE * f, slang_assembly * a, unsigned int i)
81 {
82 fprintf(f, "%.5u:\t", i);
83
84 switch (a->type) {
85 /* core */
86 case slang_asm_none:
87 fprintf(f, "none");
88 break;
89 case slang_asm_float_copy:
90 fprintf(f, "float_copy\t%d, %d", a->param[0], a->param[1]);
91 break;
92 case slang_asm_float_move:
93 fprintf(f, "float_move\t%d, %d", a->param[0], a->param[1]);
94 break;
95 case slang_asm_float_push:
96 fprintf(f, "float_push\t%f", a->literal);
97 break;
98 case slang_asm_float_deref:
99 fprintf(f, "float_deref");
100 break;
101 case slang_asm_float_add:
102 fprintf(f, "float_add");
103 break;
104 case slang_asm_float_multiply:
105 fprintf(f, "float_multiply");
106 break;
107 case slang_asm_float_divide:
108 fprintf(f, "float_divide");
109 break;
110 case slang_asm_float_negate:
111 fprintf(f, "float_negate");
112 break;
113 case slang_asm_float_less:
114 fprintf(f, "float_less");
115 break;
116 case slang_asm_float_equal_exp:
117 fprintf(f, "float_equal");
118 break;
119 case slang_asm_float_equal_int:
120 fprintf(f, "float_equal\t%d, %d", a->param[0], a->param[1]);
121 break;
122 case slang_asm_float_to_int:
123 fprintf(f, "float_to_int");
124 break;
125 case slang_asm_float_sine:
126 fprintf(f, "float_sine");
127 break;
128 case slang_asm_float_arcsine:
129 fprintf(f, "float_arcsine");
130 break;
131 case slang_asm_float_arctan:
132 fprintf(f, "float_arctan");
133 break;
134 case slang_asm_float_power:
135 fprintf(f, "float_power");
136 break;
137 case slang_asm_float_log2:
138 fprintf(f, "float_log2");
139 break;
140 case slang_asm_float_floor:
141 fprintf(f, "float_floor");
142 break;
143 case slang_asm_float_ceil:
144 fprintf(f, "float_ceil");
145 break;
146 case slang_asm_float_noise1:
147 fprintf(f, "float_noise1");
148 break;
149 case slang_asm_float_noise2:
150 fprintf(f, "float_noise2");
151 break;
152 case slang_asm_float_noise3:
153 fprintf(f, "float_noise3");
154 break;
155 case slang_asm_float_noise4:
156 fprintf(f, "float_noise4");
157 break;
158 case slang_asm_int_copy:
159 fprintf(f, "int_copy\t%d, %d", a->param[0], a->param[1]);
160 break;
161 case slang_asm_int_move:
162 fprintf(f, "int_move\t%d, %d", a->param[0], a->param[1]);
163 break;
164 case slang_asm_int_push:
165 fprintf(f, "int_push\t%d", (GLint) a->literal);
166 break;
167 case slang_asm_int_deref:
168 fprintf(f, "int_deref");
169 break;
170 case slang_asm_int_to_float:
171 fprintf(f, "int_to_float");
172 break;
173 case slang_asm_int_to_addr:
174 fprintf(f, "int_to_addr");
175 break;
176 case slang_asm_bool_copy:
177 fprintf(f, "bool_copy\t%d, %d", a->param[0], a->param[1]);
178 break;
179 case slang_asm_bool_move:
180 fprintf(f, "bool_move\t%d, %d", a->param[0], a->param[1]);
181 break;
182 case slang_asm_bool_push:
183 fprintf(f, "bool_push\t%d", a->literal != 0.0f);
184 break;
185 case slang_asm_bool_deref:
186 fprintf(f, "bool_deref");
187 break;
188 case slang_asm_addr_copy:
189 fprintf(f, "addr_copy");
190 break;
191 case slang_asm_addr_push:
192 fprintf(f, "addr_push\t%u", a->param[0]);
193 break;
194 case slang_asm_addr_deref:
195 fprintf(f, "addr_deref");
196 break;
197 case slang_asm_addr_add:
198 fprintf(f, "addr_add");
199 break;
200 case slang_asm_addr_multiply:
201 fprintf(f, "addr_multiply");
202 break;
203 case slang_asm_vec4_tex1d:
204 fprintf(f, "vec4_tex1d");
205 break;
206 case slang_asm_vec4_tex2d:
207 fprintf(f, "vec4_tex2d");
208 break;
209 case slang_asm_vec4_tex3d:
210 fprintf(f, "vec4_tex3d");
211 break;
212 case slang_asm_vec4_texcube:
213 fprintf(f, "vec4_texcube");
214 break;
215 case slang_asm_vec4_shad1d:
216 fprintf(f, "vec4_shad1d");
217 break;
218 case slang_asm_vec4_shad2d:
219 fprintf(f, "vec4_shad2d");
220 break;
221 case slang_asm_jump:
222 fprintf(f, "jump\t%u", a->param[0]);
223 break;
224 case slang_asm_jump_if_zero:
225 fprintf(f, "jump_if_zero\t%u", a->param[0]);
226 break;
227 case slang_asm_enter:
228 fprintf(f, "enter\t%u", a->param[0]);
229 break;
230 case slang_asm_leave:
231 fprintf(f, "leave");
232 break;
233 case slang_asm_local_alloc:
234 fprintf(f, "local_alloc\t%u", a->param[0]);
235 break;
236 case slang_asm_local_free:
237 fprintf(f, "local_free\t%u", a->param[0]);
238 break;
239 case slang_asm_local_addr:
240 fprintf(f, "local_addr\t%u, %u", a->param[0], a->param[1]);
241 break;
242 case slang_asm_global_addr:
243 fprintf(f, "global_addr\t%u", a->param[0]);
244 break;
245 case slang_asm_call:
246 fprintf(f, "call\t%u", a->param[0]);
247 break;
248 case slang_asm_return:
249 fprintf(f, "return");
250 break;
251 case slang_asm_discard:
252 fprintf(f, "discard");
253 break;
254 case slang_asm_exit:
255 fprintf(f, "exit");
256 break;
257 /* GL_MESA_shader_debug */
258 case slang_asm_float_print:
259 fprintf(f, "float_print");
260 break;
261 case slang_asm_int_print:
262 fprintf(f, "int_print");
263 break;
264 case slang_asm_bool_print:
265 fprintf(f, "bool_print");
266 break;
267 /* vec4 */
268 case slang_asm_float_to_vec4:
269 fprintf(f, "float_to_vec4");
270 break;
271 case slang_asm_vec4_add:
272 fprintf(f, "vec4_add");
273 break;
274 case slang_asm_vec4_subtract:
275 fprintf(f, "vec4_subtract");
276 break;
277 case slang_asm_vec4_multiply:
278 fprintf(f, "vec4_multiply");
279 break;
280 case slang_asm_vec4_divide:
281 fprintf(f, "vec4_divide");
282 break;
283 case slang_asm_vec4_negate:
284 fprintf(f, "vec4_negate");
285 break;
286 case slang_asm_vec4_dot:
287 fprintf(f, "vec4_dot");
288 break;
289 case slang_asm_vec4_copy:
290 fprintf(f, "vec4_copy");
291 break;
292 case slang_asm_vec4_deref:
293 fprintf(f, "vec4_deref");
294 break;
295 case slang_asm_vec4_equal_int:
296 fprintf(f, "vec4_equal");
297 break;
298 default:
299 break;
300 }
301
302 fprintf(f, "\n");
303 }
304
305 static void
306 dump(const slang_assembly_file * file)
307 {
308 unsigned int i;
309 static unsigned int counter = 0;
310 FILE *f;
311 char filename[256];
312
313 counter++;
314 _mesa_sprintf(filename, "~mesa-slang-assembly-dump-(%u).txt", counter);
315 f = fopen(filename, "w");
316 if (f == NULL)
317 return;
318
319 for (i = 0; i < file->count; i++)
320 dump_instruction(f, file->code + i, i);
321
322 fclose(f);
323 }
324
325 #endif
326
327 static GLvoid
328 ensure_infolog_created(slang_info_log ** infolog)
329 {
330 if (*infolog == NULL) {
331 *infolog = slang_alloc_malloc(sizeof(slang_info_log));
332 if (*infolog == NULL)
333 return;
334 slang_info_log_construct(*infolog);
335 }
336 }
337
338 GLboolean
339 _slang_execute2(const slang_assembly_file * file, slang_machine * mach)
340 {
341 slang_machine_slot *stack;
342
343 #if DEBUG_SLANG
344 static unsigned int counter = 0;
345 char filename[256];
346 FILE *f;
347 #endif
348
349 /* assume 32-bit floats and uints; should work fine also on 64-bit platforms */
350 static_assert(sizeof(GLfloat) == 4);
351 static_assert(sizeof(GLuint) == 4);
352
353 #if DEBUG_SLANG
354 dump(file);
355 counter++;
356 _mesa_sprintf(filename, "~mesa-slang-assembly-exec-(%u).txt", counter);
357 f = fopen(filename, "w");
358 #endif
359
360 #if defined(USE_X86_ASM) || defined(SLANG_X86)
361 if (mach->x86.compiled_func != NULL) {
362 mach->x86.compiled_func(mach);
363 return GL_TRUE;
364 }
365 #endif
366
367 stack = mach->mem + SLANG_MACHINE_GLOBAL_SIZE;
368
369 while (!mach->exit) {
370 const slang_assembly *a = &file->code[mach->ip];
371
372 #if DEBUG_SLANG
373 if (f != NULL && a->type != slang_asm_none) {
374 unsigned int i;
375
376 dump_instruction(f, file->code + mach->ip, mach->ip);
377 fprintf(f, "\t\tsp=%u bp=%u\n", mach->sp, mach->bp);
378 for (i = mach->sp; i < SLANG_MACHINE_STACK_SIZE; i++)
379 fprintf(f, "\t%.5u\t%6f\t%u\n", i, stack[i]._float,
380 stack[i]._addr);
381 fflush(f);
382 }
383 #endif
384
385 mach->ip++;
386
387 switch (a->type) {
388 /* core */
389 case slang_asm_none:
390 break;
391 case slang_asm_float_copy:
392 case slang_asm_int_copy:
393 case slang_asm_bool_copy:
394 /* store top value on stack to memory */
395 #if 0
396 {
397 GLuint address
398 = (stack[mach->sp + a->param[0] / 4]._addr + a->param[1]) / 4;
399 GLfloat value = stack[mach->sp]._float;
400 mach->mem[address]._float = value;
401 }
402 #else
403 mach->mem[(stack[mach->sp + a->param[0] / 4]._addr +a->param[1]) / 4]._float = stack[mach->sp]._float;
404 #endif
405 mach->sp++;
406 break;
407 case slang_asm_float_move:
408 case slang_asm_int_move:
409 case slang_asm_bool_move:
410 stack[mach->sp + a->param[0] / 4]._float =
411 stack[mach->sp +
412 (stack[mach->sp]._addr + a->param[1]) / 4]._float;
413 break;
414 case slang_asm_float_push:
415 case slang_asm_int_push:
416 case slang_asm_bool_push:
417 /* push float/int/bool literal onto stop of stack */
418 mach->sp--;
419 stack[mach->sp]._float = a->literal;
420 break;
421 case slang_asm_float_deref:
422 case slang_asm_int_deref:
423 case slang_asm_bool_deref:
424 /* load value from memory, replace stop of stack with it */
425 stack[mach->sp]._float = mach->mem[stack[mach->sp]._addr / 4]._float;
426 break;
427 case slang_asm_float_add:
428 /* pop two top floats, push sum */
429 stack[mach->sp + 1]._float += stack[mach->sp]._float;
430 mach->sp++;
431 break;
432 case slang_asm_float_subtract:
433 stack[mach->sp + 1]._float -= stack[mach->sp]._float;
434 mach->sp++;
435 break;
436 case slang_asm_float_multiply:
437 stack[mach->sp + 1]._float *= stack[mach->sp]._float;
438 mach->sp++;
439 break;
440 case slang_asm_float_divide:
441 stack[mach->sp + 1]._float /= stack[mach->sp]._float;
442 mach->sp++;
443 break;
444 case slang_asm_float_negate:
445 stack[mach->sp]._float = -stack[mach->sp]._float;
446 break;
447 case slang_asm_float_less:
448 stack[mach->sp + 1]._float =
449 (stack[mach->sp + 1]._float < stack[mach->sp]._float)
450 ? (GLfloat) 1 : (GLfloat) 0;
451 mach->sp++;
452 break;
453 case slang_asm_float_equal_exp:
454 stack[mach->sp + 1]._float =
455 (stack[mach->sp + 1]._float == stack[mach->sp]._float)
456 ? (GLfloat) 1 : (GLfloat) 0;
457 mach->sp++;
458 break;
459 case slang_asm_float_equal_int:
460 /* pop top two values, compare, push 0 or 1 */
461 mach->sp--;
462 stack[mach->sp]._float =
463 (stack[mach->sp + 1 + a->param[0] / 4]._float ==
464 stack[mach->sp + 1 + a->param[1] / 4]._float)
465 ? (GLfloat) 1 : (GLfloat) 0;
466 break;
467 case slang_asm_float_to_int:
468 stack[mach->sp]._float = (GLfloat) (GLint) stack[mach->sp]._float;
469 break;
470 case slang_asm_float_sine:
471 stack[mach->sp]._float = (GLfloat) _mesa_sin(stack[mach->sp]._float);
472 break;
473 case slang_asm_float_arcsine:
474 stack[mach->sp]._float = _mesa_asinf(stack[mach->sp]._float);
475 break;
476 case slang_asm_float_arctan:
477 stack[mach->sp]._float = _mesa_atanf(stack[mach->sp]._float);
478 break;
479 case slang_asm_float_power:
480 stack[mach->sp + 1]._float = (GLfloat)
481 _mesa_pow(stack[mach->sp + 1]._float, stack[mach->sp]._float);
482 mach->sp++;
483 break;
484 case slang_asm_float_log2:
485 stack[mach->sp]._float = LOG2(stack[mach->sp]._float);
486 break;
487 #if 0
488 case slang_asm_float_floor:
489 stack[mach->sp]._float = FLOORF(stack[mach->sp]._float);
490 break;
491 case slang_asm_float_ceil:
492 stack[mach->sp]._float = CEILF(stack[mach->sp]._float);
493 break;
494 #endif
495 case slang_asm_float_noise1:
496 stack[mach->sp]._float =
497 _slang_library_noise1(stack[mach->sp]._float);
498 break;
499 case slang_asm_float_noise2:
500 stack[mach->sp + 1]._float =
501 _slang_library_noise2(stack[mach->sp]._float,
502 stack[mach->sp + 1]._float);
503 mach->sp++;
504 break;
505 case slang_asm_float_noise3:
506 stack[mach->sp + 2]._float =
507 _slang_library_noise3(stack[mach->sp]._float,
508 stack[mach->sp + 1]._float,
509 stack[mach->sp + 2]._float);
510 mach->sp += 2;
511 break;
512 case slang_asm_float_noise4:
513 stack[mach->sp + 3]._float =
514 _slang_library_noise4(stack[mach->sp]._float,
515 stack[mach->sp + 1]._float,
516 stack[mach->sp + 2]._float,
517 stack[mach->sp + 3]._float);
518 mach->sp += 3;
519 break;
520 case slang_asm_int_to_float:
521 break;
522 case slang_asm_int_to_addr:
523 stack[mach->sp]._addr = (GLuint) (GLint) stack[mach->sp]._float;
524 break;
525 case slang_asm_addr_copy:
526 mach->mem[stack[mach->sp + 1]._addr / 4]._addr =
527 stack[mach->sp]._addr;
528 mach->sp++;
529 break;
530 case slang_asm_addr_push:
531 case slang_asm_global_addr:
532 mach->sp--;
533 stack[mach->sp]._addr = a->param[0];
534 break;
535 case slang_asm_addr_deref:
536 stack[mach->sp]._addr = mach->mem[stack[mach->sp]._addr / 4]._addr;
537 break;
538 case slang_asm_addr_add:
539 stack[mach->sp + 1]._addr += stack[mach->sp]._addr;
540 mach->sp++;
541 break;
542 case slang_asm_addr_multiply:
543 stack[mach->sp + 1]._addr *= stack[mach->sp]._addr;
544 mach->sp++;
545 break;
546 case slang_asm_vec4_tex1d:
547 _slang_library_tex1d(stack[mach->sp]._float,
548 stack[mach->sp + 1]._float,
549 stack[mach->sp + 2]._float,
550 &mach->mem[stack[mach->sp + 3]._addr /
551 4]._float);
552 mach->sp += 3;
553 break;
554 case slang_asm_vec4_tex2d:
555 _slang_library_tex2d(stack[mach->sp]._float,
556 stack[mach->sp + 1]._float,
557 stack[mach->sp + 2]._float,
558 stack[mach->sp + 3]._float,
559 &mach->mem[stack[mach->sp + 4]._addr /
560 4]._float);
561 mach->sp += 4;
562 break;
563 case slang_asm_vec4_tex3d:
564 _slang_library_tex3d(stack[mach->sp]._float,
565 stack[mach->sp + 1]._float,
566 stack[mach->sp + 2]._float,
567 stack[mach->sp + 3]._float,
568 stack[mach->sp + 4]._float,
569 &mach->mem[stack[mach->sp + 5]._addr /
570 4]._float);
571 mach->sp += 5;
572 break;
573 case slang_asm_vec4_texcube:
574 _slang_library_texcube(stack[mach->sp]._float,
575 stack[mach->sp + 1]._float,
576 stack[mach->sp + 2]._float,
577 stack[mach->sp + 3]._float,
578 stack[mach->sp + 4]._float,
579 &mach->mem[stack[mach->sp + 5]._addr /
580 4]._float);
581 mach->sp += 5;
582 break;
583 case slang_asm_vec4_shad1d:
584 _slang_library_shad1d(stack[mach->sp]._float,
585 stack[mach->sp + 1]._float,
586 stack[mach->sp + 2]._float,
587 stack[mach->sp + 3]._float,
588 stack[mach->sp + 4]._float,
589 &mach->mem[stack[mach->sp + 5]._addr /
590 4]._float);
591 mach->sp += 5;
592 break;
593 case slang_asm_vec4_shad2d:
594 _slang_library_shad2d(stack[mach->sp]._float,
595 stack[mach->sp + 1]._float,
596 stack[mach->sp + 2]._float,
597 stack[mach->sp + 3]._float,
598 stack[mach->sp + 4]._float,
599 &mach->mem[stack[mach->sp + 5]._addr /
600 4]._float);
601 mach->sp += 5;
602 break;
603 case slang_asm_jump:
604 mach->ip = a->param[0];
605 break;
606 case slang_asm_jump_if_zero:
607 if (stack[mach->sp]._float == 0.0f)
608 mach->ip = a->param[0];
609 mach->sp++;
610 break;
611 case slang_asm_enter:
612 mach->sp--;
613 stack[mach->sp]._addr = mach->bp;
614 mach->bp = mach->sp + a->param[0] / 4;
615 break;
616 case slang_asm_leave:
617 mach->bp = stack[mach->sp]._addr;
618 mach->sp++;
619 break;
620 case slang_asm_local_alloc:
621 mach->sp -= a->param[0] / 4;
622 break;
623 case slang_asm_local_free:
624 mach->sp += a->param[0] / 4;
625 break;
626 case slang_asm_local_addr:
627 mach->sp--;
628 stack[mach->sp]._addr =
629 SLANG_MACHINE_GLOBAL_SIZE * 4 + mach->bp * 4 - (a->param[0] +
630 a->param[1]) + 4;
631 break;
632 case slang_asm_call:
633 mach->sp--;
634 stack[mach->sp]._addr = mach->ip;
635 mach->ip = a->param[0];
636 break;
637 case slang_asm_return:
638 mach->ip = stack[mach->sp]._addr;
639 mach->sp++;
640 break;
641 case slang_asm_discard:
642 mach->kill = GL_TRUE;
643 break;
644 case slang_asm_exit:
645 mach->exit = GL_TRUE;
646 break;
647 /* GL_MESA_shader_debug */
648 case slang_asm_float_print:
649 _mesa_printf("slang print: %f\n", stack[mach->sp]._float);
650 ensure_infolog_created(&mach->infolog);
651 slang_info_log_print(mach->infolog, "%f", stack[mach->sp]._float);
652 break;
653 case slang_asm_int_print:
654 _mesa_printf("slang print: %d\n", (GLint) stack[mach->sp]._float);
655 ensure_infolog_created(&mach->infolog);
656 slang_info_log_print(mach->infolog, "%d",
657 (GLint) (stack[mach->sp]._float));
658 break;
659 case slang_asm_bool_print:
660 _mesa_printf("slang print: %s\n",
661 (GLint) stack[mach->sp]._float ? "true" : "false");
662 ensure_infolog_created(&mach->infolog);
663 slang_info_log_print(mach->infolog, "%s",
664 (GLint) (stack[mach->sp].
665 _float) ? "true" : "false");
666 break;
667 /* vec4 */
668 case slang_asm_float_to_vec4:
669 /* [vec4] | float > [vec4] */
670 {
671 GLuint da = stack[mach->sp + 1]._addr;
672 mach->mem[da / 4]._float = stack[mach->sp]._float;
673 mach->sp++;
674 }
675 break;
676 case slang_asm_vec4_add:
677 /* [vec4] | vec4 > [vec4] */
678 {
679 GLuint da = stack[mach->sp + 4]._addr;
680 mach->mem[da / 4]._float += stack[mach->sp]._float;
681 mach->mem[(da + 4) / 4]._float += stack[mach->sp + 1]._float;
682 mach->mem[(da + 8) / 4]._float += stack[mach->sp + 2]._float;
683 mach->mem[(da + 12) / 4]._float += stack[mach->sp + 3]._float;
684 mach->sp += 4;
685 }
686 break;
687 case slang_asm_vec4_subtract:
688 /* [vec4] | vec4 > [vec4] */
689 {
690 GLuint da = stack[mach->sp + 4]._addr;
691 mach->mem[da / 4]._float -= stack[mach->sp]._float;
692 mach->mem[(da + 4) / 4]._float -= stack[mach->sp + 1]._float;
693 mach->mem[(da + 8) / 4]._float -= stack[mach->sp + 2]._float;
694 mach->mem[(da + 12) / 4]._float -= stack[mach->sp + 3]._float;
695 mach->sp += 4;
696 }
697 break;
698 case slang_asm_vec4_multiply:
699 /* [vec4] | vec4 > [vec4] */
700 {
701 GLuint da = stack[mach->sp + 4]._addr;
702 mach->mem[da / 4]._float *= stack[mach->sp]._float;
703 mach->mem[(da + 4) / 4]._float *= stack[mach->sp + 1]._float;
704 mach->mem[(da + 8) / 4]._float *= stack[mach->sp + 2]._float;
705 mach->mem[(da + 12) / 4]._float *= stack[mach->sp + 3]._float;
706 mach->sp += 4;
707 }
708 break;
709 case slang_asm_vec4_divide:
710 /* [vec4] | vec4 > [vec4] */
711 {
712 GLuint da = stack[mach->sp + 4]._addr;
713 mach->mem[da / 4]._float /= stack[mach->sp]._float;
714 mach->mem[(da + 4) / 4]._float /= stack[mach->sp + 1]._float;
715 mach->mem[(da + 8) / 4]._float /= stack[mach->sp + 2]._float;
716 mach->mem[(da + 12) / 4]._float /= stack[mach->sp + 3]._float;
717 mach->sp += 4;
718 }
719 break;
720 case slang_asm_vec4_negate:
721 /* [vec4] > [vec4] */
722 {
723 GLuint da = stack[mach->sp]._addr;
724 mach->mem[da / 4]._float = -mach->mem[da / 4]._float;
725 mach->mem[(da + 4) / 4]._float = -mach->mem[(da + 4) / 4]._float;
726 mach->mem[(da + 8) / 4]._float = -mach->mem[(da + 8) / 4]._float;
727 mach->mem[(da + 12) / 4]._float =
728 -mach->mem[(da + 12) / 4]._float;
729 }
730 break;
731 #if 0
732 case slang_asm_vec4_dot:
733 /* [vec4] | vec4 > [float] */
734 {
735 GLuint da = stack[mach->sp + 4]._addr;
736 mach->mem[da / 4]._float =
737 mach->mem[da / 4]._float * stack[mach->sp]._float +
738 mach->mem[(da + 4) / 4]._float * stack[mach->sp + 1]._float +
739 mach->mem[(da + 8) / 4]._float * stack[mach->sp + 2]._float +
740 mach->mem[(da + 12) / 4]._float * stack[mach->sp + 3]._float;
741 mach->sp += 4;
742 }
743 break;
744 #endif
745 case slang_asm_vec4_copy:
746 /* [vec4] | vec4 > [vec4] */
747 {
748 GLuint da = stack[mach->sp + a->param[0] / 4]._addr + a->param[1];
749 mach->mem[da / 4]._float = stack[mach->sp]._float;
750 mach->mem[(da + 4) / 4]._float = stack[mach->sp + 1]._float;
751 mach->mem[(da + 8) / 4]._float = stack[mach->sp + 2]._float;
752 mach->mem[(da + 12) / 4]._float = stack[mach->sp + 3]._float;
753 mach->sp += 4;
754 }
755 break;
756 case slang_asm_vec4_deref:
757 /* [vec4] > vec4 */
758 {
759 GLuint sa = stack[mach->sp]._addr;
760 mach->sp -= 3;
761 stack[mach->sp]._float = mach->mem[sa / 4]._float;
762 stack[mach->sp + 1]._float = mach->mem[(sa + 4) / 4]._float;
763 stack[mach->sp + 2]._float = mach->mem[(sa + 8) / 4]._float;
764 stack[mach->sp + 3]._float = mach->mem[(sa + 12) / 4]._float;
765 }
766 break;
767 case slang_asm_vec4_equal_int:
768 {
769 GLuint sp0 = mach->sp + a->param[0] / 4;
770 GLuint sp1 = mach->sp + a->param[1] / 4;
771 mach->sp--;
772 if (stack[sp0]._float == stack[sp1]._float &&
773 stack[sp0 + 1]._float == stack[sp1 + 1]._float &&
774 stack[sp0 + 2]._float == stack[sp1 + 2]._float &&
775 stack[sp0 + 3]._float == stack[sp1 + 3]._float) {
776 stack[mach->sp]._float = 1.0f;
777 }
778 else {
779 stack[mach->sp]._float = 0.0f;
780 }
781 }
782 break;
783 case slang_asm_vec4_dot:
784 case slang_asm_vec3_dot:
785 {
786 /* XXX almost certainly wrong */
787 GLuint da = stack[mach->sp + 4]._addr;
788 mach->mem[da / 4]._float =
789 mach->mem[da / 4]._float * stack[mach->sp]._float +
790 mach->mem[(da + 4) / 4]._float * stack[mach->sp + 1]._float +
791 mach->mem[(da + 8) / 4]._float * stack[mach->sp + 2]._float +
792 mach->mem[(da + 12) / 4]._float * stack[mach->sp + 3]._float;
793 mach->sp += 4;
794 }
795 break;
796 default:
797 _mesa_problem(NULL, "bad slang opcode 0x%x", a->type);
798 return GL_FALSE;
799 }
800 }
801
802 #if DEBUG_SLANG
803 if (f != NULL)
804 fclose(f);
805 #endif
806
807 return GL_TRUE;
808 }