2 * Mesa 3-D graphics library
5 * Copyright (C) 2005 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_assemble_conditional.c
27 * slang condtional expressions assembler
32 #include "slang_utility.h"
33 #include "slang_assemble_conditional.h"
34 #include "slang_assemble.h"
36 /* _slang_assemble_logicaland() */
38 int _slang_assemble_logicaland (slang_assembly_file
*file
, slang_operation
*op
,
39 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
40 slang_assembly_local_info
*info
)
53 unsigned int zero_jump
, end_jump
;
54 slang_assembly_stack_info stk
;
56 /* evaluate left expression */
57 if (!_slang_assemble_operation (file
, op
->children
, 0, flow
, space
, info
, &stk
))
59 /* TODO: inspect stk */
61 /* jump to pushing 0 if not true */
62 zero_jump
= file
->count
;
63 if (!slang_assembly_file_push (file
, slang_asm_jump_if_zero
))
66 /* evaluate right expression */
67 if (!_slang_assemble_operation (file
, op
->children
+ 1, 0, flow
, space
, info
, &stk
))
69 /* TODO: inspect stk */
71 /* jump to the end of the expression */
72 end_jump
= file
->count
;
73 if (!slang_assembly_file_push (file
, slang_asm_jump
))
77 file
->code
[zero_jump
].param
[0] = file
->count
;
78 if (!slang_assembly_file_push (file
, slang_asm_bool_push
))
81 /* the end of the expression */
82 file
->code
[end_jump
].param
[0] = file
->count
;
87 /* _slang_assemble_logicalor() */
89 int _slang_assemble_logicalor (slang_assembly_file
*file
, slang_operation
*op
,
90 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
91 slang_assembly_local_info
*info
)
104 unsigned int right_jump
, end_jump
;
105 slang_assembly_stack_info stk
;
107 /* evaluate left expression */
108 if (!_slang_assemble_operation (file
, op
->children
, 0, flow
, space
, info
, &stk
))
110 /* TODO: inspect stk */
112 /* jump to evaluation of right expression if not true */
113 right_jump
= file
->count
;
114 if (!slang_assembly_file_push (file
, slang_asm_jump_if_zero
))
117 /* push 1 on stack */
118 if (!slang_assembly_file_push_literal (file
, slang_asm_bool_push
, 1.0f
))
121 /* jump to the end of the expression */
122 end_jump
= file
->count
;
123 if (!slang_assembly_file_push (file
, slang_asm_jump
))
126 /* evaluate right expression */
127 file
->code
[right_jump
].param
[0] = file
->count
;
128 if (!_slang_assemble_operation (file
, op
->children
+ 1, 0, flow
, space
, info
, &stk
))
130 /* TODO: inspect stk */
132 /* the end of the expression */
133 file
->code
[end_jump
].param
[0] = file
->count
;
138 /* _slang_assemble_select() */
140 int _slang_assemble_select (slang_assembly_file
*file
, slang_operation
*op
,
141 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
142 slang_assembly_local_info
*info
)
146 <condition-expression>
155 unsigned int cond_jump
, end_jump
;
156 slang_assembly_stack_info stk
;
158 /* execute condition expression */
159 if (!_slang_assemble_operation (file
, op
->children
, 0, flow
, space
, info
, &stk
))
161 /* TODO: inspect stk */
163 /* jump to false expression if not true */
164 cond_jump
= file
->count
;
165 if (!slang_assembly_file_push (file
, slang_asm_jump_if_zero
))
168 /* execute true expression */
169 if (!_slang_assemble_operation (file
, op
->children
+ 1, 0, flow
, space
, info
, &stk
))
171 /* TODO: inspect stk */
173 /* jump to the end of the expression */
174 end_jump
= file
->count
;
175 if (!slang_assembly_file_push (file
, slang_asm_jump
))
178 /* resolve false point */
179 file
->code
[cond_jump
].param
[0] = file
->count
;
181 /* execute false expression */
182 if (!_slang_assemble_operation (file
, op
->children
+ 2, 0, flow
, space
, info
, &stk
))
184 /* TODO: inspect stk */
186 /* resolve the end of the expression */
187 file
->code
[end_jump
].param
[0] = file
->count
;
192 /* _slang_assemble_for() */
194 int _slang_assemble_for (slang_assembly_file
*file
, slang_operation
*op
,
195 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
196 slang_assembly_local_info
*info
)
207 <condition-statement>
214 unsigned int start_jump
, end_jump
, cond_jump
;
215 unsigned int break_label
, cont_label
;
216 slang_assembly_flow_control loop_flow
= *flow
;
217 slang_assembly_stack_info stk
;
219 /* execute initialization statement */
220 if (!_slang_assemble_operation (file
, op
->children
, 0, flow
, space
, info
, &stk
))
222 /* TODO: pass-in stk to cleanup */
223 if (!_slang_cleanup_stack (file
, op
->children
, 0, space
))
226 /* skip the "go to the end of the loop" and loop-increment statements */
227 start_jump
= file
->count
;
228 if (!slang_assembly_file_push (file
, slang_asm_jump
))
231 /* go to the end of the loop - break statements are directed here */
232 break_label
= file
->count
;
233 end_jump
= file
->count
;
234 if (!slang_assembly_file_push (file
, slang_asm_jump
))
237 /* resolve the beginning of the loop - continue statements are directed here */
238 cont_label
= file
->count
;
240 /* execute loop-increment statement */
241 if (!_slang_assemble_operation (file
, op
->children
+ 2, 0, flow
, space
, info
, &stk
))
243 /* TODO: pass-in stk to cleanup */
244 if (!_slang_cleanup_stack (file
, op
->children
+ 2, 0, space
))
247 /* resolve the condition point */
248 file
->code
[start_jump
].param
[0] = file
->count
;
250 /* execute condition statement */
251 if (!_slang_assemble_operation (file
, op
->children
+ 1, 0, flow
, space
, info
, &stk
))
253 /* TODO: inspect stk */
255 /* jump to the end of the loop if not true */
256 cond_jump
= file
->count
;
257 if (!slang_assembly_file_push (file
, slang_asm_jump_if_zero
))
260 /* execute loop body */
261 loop_flow
.loop_start
= cont_label
;
262 loop_flow
.loop_end
= break_label
;
263 if (!_slang_assemble_operation (file
, op
->children
+ 3, 0, &loop_flow
, space
, info
, &stk
))
265 /* TODO: pass-in stk to cleanup */
266 if (!_slang_cleanup_stack (file
, op
->children
+ 3, 0, space
))
269 /* go to the beginning of the loop */
270 if (!slang_assembly_file_push_label (file
, slang_asm_jump
, cont_label
))
273 /* resolve the end of the loop */
274 file
->code
[end_jump
].param
[0] = file
->count
;
275 file
->code
[cond_jump
].param
[0] = file
->count
;
280 /* _slang_assemble_do() */
282 int _slang_assemble_do (slang_assembly_file
*file
, slang_operation
*op
,
283 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
284 slang_assembly_local_info
*info
)
296 <condition-statement>
302 unsigned int skip_jump
, end_jump
, cont_jump
, cond_jump
;
303 unsigned int break_label
, cont_label
;
304 slang_assembly_flow_control loop_flow
= *flow
;
305 slang_assembly_stack_info stk
;
307 /* skip the "go to the end of the loop" and "go to condition" statements */
308 skip_jump
= file
->count
;
309 if (!slang_assembly_file_push (file
, slang_asm_jump
))
312 /* go to the end of the loop - break statements are directed here */
313 break_label
= file
->count
;
314 end_jump
= file
->count
;
315 if (!slang_assembly_file_push (file
, slang_asm_jump
))
318 /* go to condition - continue statements are directed here */
319 cont_label
= file
->count
;
320 cont_jump
= file
->count
;
321 if (!slang_assembly_file_push (file
, slang_asm_jump
))
324 /* resolve the beginning of the loop */
325 file
->code
[skip_jump
].param
[0] = file
->count
;
327 /* execute loop body */
328 loop_flow
.loop_start
= cont_label
;
329 loop_flow
.loop_end
= break_label
;
330 if (!_slang_assemble_operation (file
, op
->children
, 0, &loop_flow
, space
, info
, &stk
))
332 /* TODO: pass-in stk to cleanup */
333 if (!_slang_cleanup_stack (file
, op
->children
, 0, space
))
336 /* resolve condition point */
337 file
->code
[cont_jump
].param
[0] = file
->count
;
339 /* execute condition statement */
340 if (!_slang_assemble_operation (file
, op
->children
+ 1, 0, flow
, space
, info
, &stk
))
342 /* TODO: pass-in stk to cleanup */
344 /* jump to the end of the loop if not true */
345 cond_jump
= file
->count
;
346 if (!slang_assembly_file_push (file
, slang_asm_jump_if_zero
))
349 /* jump to the beginning of the loop */
350 if (!slang_assembly_file_push_label (file
, slang_asm_jump
, file
->code
[skip_jump
].param
[0]))
353 /* resolve the end of the loop */
354 file
->code
[end_jump
].param
[0] = file
->count
;
355 file
->code
[cond_jump
].param
[0] = file
->count
;
360 /* _slang_assemble_while() */
362 int _slang_assemble_while (slang_assembly_file
*file
, slang_operation
*op
,
363 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
364 slang_assembly_local_info
*info
)
372 <condition-statement>
379 unsigned int skip_jump
, end_jump
, cond_jump
;
380 unsigned int break_label
;
381 slang_assembly_flow_control loop_flow
= *flow
;
382 slang_assembly_stack_info stk
;
384 /* skip the "go to the end of the loop" statement */
385 skip_jump
= file
->count
;
386 if (!slang_assembly_file_push (file
, slang_asm_jump
))
389 /* go to the end of the loop - break statements are directed here */
390 break_label
= file
->count
;
391 end_jump
= file
->count
;
392 if (!slang_assembly_file_push (file
, slang_asm_jump
))
395 /* resolve the beginning of the loop - continue statements are directed here */
396 file
->code
[skip_jump
].param
[0] = file
->count
;
398 /* execute condition statement */
399 if (!_slang_assemble_operation (file
, op
->children
, 0, flow
, space
, info
, &stk
))
401 /* TODO: pass-in stk to cleanup */
403 /* jump to the end of the loop if not true */
404 cond_jump
= file
->count
;
405 if (!slang_assembly_file_push (file
, slang_asm_jump_if_zero
))
408 /* execute loop body */
409 loop_flow
.loop_start
= file
->code
[skip_jump
].param
[0];
410 loop_flow
.loop_end
= break_label
;
411 if (!_slang_assemble_operation (file
, op
->children
+ 1, 0, &loop_flow
, space
, info
, &stk
))
413 /* TODO: pass-in stk to cleanup */
414 if (!_slang_cleanup_stack (file
, op
->children
+ 1, 0, space
))
417 /* jump to the beginning of the loop */
418 if (!slang_assembly_file_push_label (file
, slang_asm_jump
, file
->code
[skip_jump
].param
[0]))
421 /* resolve the end of the loop */
422 file
->code
[end_jump
].param
[0] = file
->count
;
423 file
->code
[cond_jump
].param
[0] = file
->count
;
428 /* _slang_assemble_if() */
430 int _slang_assemble_if (slang_assembly_file
*file
, slang_operation
*op
,
431 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
432 slang_assembly_local_info
*info
)
436 <condition-statement>
445 unsigned int cond_jump
, else_jump
;
446 slang_assembly_stack_info stk
;
448 /* execute condition statement */
449 if (!_slang_assemble_operation (file
, op
->children
, 0, flow
, space
, info
, &stk
))
451 /* TODO: pass-in stk to cleanup */
453 /* jump to false-statement if not true */
454 cond_jump
= file
->count
;
455 if (!slang_assembly_file_push (file
, slang_asm_jump_if_zero
))
458 /* execute true-statement */
459 if (!_slang_assemble_operation (file
, op
->children
+ 1, 0, flow
, space
, info
, &stk
))
461 /* TODO: pass-in stk to cleanup */
462 if (!_slang_cleanup_stack (file
, op
->children
+ 1, 0, space
))
465 /* skip if-false statement */
466 else_jump
= file
->count
;
467 if (!slang_assembly_file_push (file
, slang_asm_jump
))
470 /* resolve start of false-statement */
471 file
->code
[cond_jump
].param
[0] = file
->count
;
473 /* execute false-statement */
474 if (!_slang_assemble_operation (file
, op
->children
+ 2, 0, flow
, space
, info
, &stk
))
476 /* TODO: pass-in stk to cleanup */
477 if (!_slang_cleanup_stack (file
, op
->children
+ 2, 0, space
))
480 /* resolve end of if-false statement */
481 file
->code
[else_jump
].param
[0] = file
->count
;