Get it running for ARB_vertex_shader.
[mesa.git] / src / mesa / shader / slang / slang_assemble_conditional.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_assemble_conditional.c
27 * slang condtional expressions assembler
28 * \author Michal Krol
29 */
30
31 #include "imports.h"
32 #include "slang_utility.h"
33 #include "slang_assemble_conditional.h"
34 #include "slang_assemble.h"
35 #include "slang_execute.h"
36
37 /* _slang_assemble_logicaland() */
38
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)
42 {
43 /*
44 and:
45 <left-expression>
46 jumpz zero
47 <right-expression>
48 jump end
49 zero:
50 push 0
51 end:
52 */
53
54 unsigned int zero_jump, end_jump;
55 slang_assembly_stack_info stk;
56
57 /* evaluate left expression */
58 if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))
59 return 0;
60 /* TODO: inspect stk */
61
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))
65 return 0;
66
67 /* evaluate right expression */
68 if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))
69 return 0;
70 /* TODO: inspect stk */
71
72 /* jump to the end of the expression */
73 end_jump = file->count;
74 if (!slang_assembly_file_push (file, slang_asm_jump))
75 return 0;
76
77 /* push 0 on stack */
78 file->code[zero_jump].param[0] = file->count;
79 if (!slang_assembly_file_push_literal (file, slang_asm_bool_push, (GLfloat) 0))
80 return 0;
81
82 /* the end of the expression */
83 file->code[end_jump].param[0] = file->count;
84
85 return 1;
86 }
87
88 /* _slang_assemble_logicalor() */
89
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)
93 {
94 /*
95 or:
96 <left-expression>
97 jumpz right
98 push 1
99 jump end
100 right:
101 <right-expression>
102 end:
103 */
104
105 unsigned int right_jump, end_jump;
106 slang_assembly_stack_info stk;
107
108 /* evaluate left expression */
109 if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))
110 return 0;
111 /* TODO: inspect stk */
112
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))
116 return 0;
117
118 /* push 1 on stack */
119 if (!slang_assembly_file_push_literal (file, slang_asm_bool_push, (GLfloat) 1))
120 return 0;
121
122 /* jump to the end of the expression */
123 end_jump = file->count;
124 if (!slang_assembly_file_push (file, slang_asm_jump))
125 return 0;
126
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))
130 return 0;
131 /* TODO: inspect stk */
132
133 /* the end of the expression */
134 file->code[end_jump].param[0] = file->count;
135
136 return 1;
137 }
138
139 /* _slang_assemble_select() */
140
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)
144 {
145 /*
146 select:
147 <condition-expression>
148 jumpz false
149 <true-expression>
150 jump end
151 false:
152 <false-expression>
153 end:
154 */
155
156 unsigned int cond_jump, end_jump;
157 slang_assembly_stack_info stk;
158
159 /* execute condition expression */
160 if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))
161 return 0;
162 /* TODO: inspect stk */
163
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))
167 return 0;
168
169 /* execute true expression */
170 if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))
171 return 0;
172 /* TODO: inspect stk */
173
174 /* jump to the end of the expression */
175 end_jump = file->count;
176 if (!slang_assembly_file_push (file, slang_asm_jump))
177 return 0;
178
179 /* resolve false point */
180 file->code[cond_jump].param[0] = file->count;
181
182 /* execute false expression */
183 if (!_slang_assemble_operation (file, &op->children[2], 0, flow, space, info, &stk, mach, atoms))
184 return 0;
185 /* TODO: inspect stk */
186
187 /* resolve the end of the expression */
188 file->code[end_jump].param[0] = file->count;
189
190 return 1;
191 }
192
193 /* _slang_assemble_for() */
194
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)
198 {
199 /*
200 for:
201 <init-statement>
202 jump start
203 break:
204 jump end
205 continue:
206 <loop-increment>
207 start:
208 <condition-statement>
209 jumpz end
210 <loop-body>
211 jump continue
212 end:
213 */
214
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;
219
220 /* execute initialization statement */
221 if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))
222 return 0;
223 /* TODO: pass-in stk to cleanup */
224 if (!_slang_cleanup_stack (file, &op->children[0], 0, space, mach, atoms))
225 return 0;
226
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))
230 return 0;
231
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))
236 return 0;
237
238 /* resolve the beginning of the loop - continue statements are directed here */
239 cont_label = file->count;
240
241 /* execute loop-increment statement */
242 if (!_slang_assemble_operation (file, &op->children[2], 0, flow, space, info, &stk, mach, atoms))
243 return 0;
244 /* TODO: pass-in stk to cleanup */
245 if (!_slang_cleanup_stack (file, &op->children[2], 0, space, mach, atoms))
246 return 0;
247
248 /* resolve the condition point */
249 file->code[start_jump].param[0] = file->count;
250
251 /* execute condition statement */
252 if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))
253 return 0;
254 /* TODO: inspect stk */
255
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))
259 return 0;
260
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))
265 return 0;
266 /* TODO: pass-in stk to cleanup */
267 if (!_slang_cleanup_stack (file, &op->children[3], 0, space, mach, atoms))
268 return 0;
269
270 /* go to the beginning of the loop */
271 if (!slang_assembly_file_push_label (file, slang_asm_jump, cont_label))
272 return 0;
273
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;
277
278 return 1;
279 }
280
281 /* _slang_assemble_do() */
282
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)
286 {
287 /*
288 do:
289 jump start
290 break:
291 jump end
292 continue:
293 jump condition
294 start:
295 <loop-body>
296 condition:
297 <condition-statement>
298 jumpz end
299 jump start
300 end:
301 */
302
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;
307
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))
311 return 0;
312
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))
317 return 0;
318
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))
323 return 0;
324
325 /* resolve the beginning of the loop */
326 file->code[skip_jump].param[0] = file->count;
327
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))
332 return 0;
333 /* TODO: pass-in stk to cleanup */
334 if (!_slang_cleanup_stack (file, &op->children[0], 0, space, mach, atoms))
335 return 0;
336
337 /* resolve condition point */
338 file->code[cont_jump].param[0] = file->count;
339
340 /* execute condition statement */
341 if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))
342 return 0;
343 /* TODO: pass-in stk to cleanup */
344
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))
348 return 0;
349
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]))
352 return 0;
353
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;
357
358 return 1;
359 }
360
361 /* _slang_assemble_while() */
362
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)
366 {
367 /*
368 while:
369 jump continue
370 break:
371 jump end
372 continue:
373 <condition-statement>
374 jumpz end
375 <loop-body>
376 jump continue
377 end:
378 */
379
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;
384
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))
388 return 0;
389
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))
394 return 0;
395
396 /* resolve the beginning of the loop - continue statements are directed here */
397 file->code[skip_jump].param[0] = file->count;
398
399 /* execute condition statement */
400 if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))
401 return 0;
402 /* TODO: pass-in stk to cleanup */
403
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))
407 return 0;
408
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))
413 return 0;
414 /* TODO: pass-in stk to cleanup */
415 if (!_slang_cleanup_stack (file, &op->children[1], 0, space, mach, atoms))
416 return 0;
417
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]))
420 return 0;
421
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;
425
426 return 1;
427 }
428
429 /* _slang_assemble_if() */
430
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)
434 {
435 /*
436 if:
437 <condition-statement>
438 jumpz else
439 <true-statement>
440 jump end
441 else:
442 <false-statement>
443 end:
444 */
445
446 unsigned int cond_jump, else_jump;
447 slang_assembly_stack_info stk;
448
449 /* execute condition statement */
450 if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))
451 return 0;
452 /* TODO: pass-in stk to cleanup */
453
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))
457 return 0;
458
459 /* execute true-statement */
460 if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))
461 return 0;
462 /* TODO: pass-in stk to cleanup */
463 if (!_slang_cleanup_stack (file, &op->children[1], 0, space, mach, atoms))
464 return 0;
465
466 /* skip if-false statement */
467 else_jump = file->count;
468 if (!slang_assembly_file_push (file, slang_asm_jump))
469 return 0;
470
471 /* resolve start of false-statement */
472 file->code[cond_jump].param[0] = file->count;
473
474 /* execute false-statement */
475 if (!_slang_assemble_operation (file, &op->children[2], 0, flow, space, info, &stk, mach, atoms))
476 return 0;
477 /* TODO: pass-in stk to cleanup */
478 if (!_slang_cleanup_stack (file, &op->children[2], 0, space, mach, atoms))
479 return 0;
480
481 /* resolve end of if-false statement */
482 file->code[else_jump].param[0] = file->count;
483
484 return 1;
485 }
486