2 * Mesa 3-D graphics library
5 * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
26 * \file slang_execute.c
27 * intermediate code interpreter
32 #include "slang_compile.h"
33 #include "slang_execute.h"
34 #include "slang_library_noise.h"
35 #include "slang_library_texsample.h"
40 slang_machine_ctr(slang_machine
* self
)
42 slang_machine_init(self
);
44 #if defined(USE_X86_ASM) || defined(SLANG_X86)
45 self
->x86
.compiled_func
= NULL
;
50 slang_machine_dtr(slang_machine
* self
)
52 if (self
->infolog
!= NULL
) {
53 slang_info_log_destruct(self
->infolog
);
54 slang_alloc_free(self
->infolog
);
56 #if defined(USE_X86_ASM) || defined(SLANG_X86)
57 if (self
->x86
.compiled_func
!= NULL
)
58 _mesa_exec_free(self
->x86
.compiled_func
);
64 * Initialize the shader virtual machine.
65 * NOTE: stack grows downward in memory.
68 slang_machine_init(slang_machine
* mach
)
71 mach
->sp
= SLANG_MACHINE_STACK_SIZE
;
73 mach
->kill
= GL_FALSE
;
74 mach
->exit
= GL_FALSE
;
80 dump_instruction(FILE * f
, slang_assembly
* a
, unsigned int i
)
82 fprintf(f
, "%.5u:\t", i
);
89 case slang_asm_float_copy
:
90 fprintf(f
, "float_copy\t%d, %d", a
->param
[0], a
->param
[1]);
92 case slang_asm_float_move
:
93 fprintf(f
, "float_move\t%d, %d", a
->param
[0], a
->param
[1]);
95 case slang_asm_float_push
:
96 fprintf(f
, "float_push\t%f", a
->literal
);
98 case slang_asm_float_deref
:
99 fprintf(f
, "float_deref");
101 case slang_asm_float_add
:
102 fprintf(f
, "float_add");
104 case slang_asm_float_multiply
:
105 fprintf(f
, "float_multiply");
107 case slang_asm_float_divide
:
108 fprintf(f
, "float_divide");
110 case slang_asm_float_negate
:
111 fprintf(f
, "float_negate");
113 case slang_asm_float_less
:
114 fprintf(f
, "float_less");
116 case slang_asm_float_equal_exp
:
117 fprintf(f
, "float_equal");
119 case slang_asm_float_equal_int
:
120 fprintf(f
, "float_equal\t%d, %d", a
->param
[0], a
->param
[1]);
122 case slang_asm_float_to_int
:
123 fprintf(f
, "float_to_int");
125 case slang_asm_float_sine
:
126 fprintf(f
, "float_sine");
128 case slang_asm_float_arcsine
:
129 fprintf(f
, "float_arcsine");
131 case slang_asm_float_arctan
:
132 fprintf(f
, "float_arctan");
134 case slang_asm_float_power
:
135 fprintf(f
, "float_power");
137 case slang_asm_float_log2
:
138 fprintf(f
, "float_log2");
140 case slang_asm_float_floor
:
141 fprintf(f
, "float_floor");
143 case slang_asm_float_ceil
:
144 fprintf(f
, "float_ceil");
146 case slang_asm_float_noise1
:
147 fprintf(f
, "float_noise1");
149 case slang_asm_float_noise2
:
150 fprintf(f
, "float_noise2");
152 case slang_asm_float_noise3
:
153 fprintf(f
, "float_noise3");
155 case slang_asm_float_noise4
:
156 fprintf(f
, "float_noise4");
158 case slang_asm_int_copy
:
159 fprintf(f
, "int_copy\t%d, %d", a
->param
[0], a
->param
[1]);
161 case slang_asm_int_move
:
162 fprintf(f
, "int_move\t%d, %d", a
->param
[0], a
->param
[1]);
164 case slang_asm_int_push
:
165 fprintf(f
, "int_push\t%d", (GLint
) a
->literal
);
167 case slang_asm_int_deref
:
168 fprintf(f
, "int_deref");
170 case slang_asm_int_to_float
:
171 fprintf(f
, "int_to_float");
173 case slang_asm_int_to_addr
:
174 fprintf(f
, "int_to_addr");
176 case slang_asm_bool_copy
:
177 fprintf(f
, "bool_copy\t%d, %d", a
->param
[0], a
->param
[1]);
179 case slang_asm_bool_move
:
180 fprintf(f
, "bool_move\t%d, %d", a
->param
[0], a
->param
[1]);
182 case slang_asm_bool_push
:
183 fprintf(f
, "bool_push\t%d", a
->literal
!= 0.0f
);
185 case slang_asm_bool_deref
:
186 fprintf(f
, "bool_deref");
188 case slang_asm_addr_copy
:
189 fprintf(f
, "addr_copy");
191 case slang_asm_addr_push
:
192 fprintf(f
, "addr_push\t%u", a
->param
[0]);
194 case slang_asm_addr_deref
:
195 fprintf(f
, "addr_deref");
197 case slang_asm_addr_add
:
198 fprintf(f
, "addr_add");
200 case slang_asm_addr_multiply
:
201 fprintf(f
, "addr_multiply");
203 case slang_asm_vec4_tex1d
:
204 fprintf(f
, "vec4_tex1d");
206 case slang_asm_vec4_tex2d
:
207 fprintf(f
, "vec4_tex2d");
209 case slang_asm_vec4_tex3d
:
210 fprintf(f
, "vec4_tex3d");
212 case slang_asm_vec4_texcube
:
213 fprintf(f
, "vec4_texcube");
215 case slang_asm_vec4_shad1d
:
216 fprintf(f
, "vec4_shad1d");
218 case slang_asm_vec4_shad2d
:
219 fprintf(f
, "vec4_shad2d");
222 fprintf(f
, "jump\t%u", a
->param
[0]);
224 case slang_asm_jump_if_zero
:
225 fprintf(f
, "jump_if_zero\t%u", a
->param
[0]);
227 case slang_asm_enter
:
228 fprintf(f
, "enter\t%u", a
->param
[0]);
230 case slang_asm_leave
:
233 case slang_asm_local_alloc
:
234 fprintf(f
, "local_alloc\t%u", a
->param
[0]);
236 case slang_asm_local_free
:
237 fprintf(f
, "local_free\t%u", a
->param
[0]);
239 case slang_asm_local_addr
:
240 fprintf(f
, "local_addr\t%u, %u", a
->param
[0], a
->param
[1]);
242 case slang_asm_global_addr
:
243 fprintf(f
, "global_addr\t%u", a
->param
[0]);
246 fprintf(f
, "call\t%u", a
->param
[0]);
248 case slang_asm_return
:
249 fprintf(f
, "return");
251 case slang_asm_discard
:
252 fprintf(f
, "discard");
257 /* GL_MESA_shader_debug */
258 case slang_asm_float_print
:
259 fprintf(f
, "float_print");
261 case slang_asm_int_print
:
262 fprintf(f
, "int_print");
264 case slang_asm_bool_print
:
265 fprintf(f
, "bool_print");
268 case slang_asm_float_to_vec4
:
269 fprintf(f
, "float_to_vec4");
271 case slang_asm_vec4_add
:
272 fprintf(f
, "vec4_add");
274 case slang_asm_vec4_subtract
:
275 fprintf(f
, "vec4_subtract");
277 case slang_asm_vec4_multiply
:
278 fprintf(f
, "vec4_multiply");
280 case slang_asm_vec4_divide
:
281 fprintf(f
, "vec4_divide");
283 case slang_asm_vec4_negate
:
284 fprintf(f
, "vec4_negate");
286 case slang_asm_vec4_dot
:
287 fprintf(f
, "vec4_dot");
289 case slang_asm_vec4_copy
:
290 fprintf(f
, "vec4_copy");
292 case slang_asm_vec4_deref
:
293 fprintf(f
, "vec4_deref");
295 case slang_asm_vec4_equal_int
:
296 fprintf(f
, "vec4_equal");
306 dump(const slang_assembly_file
* file
)
309 static unsigned int counter
= 0;
314 _mesa_sprintf(filename
, "~mesa-slang-assembly-dump-(%u).txt", counter
);
315 f
= fopen(filename
, "w");
319 for (i
= 0; i
< file
->count
; i
++)
320 dump_instruction(f
, file
->code
+ i
, i
);
328 ensure_infolog_created(slang_info_log
** infolog
)
330 if (*infolog
== NULL
) {
331 *infolog
= slang_alloc_malloc(sizeof(slang_info_log
));
332 if (*infolog
== NULL
)
334 slang_info_log_construct(*infolog
);
339 _slang_execute2(const slang_assembly_file
* file
, slang_machine
* mach
)
341 slang_machine_slot
*stack
;
344 static unsigned int counter
= 0;
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);
356 _mesa_sprintf(filename
, "~mesa-slang-assembly-exec-(%u).txt", counter
);
357 f
= fopen(filename
, "w");
360 #if defined(USE_X86_ASM) || defined(SLANG_X86)
361 if (mach
->x86
.compiled_func
!= NULL
) {
362 mach
->x86
.compiled_func(mach
);
367 stack
= mach
->mem
+ SLANG_MACHINE_GLOBAL_SIZE
;
369 while (!mach
->exit
) {
370 const slang_assembly
*a
= &file
->code
[mach
->ip
];
373 if (f
!= NULL
&& a
->type
!= slang_asm_none
) {
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
,
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 */
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
;
403 mach
->mem
[(stack
[mach
->sp
+ a
->param
[0] / 4]._addr
+a
->param
[1]) / 4]._float
= stack
[mach
->sp
]._float
;
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
=
412 (stack
[mach
->sp
]._addr
+ a
->param
[1]) / 4]._float
;
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 */
419 stack
[mach
->sp
]._float
= a
->literal
;
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
;
427 case slang_asm_float_add
:
428 /* pop two top floats, push sum */
429 stack
[mach
->sp
+ 1]._float
+= stack
[mach
->sp
]._float
;
432 case slang_asm_float_subtract
:
433 stack
[mach
->sp
+ 1]._float
-= stack
[mach
->sp
]._float
;
436 case slang_asm_float_multiply
:
437 stack
[mach
->sp
+ 1]._float
*= stack
[mach
->sp
]._float
;
440 case slang_asm_float_divide
:
441 stack
[mach
->sp
+ 1]._float
/= stack
[mach
->sp
]._float
;
444 case slang_asm_float_negate
:
445 stack
[mach
->sp
]._float
= -stack
[mach
->sp
]._float
;
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;
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;
459 case slang_asm_float_equal_int
:
460 /* pop top two values, compare, push 0 or 1 */
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;
467 case slang_asm_float_to_int
:
468 stack
[mach
->sp
]._float
= (GLfloat
) (GLint
) stack
[mach
->sp
]._float
;
470 case slang_asm_float_sine
:
471 stack
[mach
->sp
]._float
= (GLfloat
) _mesa_sin(stack
[mach
->sp
]._float
);
473 case slang_asm_float_arcsine
:
474 stack
[mach
->sp
]._float
= _mesa_asinf(stack
[mach
->sp
]._float
);
476 case slang_asm_float_arctan
:
477 stack
[mach
->sp
]._float
= _mesa_atanf(stack
[mach
->sp
]._float
);
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
);
484 case slang_asm_float_log2
:
485 stack
[mach
->sp
]._float
= LOG2(stack
[mach
->sp
]._float
);
488 case slang_asm_float_floor
:
489 stack
[mach
->sp
]._float
= FLOORF(stack
[mach
->sp
]._float
);
491 case slang_asm_float_ceil
:
492 stack
[mach
->sp
]._float
= CEILF(stack
[mach
->sp
]._float
);
495 case slang_asm_float_noise1
:
496 stack
[mach
->sp
]._float
=
497 _slang_library_noise1(stack
[mach
->sp
]._float
);
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
);
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
);
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
);
520 case slang_asm_int_to_float
:
522 case slang_asm_int_to_addr
:
523 stack
[mach
->sp
]._addr
= (GLuint
) (GLint
) stack
[mach
->sp
]._float
;
525 case slang_asm_addr_copy
:
526 mach
->mem
[stack
[mach
->sp
+ 1]._addr
/ 4]._addr
=
527 stack
[mach
->sp
]._addr
;
530 case slang_asm_addr_push
:
531 case slang_asm_global_addr
:
533 stack
[mach
->sp
]._addr
= a
->param
[0];
535 case slang_asm_addr_deref
:
536 stack
[mach
->sp
]._addr
= mach
->mem
[stack
[mach
->sp
]._addr
/ 4]._addr
;
538 case slang_asm_addr_add
:
539 stack
[mach
->sp
+ 1]._addr
+= stack
[mach
->sp
]._addr
;
542 case slang_asm_addr_multiply
:
543 stack
[mach
->sp
+ 1]._addr
*= stack
[mach
->sp
]._addr
;
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
/
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
/
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
/
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
/
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
/
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
/
604 mach
->ip
= a
->param
[0];
606 case slang_asm_jump_if_zero
:
607 if (stack
[mach
->sp
]._float
== 0.0f
)
608 mach
->ip
= a
->param
[0];
611 case slang_asm_enter
:
613 stack
[mach
->sp
]._addr
= mach
->bp
;
614 mach
->bp
= mach
->sp
+ a
->param
[0] / 4;
616 case slang_asm_leave
:
617 mach
->bp
= stack
[mach
->sp
]._addr
;
620 case slang_asm_local_alloc
:
621 mach
->sp
-= a
->param
[0] / 4;
623 case slang_asm_local_free
:
624 mach
->sp
+= a
->param
[0] / 4;
626 case slang_asm_local_addr
:
628 stack
[mach
->sp
]._addr
=
629 SLANG_MACHINE_GLOBAL_SIZE
* 4 + mach
->bp
* 4 - (a
->param
[0] +
634 stack
[mach
->sp
]._addr
= mach
->ip
;
635 mach
->ip
= a
->param
[0];
637 case slang_asm_return
:
638 mach
->ip
= stack
[mach
->sp
]._addr
;
641 case slang_asm_discard
:
642 mach
->kill
= GL_TRUE
;
645 mach
->exit
= GL_TRUE
;
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
);
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
));
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");
668 case slang_asm_float_to_vec4
:
669 /* [vec4] | float > [vec4] */
671 GLuint da
= stack
[mach
->sp
+ 1]._addr
;
672 mach
->mem
[da
/ 4]._float
= stack
[mach
->sp
]._float
;
676 case slang_asm_vec4_add
:
677 /* [vec4] | vec4 > [vec4] */
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
;
687 case slang_asm_vec4_subtract
:
688 /* [vec4] | vec4 > [vec4] */
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
;
698 case slang_asm_vec4_multiply
:
699 /* [vec4] | vec4 > [vec4] */
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
;
709 case slang_asm_vec4_divide
:
710 /* [vec4] | vec4 > [vec4] */
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
;
720 case slang_asm_vec4_negate
:
721 /* [vec4] > [vec4] */
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
;
732 case slang_asm_vec4_dot
:
733 /* [vec4] | vec4 > [float] */
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
;
745 case slang_asm_vec4_copy
:
746 /* [vec4] | vec4 > [vec4] */
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
;
756 case slang_asm_vec4_deref
:
759 GLuint sa
= stack
[mach
->sp
]._addr
;
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
;
767 case slang_asm_vec4_equal_int
:
769 GLuint sp0
= mach
->sp
+ a
->param
[0] / 4;
770 GLuint sp1
= mach
->sp
+ a
->param
[1] / 4;
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
;
779 stack
[mach
->sp
]._float
= 0.0f
;
783 case slang_asm_vec4_dot
:
784 case slang_asm_vec3_dot
:
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
;
797 _mesa_problem(NULL
, "bad slang opcode 0x%x", a
->type
);