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_assemble_conditional.c
27 * slang condtional expressions assembler
32 #include "slang_utility.h"
33 #include "slang_assemble_conditional.h"
34 #include "slang_assemble.h"
35 #include "slang_execute.h"
37 /* _slang_assemble_logicaland() */
39 int _slang_assemble_logicaland (slang_assembly_file
*file
, slang_operation
*op
,
40 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
41 slang_assembly_local_info
*info
, slang_machine
*mach
, slang_atom_pool
*atoms
)
54 unsigned int zero_jump
, end_jump
;
55 slang_assembly_stack_info stk
;
57 /* evaluate left expression */
58 if (!_slang_assemble_operation (file
, &op
->children
[0], 0, flow
, space
, info
, &stk
, mach
, atoms
))
60 /* TODO: inspect stk */
62 /* jump to pushing 0 if not true */
63 zero_jump
= file
->count
;
64 if (!slang_assembly_file_push (file
, slang_asm_jump_if_zero
))
67 /* evaluate right expression */
68 if (!_slang_assemble_operation (file
, &op
->children
[1], 0, flow
, space
, info
, &stk
, mach
, atoms
))
70 /* TODO: inspect stk */
72 /* jump to the end of the expression */
73 end_jump
= file
->count
;
74 if (!slang_assembly_file_push (file
, slang_asm_jump
))
78 file
->code
[zero_jump
].param
[0] = file
->count
;
79 if (!slang_assembly_file_push_literal (file
, slang_asm_bool_push
, (GLfloat
) 0))
82 /* the end of the expression */
83 file
->code
[end_jump
].param
[0] = file
->count
;
88 /* _slang_assemble_logicalor() */
90 int _slang_assemble_logicalor (slang_assembly_file
*file
, slang_operation
*op
,
91 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
92 slang_assembly_local_info
*info
, slang_machine
*mach
, slang_atom_pool
*atoms
)
105 unsigned int right_jump
, end_jump
;
106 slang_assembly_stack_info stk
;
108 /* evaluate left expression */
109 if (!_slang_assemble_operation (file
, &op
->children
[0], 0, flow
, space
, info
, &stk
, mach
, atoms
))
111 /* TODO: inspect stk */
113 /* jump to evaluation of right expression if not true */
114 right_jump
= file
->count
;
115 if (!slang_assembly_file_push (file
, slang_asm_jump_if_zero
))
118 /* push 1 on stack */
119 if (!slang_assembly_file_push_literal (file
, slang_asm_bool_push
, (GLfloat
) 1))
122 /* jump to the end of the expression */
123 end_jump
= file
->count
;
124 if (!slang_assembly_file_push (file
, slang_asm_jump
))
127 /* evaluate right expression */
128 file
->code
[right_jump
].param
[0] = file
->count
;
129 if (!_slang_assemble_operation (file
, &op
->children
[1], 0, flow
, space
, info
, &stk
, mach
, atoms
))
131 /* TODO: inspect stk */
133 /* the end of the expression */
134 file
->code
[end_jump
].param
[0] = file
->count
;
139 /* _slang_assemble_select() */
141 int _slang_assemble_select (slang_assembly_file
*file
, slang_operation
*op
,
142 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
143 slang_assembly_local_info
*info
, slang_machine
*mach
, slang_atom_pool
*atoms
)
147 <condition-expression>
156 unsigned int cond_jump
, end_jump
;
157 slang_assembly_stack_info stk
;
159 /* execute condition expression */
160 if (!_slang_assemble_operation (file
, &op
->children
[0], 0, flow
, space
, info
, &stk
, mach
, atoms
))
162 /* TODO: inspect stk */
164 /* jump to false expression if not true */
165 cond_jump
= file
->count
;
166 if (!slang_assembly_file_push (file
, slang_asm_jump_if_zero
))
169 /* execute true expression */
170 if (!_slang_assemble_operation (file
, &op
->children
[1], 0, flow
, space
, info
, &stk
, mach
, atoms
))
172 /* TODO: inspect stk */
174 /* jump to the end of the expression */
175 end_jump
= file
->count
;
176 if (!slang_assembly_file_push (file
, slang_asm_jump
))
179 /* resolve false point */
180 file
->code
[cond_jump
].param
[0] = file
->count
;
182 /* execute false expression */
183 if (!_slang_assemble_operation (file
, &op
->children
[2], 0, flow
, space
, info
, &stk
, mach
, atoms
))
185 /* TODO: inspect stk */
187 /* resolve the end of the expression */
188 file
->code
[end_jump
].param
[0] = file
->count
;
193 /* _slang_assemble_for() */
195 int _slang_assemble_for (slang_assembly_file
*file
, slang_operation
*op
,
196 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
197 slang_assembly_local_info
*info
, slang_machine
*mach
, slang_atom_pool
*atoms
)
208 <condition-statement>
215 unsigned int start_jump
, end_jump
, cond_jump
;
216 unsigned int break_label
, cont_label
;
217 slang_assembly_flow_control loop_flow
= *flow
;
218 slang_assembly_stack_info stk
;
220 /* execute initialization statement */
221 if (!_slang_assemble_operation (file
, &op
->children
[0], 0, flow
, space
, info
, &stk
, mach
, atoms
))
223 /* TODO: pass-in stk to cleanup */
224 if (!_slang_cleanup_stack (file
, &op
->children
[0], 0, space
, mach
, atoms
))
227 /* skip the "go to the end of the loop" and loop-increment statements */
228 start_jump
= file
->count
;
229 if (!slang_assembly_file_push (file
, slang_asm_jump
))
232 /* go to the end of the loop - break statements are directed here */
233 break_label
= file
->count
;
234 end_jump
= file
->count
;
235 if (!slang_assembly_file_push (file
, slang_asm_jump
))
238 /* resolve the beginning of the loop - continue statements are directed here */
239 cont_label
= file
->count
;
241 /* execute loop-increment statement */
242 if (!_slang_assemble_operation (file
, &op
->children
[2], 0, flow
, space
, info
, &stk
, mach
, atoms
))
244 /* TODO: pass-in stk to cleanup */
245 if (!_slang_cleanup_stack (file
, &op
->children
[2], 0, space
, mach
, atoms
))
248 /* resolve the condition point */
249 file
->code
[start_jump
].param
[0] = file
->count
;
251 /* execute condition statement */
252 if (!_slang_assemble_operation (file
, &op
->children
[1], 0, flow
, space
, info
, &stk
, mach
, atoms
))
254 /* TODO: inspect stk */
256 /* jump to the end of the loop if not true */
257 cond_jump
= file
->count
;
258 if (!slang_assembly_file_push (file
, slang_asm_jump_if_zero
))
261 /* execute loop body */
262 loop_flow
.loop_start
= cont_label
;
263 loop_flow
.loop_end
= break_label
;
264 if (!_slang_assemble_operation (file
, &op
->children
[3], 0, &loop_flow
, space
, info
, &stk
, mach
, atoms
))
266 /* TODO: pass-in stk to cleanup */
267 if (!_slang_cleanup_stack (file
, &op
->children
[3], 0, space
, mach
, atoms
))
270 /* go to the beginning of the loop */
271 if (!slang_assembly_file_push_label (file
, slang_asm_jump
, cont_label
))
274 /* resolve the end of the loop */
275 file
->code
[end_jump
].param
[0] = file
->count
;
276 file
->code
[cond_jump
].param
[0] = file
->count
;
281 /* _slang_assemble_do() */
283 int _slang_assemble_do (slang_assembly_file
*file
, slang_operation
*op
,
284 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
285 slang_assembly_local_info
*info
, slang_machine
*mach
, slang_atom_pool
*atoms
)
297 <condition-statement>
303 unsigned int skip_jump
, end_jump
, cont_jump
, cond_jump
;
304 unsigned int break_label
, cont_label
;
305 slang_assembly_flow_control loop_flow
= *flow
;
306 slang_assembly_stack_info stk
;
308 /* skip the "go to the end of the loop" and "go to condition" statements */
309 skip_jump
= file
->count
;
310 if (!slang_assembly_file_push (file
, slang_asm_jump
))
313 /* go to the end of the loop - break statements are directed here */
314 break_label
= file
->count
;
315 end_jump
= file
->count
;
316 if (!slang_assembly_file_push (file
, slang_asm_jump
))
319 /* go to condition - continue statements are directed here */
320 cont_label
= file
->count
;
321 cont_jump
= file
->count
;
322 if (!slang_assembly_file_push (file
, slang_asm_jump
))
325 /* resolve the beginning of the loop */
326 file
->code
[skip_jump
].param
[0] = file
->count
;
328 /* execute loop body */
329 loop_flow
.loop_start
= cont_label
;
330 loop_flow
.loop_end
= break_label
;
331 if (!_slang_assemble_operation (file
, &op
->children
[0], 0, &loop_flow
, space
, info
, &stk
, mach
, atoms
))
333 /* TODO: pass-in stk to cleanup */
334 if (!_slang_cleanup_stack (file
, &op
->children
[0], 0, space
, mach
, atoms
))
337 /* resolve condition point */
338 file
->code
[cont_jump
].param
[0] = file
->count
;
340 /* execute condition statement */
341 if (!_slang_assemble_operation (file
, &op
->children
[1], 0, flow
, space
, info
, &stk
, mach
, atoms
))
343 /* TODO: pass-in stk to cleanup */
345 /* jump to the end of the loop if not true */
346 cond_jump
= file
->count
;
347 if (!slang_assembly_file_push (file
, slang_asm_jump_if_zero
))
350 /* jump to the beginning of the loop */
351 if (!slang_assembly_file_push_label (file
, slang_asm_jump
, file
->code
[skip_jump
].param
[0]))
354 /* resolve the end of the loop */
355 file
->code
[end_jump
].param
[0] = file
->count
;
356 file
->code
[cond_jump
].param
[0] = file
->count
;
361 /* _slang_assemble_while() */
363 int _slang_assemble_while (slang_assembly_file
*file
, slang_operation
*op
,
364 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
365 slang_assembly_local_info
*info
, slang_machine
*mach
, slang_atom_pool
*atoms
)
373 <condition-statement>
380 unsigned int skip_jump
, end_jump
, cond_jump
;
381 unsigned int break_label
;
382 slang_assembly_flow_control loop_flow
= *flow
;
383 slang_assembly_stack_info stk
;
385 /* skip the "go to the end of the loop" statement */
386 skip_jump
= file
->count
;
387 if (!slang_assembly_file_push (file
, slang_asm_jump
))
390 /* go to the end of the loop - break statements are directed here */
391 break_label
= file
->count
;
392 end_jump
= file
->count
;
393 if (!slang_assembly_file_push (file
, slang_asm_jump
))
396 /* resolve the beginning of the loop - continue statements are directed here */
397 file
->code
[skip_jump
].param
[0] = file
->count
;
399 /* execute condition statement */
400 if (!_slang_assemble_operation (file
, &op
->children
[0], 0, flow
, space
, info
, &stk
, mach
, atoms
))
402 /* TODO: pass-in stk to cleanup */
404 /* jump to the end of the loop if not true */
405 cond_jump
= file
->count
;
406 if (!slang_assembly_file_push (file
, slang_asm_jump_if_zero
))
409 /* execute loop body */
410 loop_flow
.loop_start
= file
->code
[skip_jump
].param
[0];
411 loop_flow
.loop_end
= break_label
;
412 if (!_slang_assemble_operation (file
, &op
->children
[1], 0, &loop_flow
, space
, info
, &stk
, mach
, atoms
))
414 /* TODO: pass-in stk to cleanup */
415 if (!_slang_cleanup_stack (file
, &op
->children
[1], 0, space
, mach
, atoms
))
418 /* jump to the beginning of the loop */
419 if (!slang_assembly_file_push_label (file
, slang_asm_jump
, file
->code
[skip_jump
].param
[0]))
422 /* resolve the end of the loop */
423 file
->code
[end_jump
].param
[0] = file
->count
;
424 file
->code
[cond_jump
].param
[0] = file
->count
;
429 /* _slang_assemble_if() */
431 int _slang_assemble_if (slang_assembly_file
*file
, slang_operation
*op
,
432 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
433 slang_assembly_local_info
*info
, slang_machine
*mach
, slang_atom_pool
*atoms
)
437 <condition-statement>
446 unsigned int cond_jump
, else_jump
;
447 slang_assembly_stack_info stk
;
449 /* execute condition statement */
450 if (!_slang_assemble_operation (file
, &op
->children
[0], 0, flow
, space
, info
, &stk
, mach
, atoms
))
452 /* TODO: pass-in stk to cleanup */
454 /* jump to false-statement if not true */
455 cond_jump
= file
->count
;
456 if (!slang_assembly_file_push (file
, slang_asm_jump_if_zero
))
459 /* execute true-statement */
460 if (!_slang_assemble_operation (file
, &op
->children
[1], 0, flow
, space
, info
, &stk
, mach
, atoms
))
462 /* TODO: pass-in stk to cleanup */
463 if (!_slang_cleanup_stack (file
, &op
->children
[1], 0, space
, mach
, atoms
))
466 /* skip if-false statement */
467 else_jump
= file
->count
;
468 if (!slang_assembly_file_push (file
, slang_asm_jump
))
471 /* resolve start of false-statement */
472 file
->code
[cond_jump
].param
[0] = file
->count
;
474 /* execute false-statement */
475 if (!_slang_assemble_operation (file
, &op
->children
[2], 0, flow
, space
, info
, &stk
, mach
, atoms
))
477 /* TODO: pass-in stk to cleanup */
478 if (!_slang_cleanup_stack (file
, &op
->children
[2], 0, space
, mach
, atoms
))
481 /* resolve end of if-false statement */
482 file
->code
[else_jump
].param
[0] = file
->count
;