134
145
/* slang_assembly_file_restore_point */
136
GLboolean slang_assembly_file_restore_point_save (slang_assembly_file *file,
137
slang_assembly_file_restore_point *point)
148
slang_assembly_file_restore_point_save(slang_assembly_file * file,
149
slang_assembly_file_restore_point *
139
point->count = file->count;
152
point->count = file->count;
143
GLboolean slang_assembly_file_restore_point_load (slang_assembly_file *file,
144
slang_assembly_file_restore_point *point)
157
slang_assembly_file_restore_point_load(slang_assembly_file * file,
158
slang_assembly_file_restore_point *
148
for (i = point->count; i < file->count; i++)
149
slang_assembly_destruct (&file->code[i]);
150
file->count = point->count;
163
for (i = point->count; i < file->count; i++)
164
slang_assembly_destruct(&file->code[i]);
165
file->count = point->count;
154
169
/* utility functions */
156
static GLboolean sizeof_variable (slang_assemble_ctx *A, slang_type_specifier *spec,
157
slang_type_qualifier qual, GLuint array_len, GLuint *size)
159
slang_storage_aggregate agg;
161
/* calculate the size of the variable's aggregate */
162
if (!slang_storage_aggregate_construct (&agg))
164
if (!_slang_aggregate_variable (&agg, spec, array_len, A->space.funcs, A->space.structs,
165
A->space.vars, A->mach, A->file, A->atoms))
167
slang_storage_aggregate_destruct (&agg);
170
*size += _slang_sizeof_aggregate (&agg);
171
slang_storage_aggregate_destruct (&agg);
173
/* for reference variables consider the additional address overhead */
174
if (qual == slang_qual_out || qual == slang_qual_inout)
180
static GLboolean sizeof_variable2 (slang_assemble_ctx *A, slang_variable *var, GLuint *size)
182
var->address = *size;
183
if (var->type.qualifier == slang_qual_out || var->type.qualifier == slang_qual_inout)
185
return sizeof_variable (A, &var->type.specifier, var->type.qualifier, var->array_len, size);
188
static GLboolean sizeof_variables (slang_assemble_ctx *A, slang_variable_scope *vars, GLuint start,
189
GLuint stop, GLuint *size)
193
for (i = start; i < stop; i++)
194
if (!sizeof_variable2 (A, &vars->variables[i], size))
199
static GLboolean collect_locals (slang_assemble_ctx *A, slang_operation *op, GLuint *size)
203
if (!sizeof_variables (A, op->locals, 0, op->locals->num_variables, size))
205
for (i = 0; i < op->num_children; i++)
206
if (!collect_locals (A, &op->children[i], size))
172
sizeof_variable(slang_assemble_ctx * A, slang_type_specifier * spec,
173
slang_type_qualifier qual, GLuint array_len, GLuint * size)
175
slang_storage_aggregate agg;
177
/* calculate the size of the variable's aggregate */
178
if (!slang_storage_aggregate_construct(&agg))
180
if (!_slang_aggregate_variable
181
(&agg, spec, array_len, A->space.funcs, A->space.structs,
182
A->space.vars, A->mach, A->file, A->atoms)) {
183
slang_storage_aggregate_destruct(&agg);
186
*size += _slang_sizeof_aggregate(&agg);
187
slang_storage_aggregate_destruct(&agg);
189
/* for reference variables consider the additional address overhead */
190
if (qual == slang_qual_out || qual == slang_qual_inout)
197
sizeof_variable2(slang_assemble_ctx * A, slang_variable * var, GLuint * size)
199
var->address = *size;
200
if (var->type.qualifier == slang_qual_out
201
|| var->type.qualifier == slang_qual_inout)
203
return sizeof_variable(A, &var->type.specifier, var->type.qualifier,
204
var->array_len, size);
208
sizeof_variables(slang_assemble_ctx * A, slang_variable_scope * vars,
209
GLuint start, GLuint stop, GLuint * size)
213
for (i = start; i < stop; i++)
214
if (!sizeof_variable2(A, &vars->variables[i], size))
220
collect_locals(slang_assemble_ctx * A, slang_operation * op, GLuint * size)
224
if (!sizeof_variables(A, op->locals, 0, op->locals->num_variables, size))
226
for (i = 0; i < op->num_children; i++)
227
if (!collect_locals(A, &op->children[i], size))
211
232
/* _slang_locate_function() */
213
slang_function *_slang_locate_function (slang_function_scope *funcs, slang_atom a_name,
214
slang_operation *params, GLuint num_params, slang_assembly_name_space *space,
215
slang_atom_pool *atoms)
235
_slang_locate_function(const slang_function_scope * funcs, slang_atom a_name,
236
const slang_operation * params, GLuint num_params,
237
const slang_assembly_name_space * space,
238
slang_atom_pool * atoms)
219
for (i = 0; i < funcs->num_functions; i++)
222
slang_function *f = &funcs->functions[i];
224
if (a_name != f->header.a_name)
226
if (f->param_count != num_params)
228
for (j = 0; j < num_params; j++)
230
slang_assembly_typeinfo ti;
232
if (!slang_assembly_typeinfo_construct (&ti))
234
if (!_slang_typeof_operation_ (¶ms[j], space, &ti, atoms))
236
slang_assembly_typeinfo_destruct (&ti);
239
if (!slang_type_specifier_equal (&ti.spec, &f->parameters->variables[j].type.specifier))
241
slang_assembly_typeinfo_destruct (&ti);
244
slang_assembly_typeinfo_destruct (&ti);
246
/* "out" and "inout" formal parameter requires the actual parameter to be l-value */
247
if (!ti.can_be_referenced &&
248
(f->parameters->variables[j].type.qualifier == slang_qual_out ||
249
f->parameters->variables[j].type.qualifier == slang_qual_inout))
255
if (funcs->outer_scope != NULL)
256
return _slang_locate_function (funcs->outer_scope, a_name, params, num_params, space, atoms);
242
for (i = 0; i < funcs->num_functions; i++) {
244
slang_function *f = &funcs->functions[i];
246
if (a_name != f->header.a_name)
248
if (f->param_count != num_params)
250
for (j = 0; j < num_params; j++) {
251
slang_assembly_typeinfo ti;
253
if (!slang_assembly_typeinfo_construct(&ti))
255
if (!_slang_typeof_operation_(¶ms[j], space, &ti, atoms)) {
256
slang_assembly_typeinfo_destruct(&ti);
259
if (!slang_type_specifier_equal
260
(&ti.spec, &f->parameters->variables[j].type.specifier)) {
261
slang_assembly_typeinfo_destruct(&ti);
264
slang_assembly_typeinfo_destruct(&ti);
266
/* "out" and "inout" formal parameter requires the actual parameter to be l-value */
267
if (!ti.can_be_referenced &&
268
(f->parameters->variables[j].type.qualifier == slang_qual_out ||
269
f->parameters->variables[j].type.qualifier == slang_qual_inout))
275
if (funcs->outer_scope != NULL)
276
return _slang_locate_function(funcs->outer_scope, a_name, params,
277
num_params, space, atoms);
260
281
/* _slang_assemble_function() */
262
GLboolean _slang_assemble_function (slang_assemble_ctx *A, slang_function *fun)
284
_slang_assemble_function(slang_assemble_ctx * A, slang_function * fun)
264
GLuint param_size, local_size;
265
GLuint skip, cleanup;
267
fun->address = A->file->count;
269
if (fun->body == NULL)
271
/* jump to the actual function body - we do not know it, so add the instruction
273
fun->fixups.table = (GLuint *) slang_alloc_realloc (fun->fixups.table,
274
fun->fixups.count * sizeof (GLuint), (fun->fixups.count + 1) * sizeof (GLuint));
275
if (fun->fixups.table == NULL)
277
fun->fixups.table[fun->fixups.count] = fun->address;
279
if (!PUSH (A->file, slang_asm_jump))
287
/* resolve all fixup table entries and delete it */
288
for (i = 0; i < fun->fixups.count; i++)
289
A->file->code[fun->fixups.table[i]].param[0] = fun->address;
290
slang_fixup_table_free (&fun->fixups);
293
/* At this point traverse function formal parameters and code to calculate
294
* total memory size to be allocated on the stack.
295
* During this process the variables will be assigned local addresses to
296
* reference them in the code.
297
* No storage optimizations are performed so exclusive scopes are not detected and shared. */
299
/* calculate return value size */
301
if (fun->header.type.specifier.type != slang_spec_void)
302
if (!sizeof_variable (A, &fun->header.type.specifier, slang_qual_none, 0, ¶m_size))
304
A->local.ret_size = param_size;
306
/* calculate formal parameter list size */
307
if (!sizeof_variables (A, fun->parameters, 0, fun->param_count, ¶m_size))
310
/* calculate local variables size - take into account the four-byte return address and
311
* temporaries for various tasks (4 for addr and 16 for swizzle temporaries).
312
* these include variables from the formal parameter scope and from the code */
313
A->local.addr_tmp = param_size + 4;
314
A->local.swizzle_tmp = param_size + 4 + 4;
315
local_size = param_size + 4 + 4 + 16;
316
if (!sizeof_variables (A, fun->parameters, fun->param_count, fun->parameters->num_variables,
319
if (!collect_locals (A, fun->body, &local_size))
322
/* allocate local variable storage */
323
if (!PLAB (A->file, slang_asm_local_alloc, local_size - param_size - 4))
326
/* mark a new frame for function variable storage */
327
if (!PLAB (A->file, slang_asm_enter, local_size))
330
/* jump directly to the actual code */
331
skip = A->file->count;
332
if (!push_new (A->file))
334
A->file->code[skip].type = slang_asm_jump;
336
/* all "return" statements will be directed here */
337
A->flow.function_end = A->file->count;
338
cleanup = A->file->count;
339
if (!push_new (A->file))
341
A->file->code[cleanup].type = slang_asm_jump;
343
/* execute the function body */
344
A->file->code[skip].param[0] = A->file->count;
345
if (!_slang_assemble_operation (A, fun->body, /*slang_ref_freelance*/slang_ref_forbid))
348
/* this is the end of the function - restore the old function frame */
349
A->file->code[cleanup].param[0] = A->file->count;
350
if (!PUSH (A->file, slang_asm_leave))
353
/* free local variable storage */
354
if (!PLAB (A->file, slang_asm_local_free, local_size - param_size - 4))
357
/* return from the function */
358
if (!PUSH (A->file, slang_asm_return))
286
GLuint param_size, local_size;
287
GLuint skip, cleanup;
289
fun->address = A->file->count;
291
if (fun->body == NULL) {
292
/* jump to the actual function body - we do not know it, so add
293
* the instruction to fixup table
295
if (!slang_fixup_save(&fun->fixups, fun->address))
297
if (!PUSH(A->file, slang_asm_jump))
302
/* resolve all fixup table entries and delete it */
304
for (i = 0; i < fun->fixups.count; i++)
305
A->file->code[fun->fixups.table[i]].param[0] = fun->address;
306
slang_fixup_table_free(&fun->fixups);
309
/* At this point traverse function formal parameters and code to calculate
310
* total memory size to be allocated on the stack.
311
* During this process the variables will be assigned local addresses to
312
* reference them in the code.
313
* No storage optimizations are performed so exclusive scopes are not
314
* detected and shared.
317
/* calculate return value size */
319
if (fun->header.type.specifier.type != slang_spec_void)
321
(A, &fun->header.type.specifier, slang_qual_none, 0, ¶m_size))
323
A->local.ret_size = param_size;
325
/* calculate formal parameter list size */
326
if (!sizeof_variables
327
(A, fun->parameters, 0, fun->param_count, ¶m_size))
330
/* calculate local variables size - take into account the four-byte
331
* return address and temporaries for various tasks (4 for addr and
332
* 16 for swizzle temporaries). these include variables from the
333
* formal parameter scope and from the code
335
A->local.addr_tmp = param_size + 4;
336
A->local.swizzle_tmp = param_size + 4 + 4;
337
local_size = param_size + 4 + 4 + 16;
338
if (!sizeof_variables
339
(A, fun->parameters, fun->param_count, fun->parameters->num_variables,
342
if (!collect_locals(A, fun->body, &local_size))
345
/* allocate local variable storage */
346
if (!PLAB(A->file, slang_asm_local_alloc, local_size - param_size - 4))
349
/* mark a new frame for function variable storage */
350
if (!PLAB(A->file, slang_asm_enter, local_size))
353
/* jump directly to the actual code */
354
skip = A->file->count;
355
if (!push_new(A->file))
357
A->file->code[skip].type = slang_asm_jump;
359
/* all "return" statements will be directed here */
360
A->flow.function_end = A->file->count;
361
cleanup = A->file->count;
362
if (!push_new(A->file))
364
A->file->code[cleanup].type = slang_asm_jump;
366
/* execute the function body */
367
A->file->code[skip].param[0] = A->file->count;
368
if (!_slang_assemble_operation
369
(A, fun->body, /*slang_ref_freelance */ slang_ref_forbid))
372
/* this is the end of the function - restore the old function frame */
373
A->file->code[cleanup].param[0] = A->file->count;
374
if (!PUSH(A->file, slang_asm_leave))
377
/* free local variable storage */
378
if (!PLAB(A->file, slang_asm_local_free, local_size - param_size - 4))
381
/* return from the function */
382
if (!PUSH(A->file, slang_asm_return))
364
GLboolean _slang_cleanup_stack (slang_assemble_ctx *A, slang_operation *op)
389
_slang_cleanup_stack(slang_assemble_ctx * A, slang_operation * op)
366
slang_assembly_typeinfo ti;
369
/* get type info of the operation and calculate its size */
370
if (!slang_assembly_typeinfo_construct (&ti))
372
if (!_slang_typeof_operation (A, op, &ti))
374
slang_assembly_typeinfo_destruct (&ti);
377
if (ti.spec.type != slang_spec_void) {
378
if (A->ref == slang_ref_force) {
381
else if (!sizeof_variable (A, &ti.spec, slang_qual_none, 0, &size))
383
slang_assembly_typeinfo_destruct (&ti);
387
slang_assembly_typeinfo_destruct (&ti);
389
/* if nonzero, free it from the stack */
392
if (!PLAB (A->file, slang_asm_local_free, size))
391
slang_assembly_typeinfo ti;
394
/* get type info of the operation and calculate its size */
395
if (!slang_assembly_typeinfo_construct(&ti))
397
if (!_slang_typeof_operation(A, op, &ti)) {
398
slang_assembly_typeinfo_destruct(&ti);
401
if (ti.spec.type != slang_spec_void) {
402
if (A->ref == slang_ref_force) {
405
else if (!sizeof_variable(A, &ti.spec, slang_qual_none, 0, &size)) {
406
slang_assembly_typeinfo_destruct(&ti);
410
slang_assembly_typeinfo_destruct(&ti);
412
/* if nonzero, free it from the stack */
414
if (!PLAB(A->file, slang_asm_local_free, size))
399
421
/* _slang_assemble_operation() */
402
dereference_basic (slang_assemble_ctx *A, slang_storage_type type, GLuint *size, slang_swizzle *swz,
403
GLboolean is_swizzled)
424
dereference_basic(slang_assemble_ctx * A, slang_storage_type type,
425
GLuint * size, slang_swizzle * swz, GLboolean is_swizzled)
405
427
GLuint src_offset;
406
428
slang_assembly_type ty;
408
*size -= _slang_sizeof_type (type);
430
*size -= _slang_sizeof_type(type);
410
/* If swizzling is taking place, we are forced to use scalar operations, even if we have
411
* vec4 instructions enabled (this should be actually done with special vec4 shuffle
413
* Adjust the size and calculate the offset within source variable to read.
432
/* If swizzling is taking place, we are forced to use scalar
433
* operations, even if we have vec4 instructions enabled (this
434
* should be actually done with special vec4 shuffle instructions).
435
* Adjust the size and calculate the offset within source variable
416
439
src_offset = swz->swizzle[*size / 4] * 4;
492
GLboolean _slang_dereference (slang_assemble_ctx *A, slang_operation *op)
494
slang_assembly_typeinfo ti;
495
GLboolean result = GL_FALSE;
496
slang_storage_aggregate agg;
499
/* get type information of the given operation */
500
if (!slang_assembly_typeinfo_construct (&ti))
502
if (!_slang_typeof_operation (A, op, &ti))
505
/* construct aggregate from the type info */
506
if (!slang_storage_aggregate_construct (&agg))
508
if (!_slang_aggregate_variable (&agg, &ti.spec, ti.array_len, A->space.funcs, A->space.structs,
509
A->space.vars, A->mach, A->file, A->atoms))
512
/* dereference the resulting aggregate */
513
size = _slang_sizeof_aggregate (&agg);
514
result = dereference_aggregate (A, &agg, &size, &ti.swz, ti.is_swizzled);
517
slang_storage_aggregate_destruct (&agg);
519
slang_assembly_typeinfo_destruct (&ti);
523
GLboolean _slang_assemble_function_call (slang_assemble_ctx *A, slang_function *fun,
524
slang_operation *params, GLuint param_count, GLboolean assignment)
527
slang_swizzle p_swz[64];
528
slang_ref_type p_ref[64];
530
/* TODO: fix this, allocate dynamically */
531
if (param_count > 64)
534
/* make room for the return value, if any */
535
if (fun->header.type.specifier.type != slang_spec_void)
539
if (!sizeof_variable (A, &fun->header.type.specifier, slang_qual_none, 0, &ret_size))
541
if (!PLAB (A->file, slang_asm_local_alloc, ret_size))
545
/* push the actual parameters on the stack */
546
for (i = 0; i < param_count; i++)
548
if (fun->parameters->variables[i].type.qualifier == slang_qual_inout ||
549
fun->parameters->variables[i].type.qualifier == slang_qual_out)
551
if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
553
/* TODO: optimize the "out" parameter case */
554
if (!_slang_assemble_operation (A, ¶ms[i], slang_ref_force))
558
if (!PUSH (A->file, slang_asm_addr_copy))
560
if (!PUSH (A->file, slang_asm_addr_deref))
562
if (i == 0 && assignment)
564
/* duplicate the resulting address */
565
if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
567
if (!PUSH (A->file, slang_asm_addr_deref))
570
if (!_slang_dereference (A, ¶ms[i]))
575
if (!_slang_assemble_operation (A, ¶ms[i], slang_ref_forbid))
582
/* call the function */
583
if (!PLAB (A->file, slang_asm_call, fun->address))
586
/* pop the parameters from the stack */
587
for (i = param_count; i > 0; i--)
593
if (fun->parameters->variables[j].type.qualifier == slang_qual_inout ||
594
fun->parameters->variables[j].type.qualifier == slang_qual_out)
596
/* for output parameter copy the contents of the formal parameter
597
* back to the original actual parameter */
598
if (!_slang_assemble_assignment (A, ¶ms[j]))
600
/* pop the actual parameter's address */
601
if (!PLAB (A->file, slang_asm_local_free, 4))
606
/* pop the value of the parameter */
607
if (!_slang_cleanup_stack (A, ¶ms[j]))
615
GLboolean _slang_assemble_function_call_name (slang_assemble_ctx *A, const char *name,
616
slang_operation *params, GLuint param_count, GLboolean assignment)
621
atom = slang_atom_pool_atom (A->atoms, name);
622
if (atom == SLANG_ATOM_NULL)
624
fun = _slang_locate_function (A->space.funcs, atom, params, param_count, &A->space, A->atoms);
627
return _slang_assemble_function_call (A, fun, params, param_count, assignment);
630
static GLboolean assemble_function_call_name_dummyint (slang_assemble_ctx *A, const char *name,
631
slang_operation *params)
633
slang_operation p[2];
637
if (!slang_operation_construct (&p[1]))
639
p[1].type = slang_oper_literal_int;
640
result = _slang_assemble_function_call_name (A, name, p, 2, GL_FALSE);
641
slang_operation_destruct (&p[1]);
522
_slang_dereference(slang_assemble_ctx * A, slang_operation * op)
524
slang_assembly_typeinfo ti;
525
GLboolean result = GL_FALSE;
526
slang_storage_aggregate agg;
529
/* get type information of the given operation */
530
if (!slang_assembly_typeinfo_construct(&ti))
532
if (!_slang_typeof_operation(A, op, &ti))
535
/* construct aggregate from the type info */
536
if (!slang_storage_aggregate_construct(&agg))
538
if (!_slang_aggregate_variable
539
(&agg, &ti.spec, ti.array_len, A->space.funcs, A->space.structs,
540
A->space.vars, A->mach, A->file, A->atoms))
543
/* dereference the resulting aggregate */
544
size = _slang_sizeof_aggregate(&agg);
545
result = dereference_aggregate(A, &agg, &size, &ti.swz, ti.is_swizzled);
548
slang_storage_aggregate_destruct(&agg);
550
slang_assembly_typeinfo_destruct(&ti);
555
_slang_assemble_function_call(slang_assemble_ctx * A, slang_function * fun,
556
slang_operation * params, GLuint param_count,
557
GLboolean assignment)
560
slang_swizzle p_swz[64];
561
slang_ref_type p_ref[64];
563
/* TODO: fix this, allocate dynamically */
564
if (param_count > 64)
567
/* make room for the return value, if any */
568
if (fun->header.type.specifier.type != slang_spec_void) {
572
(A, &fun->header.type.specifier, slang_qual_none, 0, &ret_size))
574
if (!PLAB(A->file, slang_asm_local_alloc, ret_size))
578
/* push the actual parameters on the stack */
579
for (i = 0; i < param_count; i++) {
580
if (fun->parameters->variables[i].type.qualifier == slang_qual_inout ||
581
fun->parameters->variables[i].type.qualifier == slang_qual_out) {
582
if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
584
/* TODO: optimize the "out" parameter case */
585
if (!_slang_assemble_operation(A, ¶ms[i], slang_ref_force))
589
if (!PUSH(A->file, slang_asm_addr_copy))
591
if (!PUSH(A->file, slang_asm_addr_deref))
593
if (i == 0 && assignment) {
594
/* duplicate the resulting address */
595
if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
597
if (!PUSH(A->file, slang_asm_addr_deref))
600
if (!_slang_dereference(A, ¶ms[i]))
604
if (!_slang_assemble_operation(A, ¶ms[i], slang_ref_forbid))
611
/* call the function */
612
if (!PLAB(A->file, slang_asm_call, fun->address))
615
/* pop the parameters from the stack */
616
for (i = param_count; i > 0; i--) {
621
if (fun->parameters->variables[j].type.qualifier == slang_qual_inout ||
622
fun->parameters->variables[j].type.qualifier == slang_qual_out) {
623
/* for output parameter copy the contents of the formal parameter
624
* back to the original actual parameter
626
if (!_slang_assemble_assignment(A, ¶ms[j]))
628
/* pop the actual parameter's address */
629
if (!PLAB(A->file, slang_asm_local_free, 4))
633
/* pop the value of the parameter */
634
if (!_slang_cleanup_stack(A, ¶ms[j]))
643
_slang_assemble_function_call_name(slang_assemble_ctx * A, const char *name,
644
slang_operation * params,
645
GLuint param_count, GLboolean assignment)
650
atom = slang_atom_pool_atom(A->atoms, name);
651
if (atom == SLANG_ATOM_NULL)
654
_slang_locate_function(A->space.funcs, atom, params, param_count,
655
&A->space, A->atoms);
658
return _slang_assemble_function_call(A, fun, params, param_count,
663
assemble_function_call_name_dummyint(slang_assemble_ctx * A, const char *name,
664
slang_operation * params)
666
slang_operation p[2];
670
if (!slang_operation_construct(&p[1]))
672
p[1].type = slang_oper_literal_int;
673
result = _slang_assemble_function_call_name(A, name, p, 2, GL_FALSE);
674
slang_operation_destruct(&p[1]);
645
678
static const struct
648
slang_assembly_type code1, code2;
681
slang_assembly_type code1, code2;
651
{ "float_add", slang_asm_float_add, slang_asm_float_copy },
652
{ "float_multiply", slang_asm_float_multiply, slang_asm_float_copy },
653
{ "float_divide", slang_asm_float_divide, slang_asm_float_copy },
654
{ "float_negate", slang_asm_float_negate, slang_asm_float_copy },
655
{ "float_less", slang_asm_float_less, slang_asm_bool_copy },
656
{ "float_equal", slang_asm_float_equal_exp,slang_asm_bool_copy },
657
{ "float_to_int", slang_asm_float_to_int, slang_asm_int_copy },
658
{ "float_sine", slang_asm_float_sine, slang_asm_float_copy },
659
{ "float_arcsine", slang_asm_float_arcsine, slang_asm_float_copy },
660
{ "float_arctan", slang_asm_float_arctan, slang_asm_float_copy },
661
{ "float_power", slang_asm_float_power, slang_asm_float_copy },
662
{ "float_log2", slang_asm_float_log2, slang_asm_float_copy },
663
{ "float_floor", slang_asm_float_floor, slang_asm_float_copy },
664
{ "float_ceil", slang_asm_float_ceil, slang_asm_float_copy },
665
{ "float_noise1", slang_asm_float_noise1, slang_asm_float_copy },
666
{ "float_noise2", slang_asm_float_noise2, slang_asm_float_copy },
667
{ "float_noise3", slang_asm_float_noise3, slang_asm_float_copy },
668
{ "float_noise4", slang_asm_float_noise4, slang_asm_float_copy },
669
{ "int_to_float", slang_asm_int_to_float, slang_asm_float_copy },
670
{ "vec4_tex1d", slang_asm_vec4_tex1d, slang_asm_none },
671
{ "vec4_tex2d", slang_asm_vec4_tex2d, slang_asm_none },
672
{ "vec4_tex3d", slang_asm_vec4_tex3d, slang_asm_none },
673
{ "vec4_texcube", slang_asm_vec4_texcube, slang_asm_none },
674
{ "vec4_shad1d", slang_asm_vec4_shad1d, slang_asm_none },
675
{ "vec4_shad2d", slang_asm_vec4_shad2d, slang_asm_none },
676
/* GL_MESA_shader_debug */
677
{ "float_print", slang_asm_float_deref, slang_asm_float_print },
678
{ "int_print", slang_asm_int_deref, slang_asm_int_print },
679
{ "bool_print", slang_asm_bool_deref, slang_asm_bool_print },
684
{"float_add", slang_asm_float_add, slang_asm_float_copy},
685
{"float_multiply", slang_asm_float_multiply, slang_asm_float_copy},
686
{"float_divide", slang_asm_float_divide, slang_asm_float_copy},
687
{"float_negate", slang_asm_float_negate, slang_asm_float_copy},
688
{"float_less", slang_asm_float_less, slang_asm_bool_copy},
689
{"float_equal", slang_asm_float_equal_exp, slang_asm_bool_copy},
690
{"float_to_int", slang_asm_float_to_int, slang_asm_int_copy},
691
{"float_sine", slang_asm_float_sine, slang_asm_float_copy},
692
{"float_arcsine", slang_asm_float_arcsine, slang_asm_float_copy},
693
{"float_arctan", slang_asm_float_arctan, slang_asm_float_copy},
694
{"float_power", slang_asm_float_power, slang_asm_float_copy},
695
{"float_log2", slang_asm_float_log2, slang_asm_float_copy},
696
{"float_floor", slang_asm_float_floor, slang_asm_float_copy},
697
{"float_ceil", slang_asm_float_ceil, slang_asm_float_copy},
698
{"float_noise1", slang_asm_float_noise1, slang_asm_float_copy},
699
{"float_noise2", slang_asm_float_noise2, slang_asm_float_copy},
700
{"float_noise3", slang_asm_float_noise3, slang_asm_float_copy},
701
{"float_noise4", slang_asm_float_noise4, slang_asm_float_copy},
702
{"int_to_float", slang_asm_int_to_float, slang_asm_float_copy},
703
{"vec4_tex1d", slang_asm_vec4_tex1d, slang_asm_none},
704
{"vec4_tex2d", slang_asm_vec4_tex2d, slang_asm_none},
705
{"vec4_tex3d", slang_asm_vec4_tex3d, slang_asm_none},
706
{"vec4_texcube", slang_asm_vec4_texcube, slang_asm_none},
707
{"vec4_shad1d", slang_asm_vec4_shad1d, slang_asm_none},
708
{"vec4_shad2d", slang_asm_vec4_shad2d, slang_asm_none},
709
/* GL_MESA_shader_debug */
710
{"float_print", slang_asm_float_deref, slang_asm_float_print},
711
{"int_print", slang_asm_int_deref, slang_asm_int_print},
712
{"bool_print", slang_asm_bool_deref, slang_asm_bool_print},
681
{ "float_to_vec4", slang_asm_float_to_vec4, slang_asm_none },
682
{ "vec4_add", slang_asm_vec4_add, slang_asm_none },
683
{ "vec4_subtract", slang_asm_vec4_subtract, slang_asm_none },
684
{ "vec4_multiply", slang_asm_vec4_multiply, slang_asm_none },
685
{ "vec4_divide", slang_asm_vec4_divide, slang_asm_none },
686
{ "vec4_negate", slang_asm_vec4_negate, slang_asm_none },
687
{ "vec4_dot", slang_asm_vec4_dot, slang_asm_none },
689
{ NULL, slang_asm_none, slang_asm_none }
714
{"float_to_vec4", slang_asm_float_to_vec4, slang_asm_none},
715
{"vec4_add", slang_asm_vec4_add, slang_asm_none},
716
{"vec4_subtract", slang_asm_vec4_subtract, slang_asm_none},
717
{"vec4_multiply", slang_asm_vec4_multiply, slang_asm_none},
718
{"vec4_divide", slang_asm_vec4_divide, slang_asm_none},
719
{"vec4_negate", slang_asm_vec4_negate, slang_asm_none},
720
{"vec4_dot", slang_asm_vec4_dot, slang_asm_none},
721
{NULL, slang_asm_none, slang_asm_none}
692
static GLboolean call_asm_instruction (slang_assemble_ctx *A, slang_atom a_name)
725
call_asm_instruction(slang_assemble_ctx * A, slang_atom a_name)
697
id = slang_atom_pool_id (A->atoms, a_name);
699
for (i = 0; inst[i].name != NULL; i++)
700
if (slang_string_compare (id, inst[i].name) == 0)
702
if (inst[i].name == NULL)
705
if (!PLAB2 (A->file, inst[i].code1, 4, 0))
707
if (inst[i].code2 != slang_asm_none)
708
if (!PLAB2 (A->file, inst[i].code2, 4, 0))
711
/* clean-up the stack from the remaining dst address */
712
if (!PLAB (A->file, slang_asm_local_free, 4))
730
id = slang_atom_pool_id(A->atoms, a_name);
732
for (i = 0; inst[i].name != NULL; i++)
733
if (slang_string_compare(id, inst[i].name) == 0)
735
if (inst[i].name == NULL)
738
if (!PLAB2(A->file, inst[i].code1, 4, 0))
740
if (inst[i].code2 != slang_asm_none)
741
if (!PLAB2(A->file, inst[i].code2, 4, 0))
744
/* clean-up the stack from the remaining dst address */
745
if (!PLAB(A->file, slang_asm_local_free, 4))
719
equality_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLuint *index,
720
GLuint size, GLuint z_label)
752
equality_aggregate(slang_assemble_ctx * A,
753
const slang_storage_aggregate * agg, GLuint * index,
754
GLuint size, GLuint z_label)
754
static GLboolean equality (slang_assemble_ctx *A, slang_operation *op, GLboolean equal)
756
slang_assembly_typeinfo ti;
757
GLboolean result = GL_FALSE;
758
slang_storage_aggregate agg;
760
GLuint skip_jump, true_label, true_jump, false_label, false_jump;
762
/* get type of operation */
763
if (!slang_assembly_typeinfo_construct (&ti))
765
if (!_slang_typeof_operation (A, op, &ti))
768
/* convert it to an aggregate */
769
if (!slang_storage_aggregate_construct (&agg))
771
if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs,
772
A->space.vars, A->mach, A->file, A->atoms))
775
/* compute the size of the agregate - there are two such aggregates on the stack */
776
size = _slang_sizeof_aggregate (&agg);
778
/* jump to the actual data-comparison code */
779
skip_jump = A->file->count;
780
if (!PUSH (A->file, slang_asm_jump))
783
/* pop off the stack the compared data and push 1 */
784
true_label = A->file->count;
785
if (!PLAB (A->file, slang_asm_local_free, size * 2))
787
if (!PLIT (A->file, slang_asm_bool_push, (GLfloat) 1))
789
true_jump = A->file->count;
790
if (!PUSH (A->file, slang_asm_jump))
793
false_label = A->file->count;
794
if (!PLAB (A->file, slang_asm_local_free, size * 2))
796
if (!PLIT (A->file, slang_asm_bool_push, (GLfloat) 0))
798
false_jump = A->file->count;
799
if (!PUSH (A->file, slang_asm_jump))
802
A->file->code[skip_jump].param[0] = A->file->count;
804
/* compare the data on stack, it will eventually jump either to true or false label */
806
if (!equality_aggregate (A, &agg, &index, size, equal ? false_label : true_label))
808
if (!PLAB (A->file, slang_asm_jump, equal ? true_label : false_label))
811
A->file->code[true_jump].param[0] = A->file->count;
812
A->file->code[false_jump].param[0] = A->file->count;
816
slang_storage_aggregate_destruct (&agg);
818
slang_assembly_typeinfo_destruct (&ti);
822
static GLboolean handle_subscript (slang_assemble_ctx *A, slang_assembly_typeinfo *tie,
823
slang_assembly_typeinfo *tia, slang_operation *op, slang_ref_type ref)
825
GLuint asize = 0, esize = 0;
827
/* get type info of the master expression (matrix, vector or an array */
828
if (!_slang_typeof_operation (A, &op->children[0], tia))
830
if (!sizeof_variable (A, &tia->spec, slang_qual_none, tia->array_len, &asize))
833
/* get type info of the result (matrix column, vector row or array element) */
834
if (!_slang_typeof_operation (A, op, tie))
836
if (!sizeof_variable (A, &tie->spec, slang_qual_none, 0, &esize))
839
/* assemble the master expression */
840
if (!_slang_assemble_operation (A, &op->children[0], ref))
843
/* when indexing an l-value swizzle, push the swizzle_tmp */
844
if (ref == slang_ref_force && tia->is_swizzled)
845
if (!PLAB2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
848
/* assemble the subscript expression */
849
if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
852
if (ref == slang_ref_force && tia->is_swizzled)
856
/* copy the swizzle indexes to the swizzle_tmp */
857
for (i = 0; i < tia->swz.num_components; i++)
859
if (!PLAB2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
861
if (!PLAB (A->file, slang_asm_addr_push, i * 4))
863
if (!PUSH (A->file, slang_asm_addr_add))
865
if (!PLAB (A->file, slang_asm_addr_push, tia->swz.swizzle[i]))
867
if (!PUSH (A->file, slang_asm_addr_copy))
869
if (!PLAB (A->file, slang_asm_local_free, 4))
873
/* offset the pushed swizzle_tmp address and dereference it */
874
if (!PUSH (A->file, slang_asm_int_to_addr))
876
if (!PLAB (A->file, slang_asm_addr_push, 4))
878
if (!PUSH (A->file, slang_asm_addr_multiply))
880
if (!PUSH (A->file, slang_asm_addr_add))
882
if (!PUSH (A->file, slang_asm_addr_deref))
887
/* convert the integer subscript to a relative address */
888
if (!PUSH (A->file, slang_asm_int_to_addr))
892
if (!PLAB (A->file, slang_asm_addr_push, esize))
894
if (!PUSH (A->file, slang_asm_addr_multiply))
897
if (ref == slang_ref_force)
899
/* offset the base address with the relative address */
900
if (!PUSH (A->file, slang_asm_addr_add))
907
/* move the selected element to the beginning of the master expression */
908
for (i = 0; i < esize; i += 4)
909
if (!PLAB2 (A->file, slang_asm_float_move, asize - esize + i + 4, i + 4))
911
if (!PLAB (A->file, slang_asm_local_free, 4))
914
/* free the rest of the master expression */
915
if (!PLAB (A->file, slang_asm_local_free, asize - esize))
922
static GLboolean handle_field (slang_assemble_ctx *A, slang_assembly_typeinfo *tia,
923
slang_assembly_typeinfo *tib, slang_operation *op, slang_ref_type ref)
925
/* get type info of the result (field or swizzle) */
926
if (!_slang_typeof_operation (A, op, tia))
929
/* get type info of the master expression being accessed (struct or vector) */
930
if (!_slang_typeof_operation (A, &op->children[0], tib))
933
/* if swizzling a vector in-place, the swizzle temporary is needed */
934
if (ref == slang_ref_forbid && tia->is_swizzled)
935
if (!PLAB2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
938
/* assemble the master expression */
939
if (!_slang_assemble_operation (A, &op->children[0], ref))
942
/* assemble the field expression */
943
if (tia->is_swizzled)
945
if (ref == slang_ref_force)
792
equality(slang_assemble_ctx * A, slang_operation * op, GLboolean equal)
794
slang_assembly_typeinfo ti;
795
GLboolean result = GL_FALSE;
796
slang_storage_aggregate agg;
798
GLuint skip_jump, true_label, true_jump, false_label, false_jump;
800
/* get type of operation */
801
if (!slang_assembly_typeinfo_construct(&ti))
803
if (!_slang_typeof_operation(A, op, &ti))
806
/* convert it to an aggregate */
807
if (!slang_storage_aggregate_construct(&agg))
809
if (!_slang_aggregate_variable
810
(&agg, &ti.spec, 0, A->space.funcs, A->space.structs, A->space.vars,
811
A->mach, A->file, A->atoms))
814
/* compute the size of the agregate - there are two such aggregates on the stack */
815
size = _slang_sizeof_aggregate(&agg);
817
/* jump to the actual data-comparison code */
818
skip_jump = A->file->count;
819
if (!PUSH(A->file, slang_asm_jump))
822
/* pop off the stack the compared data and push 1 */
823
true_label = A->file->count;
824
if (!PLAB(A->file, slang_asm_local_free, size * 2))
826
if (!PLIT(A->file, slang_asm_bool_push, (GLfloat) 1))
828
true_jump = A->file->count;
829
if (!PUSH(A->file, slang_asm_jump))
832
false_label = A->file->count;
833
if (!PLAB(A->file, slang_asm_local_free, size * 2))
835
if (!PLIT(A->file, slang_asm_bool_push, (GLfloat) 0))
837
false_jump = A->file->count;
838
if (!PUSH(A->file, slang_asm_jump))
841
A->file->code[skip_jump].param[0] = A->file->count;
843
/* compare the data on stack, it will eventually jump either to true or false label */
845
if (!equality_aggregate
846
(A, &agg, &index, size, equal ? false_label : true_label))
848
if (!PLAB(A->file, slang_asm_jump, equal ? true_label : false_label))
851
A->file->code[true_jump].param[0] = A->file->count;
852
A->file->code[false_jump].param[0] = A->file->count;
856
slang_storage_aggregate_destruct(&agg);
858
slang_assembly_typeinfo_destruct(&ti);
863
handle_subscript(slang_assemble_ctx * A, slang_assembly_typeinfo * tie,
864
slang_assembly_typeinfo * tia, slang_operation * op,
867
GLuint asize = 0, esize = 0;
869
/* get type info of the master expression (matrix, vector or an array */
870
if (!_slang_typeof_operation(A, &op->children[0], tia))
873
(A, &tia->spec, slang_qual_none, tia->array_len, &asize))
876
/* get type info of the result (matrix column, vector row or array element) */
877
if (!_slang_typeof_operation(A, op, tie))
879
if (!sizeof_variable(A, &tie->spec, slang_qual_none, 0, &esize))
882
/* assemble the master expression */
883
if (!_slang_assemble_operation(A, &op->children[0], ref))
886
/* when indexing an l-value swizzle, push the swizzle_tmp */
887
if (ref == slang_ref_force && tia->is_swizzled)
888
if (!PLAB2(A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
891
/* assemble the subscript expression */
892
if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid))
895
if (ref == slang_ref_force && tia->is_swizzled) {
898
/* copy the swizzle indexes to the swizzle_tmp */
899
for (i = 0; i < tia->swz.num_components; i++) {
900
if (!PLAB2(A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
902
if (!PLAB(A->file, slang_asm_addr_push, i * 4))
904
if (!PUSH(A->file, slang_asm_addr_add))
906
if (!PLAB(A->file, slang_asm_addr_push, tia->swz.swizzle[i]))
908
if (!PUSH(A->file, slang_asm_addr_copy))
910
if (!PLAB(A->file, slang_asm_local_free, 4))
914
/* offset the pushed swizzle_tmp address and dereference it */
915
if (!PUSH(A->file, slang_asm_int_to_addr))
917
if (!PLAB(A->file, slang_asm_addr_push, 4))
919
if (!PUSH(A->file, slang_asm_addr_multiply))
921
if (!PUSH(A->file, slang_asm_addr_add))
923
if (!PUSH(A->file, slang_asm_addr_deref))
927
/* convert the integer subscript to a relative address */
928
if (!PUSH(A->file, slang_asm_int_to_addr))
932
if (!PLAB(A->file, slang_asm_addr_push, esize))
934
if (!PUSH(A->file, slang_asm_addr_multiply))
937
if (ref == slang_ref_force) {
938
/* offset the base address with the relative address */
939
if (!PUSH(A->file, slang_asm_addr_add))
945
/* move the selected element to the beginning of the master expression */
946
for (i = 0; i < esize; i += 4)
948
(A->file, slang_asm_float_move, asize - esize + i + 4, i + 4))
950
if (!PLAB(A->file, slang_asm_local_free, 4))
953
/* free the rest of the master expression */
954
if (!PLAB(A->file, slang_asm_local_free, asize - esize))
962
handle_field(slang_assemble_ctx * A, slang_assembly_typeinfo * tia,
963
slang_assembly_typeinfo * tib, slang_operation * op,
966
/* get type info of the result (field or swizzle) */
967
if (!_slang_typeof_operation(A, op, tia))
970
/* get type info of the master expression being accessed (struct or vector) */
971
if (!_slang_typeof_operation(A, &op->children[0], tib))
974
/* if swizzling a vector in-place, the swizzle temporary is needed */
975
if (ref == slang_ref_forbid && tia->is_swizzled)
976
if (!PLAB2(A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
979
/* assemble the master expression */
980
if (!_slang_assemble_operation(A, &op->children[0], ref))
983
/* assemble the field expression */
984
if (tia->is_swizzled) {
985
if (ref == slang_ref_force) {
948
if (tia->swz.num_components == 1)
950
/* simple case - adjust the vector's address to point to the selected component */
951
if (!PLAB (file, slang_asm_addr_push, tia->swz.swizzle[0] * 4))
953
if (!PUSH (file, slang_asm_addr_add))
987
if (tia->swz.num_components == 1) {
988
/* simple case - adjust the vector's address to point to
989
* the selected component
991
if (!PLAB(file, slang_asm_addr_push, tia->swz.swizzle[0] * 4))
993
if (!PUSH(file, slang_asm_addr_add))
959
/* two or more vector components are being referenced - the so-called write mask
960
* must be passed to the upper operations and applied when assigning value
967
/* swizzle the vector in-place using the swizzle temporary */
968
if (!_slang_assemble_constructor_from_swizzle (A, &tia->swz, &tia->spec, &tib->spec))
974
GLuint i, struct_size = 0, field_offset = 0, field_size = 0;
999
/* two or more vector components are being referenced -
1000
* the so-called write mask must be passed to the upper
1001
* operations and applied when assigning value to this swizzle
1007
/* swizzle the vector in-place using the swizzle temporary */
1008
if (!_slang_assemble_constructor_from_swizzle
1009
(A, &tia->swz, &tia->spec, &tib->spec))
1014
GLuint i, struct_size = 0, field_offset = 0, field_size = 0;
977
1017
* Calculate struct size, field offset and field size.
979
for (i = 0; i < tib->spec._struct->fields->num_variables; i++)
981
slang_variable *field;
982
slang_storage_aggregate agg;
1019
for (i = 0; i < tib->spec._struct->fields->num_variables; i++) {
1020
slang_variable *field;
1021
slang_storage_aggregate agg;
985
field = &tib->spec._struct->fields->variables[i];
986
if (!slang_storage_aggregate_construct (&agg))
988
if (!_slang_aggregate_variable (&agg, &field->type.specifier, field->array_len,
989
A->space.funcs, A->space.structs, A->space.vars, A->mach, A->file, A->atoms))
991
slang_storage_aggregate_destruct (&agg);
994
size = _slang_sizeof_aggregate (&agg);
995
slang_storage_aggregate_destruct (&agg);
1024
field = &tib->spec._struct->fields->variables[i];
1025
if (!slang_storage_aggregate_construct(&agg))
1027
if (!_slang_aggregate_variable
1028
(&agg, &field->type.specifier, field->array_len, A->space.funcs,
1029
A->space.structs, A->space.vars, A->mach, A->file, A->atoms)) {
1030
slang_storage_aggregate_destruct(&agg);
1033
size = _slang_sizeof_aggregate(&agg);
1034
slang_storage_aggregate_destruct(&agg);
997
1036
if (op->a_id == field->a_name) {
998
1037
field_size = size;
999
1038
field_offset = struct_size;
1001
1040
struct_size += size;
1004
if (ref == slang_ref_force)
1043
if (ref == slang_ref_force) {
1006
1044
GLboolean shift;
1009
* OPTIMIZATION: If selecting first field, no address shifting is needed.
1047
* OPTIMIZATION: If selecting first field, no address shifting
1011
1050
shift = (field_offset != 0);
1014
if (!PLAB (A->file, slang_asm_addr_push, field_offset))
1016
if (!PUSH (A->file, slang_asm_addr_add))
1053
if (!PLAB(A->file, slang_asm_addr_push, field_offset))
1055
if (!PUSH(A->file, slang_asm_addr_add))
1022
1060
GLboolean relocate, shrink;
1026
* OPTIMIZATION: If selecting last field, no relocation is needed.
1064
* OPTIMIZATION: If selecting last field, no relocation is needed.
1028
1066
relocate = (field_offset != (struct_size - field_size));
1031
* OPTIMIZATION: If field and struct sizes are equal, no partial free is needed.
1069
* OPTIMIZATION: If field and struct sizes are equal, no partial
1033
1072
shrink = (field_size != struct_size);
1040
* Move the selected element to the end of the master expression.
1041
* Do it in reverse order to avoid overwriting itself.
1043
if (!PLAB (A->file, slang_asm_addr_push, field_offset))
1045
for (i = field_size; i > 0; i -= 4)
1046
if (!PLAB2 (A->file, slang_asm_float_move, struct_size - field_size + i, i))
1053
/* free the rest of the master expression */
1054
free_b += struct_size - field_size;
1059
if (!PLAB (A->file, slang_asm_local_free, free_b))
1078
* Move the selected element to the end of the master expression.
1079
* Do it in reverse order to avoid overwriting itself.
1081
if (!PLAB(A->file, slang_asm_addr_push, field_offset))
1083
for (i = field_size; i > 0; i -= 4)
1085
(A->file, slang_asm_float_move,
1086
struct_size - field_size + i, i))
1092
/* free the rest of the master expression */
1093
free_b += struct_size - field_size;
1097
if (!PLAB(A->file, slang_asm_local_free, free_b))
1068
GLboolean _slang_assemble_operation (slang_assemble_ctx *A, slang_operation *op, slang_ref_type ref)
1107
_slang_assemble_operation(slang_assemble_ctx * A, slang_operation * op,
1070
/* set default results */
1071
A->ref = /*(ref == slang_ref_freelance) ? slang_ref_force : */ref;
1072
A->swz.num_components = 0;
1076
case slang_oper_block_no_new_scope:
1077
case slang_oper_block_new_scope:
1081
for (i = 0; i < op->num_children; i++)
1083
if (!_slang_assemble_operation (A, &op->children[i], slang_ref_forbid/*slang_ref_freelance*/))
1085
if (!_slang_cleanup_stack (A, &op->children[i]))
1090
case slang_oper_variable_decl:
1093
slang_operation assign;
1096
/* Construct assignment expression placeholder. */
1097
if (!slang_operation_construct (&assign))
1099
assign.type = slang_oper_assign;
1100
assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));
1101
if (assign.children == NULL)
1103
slang_operation_destruct (&assign);
1106
for (assign.num_children = 0; assign.num_children < 2; assign.num_children++)
1107
if (!slang_operation_construct (&assign.children[assign.num_children]))
1109
slang_operation_destruct (&assign);
1114
for (i = 0; i < op->num_children; i++)
1116
slang_variable *var;
1118
var = _slang_locate_variable (op->children[i].locals, op->children[i].a_id, GL_TRUE);
1124
if (var->initializer == NULL)
1127
if (!slang_operation_copy (&assign.children[0], &op->children[i]) ||
1128
!slang_operation_copy (&assign.children[1], var->initializer) ||
1129
!_slang_assemble_assign (A, &assign, "=", slang_ref_forbid) ||
1130
!_slang_cleanup_stack (A, &assign))
1136
slang_operation_destruct (&assign);
1141
case slang_oper_asm:
1145
if (!_slang_assemble_operation (A, &op->children[0], slang_ref_force))
1147
for (i = 1; i < op->num_children; i++)
1148
if (!_slang_assemble_operation (A, &op->children[i], slang_ref_forbid))
1150
if (!call_asm_instruction (A, op->a_id))
1154
case slang_oper_break:
1155
if (!PLAB (A->file, slang_asm_jump, A->flow.loop_end))
1158
case slang_oper_continue:
1159
if (!PLAB (A->file, slang_asm_jump, A->flow.loop_start))
1162
case slang_oper_discard:
1163
if (!PUSH (A->file, slang_asm_discard))
1165
if (!PUSH (A->file, slang_asm_exit))
1168
case slang_oper_return:
1169
if (A->local.ret_size != 0)
1171
/* push the result's address */
1172
if (!PLAB2 (A->file, slang_asm_local_addr, 0, A->local.ret_size))
1174
if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
1177
A->swz.num_components = 0;
1178
/* assign the operation to the function result (it was reserved on the stack) */
1179
if (!_slang_assemble_assignment (A, op->children))
1182
if (!PLAB (A->file, slang_asm_local_free, 4))
1185
if (!PLAB (A->file, slang_asm_jump, A->flow.function_end))
1188
case slang_oper_expression:
1189
if (ref == slang_ref_force)
1191
if (!_slang_assemble_operation (A, &op->children[0], ref))
1195
if (!_slang_assemble_if (A, op))
1198
case slang_oper_while:
1199
if (!_slang_assemble_while (A, op))
1203
if (!_slang_assemble_do (A, op))
1206
case slang_oper_for:
1207
if (!_slang_assemble_for (A, op))
1210
case slang_oper_void:
1212
case slang_oper_literal_bool:
1213
if (ref == slang_ref_force)
1215
if (!PLIT (A->file, slang_asm_bool_push, op->literal))
1217
A->ref = slang_ref_forbid;
1219
case slang_oper_literal_int:
1220
if (ref == slang_ref_force)
1222
if (!PLIT (A->file, slang_asm_int_push, op->literal))
1224
A->ref = slang_ref_forbid;
1226
case slang_oper_literal_float:
1227
if (ref == slang_ref_force)
1229
if (!PLIT (A->file, slang_asm_float_push, op->literal))
1231
A->ref = slang_ref_forbid;
1233
case slang_oper_identifier:
1235
slang_variable *var;
1238
/* find the variable and calculate its size */
1239
var = _slang_locate_variable (op->locals, op->a_id, GL_TRUE);
1243
if (!sizeof_variable (A, &var->type.specifier, slang_qual_none, var->array_len, &size))
1246
/* prepare stack for dereferencing */
1247
if (ref == slang_ref_forbid)
1248
if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
1251
/* push the variable's address */
1254
if (!PLAB (A->file, slang_asm_global_addr, var->address))
1259
if (!PLAB2 (A->file, slang_asm_local_addr, var->address, size))
1263
/* perform the dereference */
1264
if (ref == slang_ref_forbid)
1266
if (!PUSH (A->file, slang_asm_addr_copy))
1268
if (!PLAB (A->file, slang_asm_local_free, 4))
1270
if (!_slang_dereference (A, op))
1275
case slang_oper_sequence:
1276
if (ref == slang_ref_force)
1278
if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid/*slang_ref_freelance*/))
1280
if (!_slang_cleanup_stack (A, &op->children[0]))
1282
if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
1284
A->ref = slang_ref_forbid;
1286
case slang_oper_assign:
1287
if (!_slang_assemble_assign (A, op, "=", ref))
1290
case slang_oper_addassign:
1291
if (!_slang_assemble_assign (A, op, "+=", ref))
1295
case slang_oper_subassign:
1296
if (!_slang_assemble_assign (A, op, "-=", ref))
1300
case slang_oper_mulassign:
1301
if (!_slang_assemble_assign (A, op, "*=", ref))
1305
/*case slang_oper_modassign:*/
1306
/*case slang_oper_lshassign:*/
1307
/*case slang_oper_rshassign:*/
1308
/*case slang_oper_orassign:*/
1309
/*case slang_oper_xorassign:*/
1310
/*case slang_oper_andassign:*/
1311
case slang_oper_divassign:
1312
if (!_slang_assemble_assign (A, op, "/=", ref))
1316
case slang_oper_select:
1317
if (!_slang_assemble_select (A, op))
1319
A->ref = slang_ref_forbid;
1321
case slang_oper_logicalor:
1322
if (!_slang_assemble_logicalor (A, op))
1324
A->ref = slang_ref_forbid;
1326
case slang_oper_logicaland:
1327
if (!_slang_assemble_logicaland (A, op))
1329
A->ref = slang_ref_forbid;
1331
case slang_oper_logicalxor:
1332
if (!_slang_assemble_function_call_name (A, "^^", op->children, 2, GL_FALSE))
1334
A->ref = slang_ref_forbid;
1336
/*case slang_oper_bitor:*/
1337
/*case slang_oper_bitxor:*/
1338
/*case slang_oper_bitand:*/
1339
case slang_oper_less:
1340
if (!_slang_assemble_function_call_name (A, "<", op->children, 2, GL_FALSE))
1342
A->ref = slang_ref_forbid;
1344
case slang_oper_greater:
1345
if (!_slang_assemble_function_call_name (A, ">", op->children, 2, GL_FALSE))
1347
A->ref = slang_ref_forbid;
1349
case slang_oper_lessequal:
1350
if (!_slang_assemble_function_call_name (A, "<=", op->children, 2, GL_FALSE))
1352
A->ref = slang_ref_forbid;
1354
case slang_oper_greaterequal:
1355
if (!_slang_assemble_function_call_name (A, ">=", op->children, 2, GL_FALSE))
1357
A->ref = slang_ref_forbid;
1359
/*case slang_oper_lshift:*/
1360
/*case slang_oper_rshift:*/
1361
case slang_oper_add:
1362
if (!_slang_assemble_function_call_name (A, "+", op->children, 2, GL_FALSE))
1364
A->ref = slang_ref_forbid;
1366
case slang_oper_subtract:
1367
if (!_slang_assemble_function_call_name (A, "-", op->children, 2, GL_FALSE))
1369
A->ref = slang_ref_forbid;
1371
case slang_oper_multiply:
1372
if (!_slang_assemble_function_call_name (A, "*", op->children, 2, GL_FALSE))
1374
A->ref = slang_ref_forbid;
1376
/*case slang_oper_modulus:*/
1377
case slang_oper_divide:
1378
if (!_slang_assemble_function_call_name (A, "/", op->children, 2, GL_FALSE))
1380
A->ref = slang_ref_forbid;
1382
case slang_oper_equal:
1383
if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
1385
if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
1387
if (!equality (A, op->children, GL_TRUE))
1389
A->ref = slang_ref_forbid;
1391
case slang_oper_notequal:
1392
if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
1394
if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
1396
if (!equality (A, op->children, GL_FALSE))
1398
A->ref = slang_ref_forbid;
1400
case slang_oper_preincrement:
1401
if (!_slang_assemble_assign (A, op, "++", ref))
1405
case slang_oper_predecrement:
1406
if (!_slang_assemble_assign (A, op, "--", ref))
1410
case slang_oper_plus:
1411
if (!_slang_dereference (A, op))
1413
A->ref = slang_ref_forbid;
1415
case slang_oper_minus:
1416
if (!_slang_assemble_function_call_name (A, "-", op->children, 1, GL_FALSE))
1418
A->ref = slang_ref_forbid;
1420
/*case slang_oper_complement:*/
1421
case slang_oper_not:
1422
if (!_slang_assemble_function_call_name (A, "!", op->children, 1, GL_FALSE))
1424
A->ref = slang_ref_forbid;
1426
case slang_oper_subscript:
1428
slang_assembly_typeinfo ti_arr, ti_elem;
1430
if (!slang_assembly_typeinfo_construct (&ti_arr))
1432
if (!slang_assembly_typeinfo_construct (&ti_elem))
1434
slang_assembly_typeinfo_destruct (&ti_arr);
1437
if (!handle_subscript (A, &ti_elem, &ti_arr, op, ref))
1439
slang_assembly_typeinfo_destruct (&ti_arr);
1440
slang_assembly_typeinfo_destruct (&ti_elem);
1443
slang_assembly_typeinfo_destruct (&ti_arr);
1444
slang_assembly_typeinfo_destruct (&ti_elem);
1447
case slang_oper_call:
1449
slang_function *fun;
1451
fun = _slang_locate_function (A->space.funcs, op->a_id, op->children, op->num_children,
1452
&A->space, A->atoms);
1455
if (!_slang_assemble_constructor (A, op))
1460
if (!_slang_assemble_function_call (A, fun, op->children, op->num_children, GL_FALSE))
1463
A->ref = slang_ref_forbid;
1466
case slang_oper_field:
1468
slang_assembly_typeinfo ti_after, ti_before;
1470
if (!slang_assembly_typeinfo_construct (&ti_after))
1472
if (!slang_assembly_typeinfo_construct (&ti_before))
1474
slang_assembly_typeinfo_destruct (&ti_after);
1477
if (!handle_field (A, &ti_after, &ti_before, op, ref))
1479
slang_assembly_typeinfo_destruct (&ti_after);
1480
slang_assembly_typeinfo_destruct (&ti_before);
1483
slang_assembly_typeinfo_destruct (&ti_after);
1484
slang_assembly_typeinfo_destruct (&ti_before);
1487
case slang_oper_postincrement:
1488
if (!assemble_function_call_name_dummyint (A, "++", op->children))
1490
A->ref = slang_ref_forbid;
1492
case slang_oper_postdecrement:
1493
if (!assemble_function_call_name_dummyint (A, "--", op->children))
1495
A->ref = slang_ref_forbid;
1110
/* set default results */
1111
A->ref = /*(ref == slang_ref_freelance) ? slang_ref_force : */ ref;
1112
A->swz.num_components = 0;
1115
case slang_oper_block_no_new_scope:
1116
case slang_oper_block_new_scope:
1120
for (i = 0; i < op->num_children; i++) {
1121
if (!_slang_assemble_operation
1122
(A, &op->children[i],
1123
slang_ref_forbid /*slang_ref_freelance */ ))
1125
if (!_slang_cleanup_stack(A, &op->children[i]))
1130
case slang_oper_variable_decl:
1133
slang_operation assign;
1136
/* Construct assignment expression placeholder. */
1137
if (!slang_operation_construct(&assign))
1139
assign.type = slang_oper_assign;
1141
(slang_operation *) slang_alloc_malloc(2 *
1142
sizeof(slang_operation));
1143
if (assign.children == NULL) {
1144
slang_operation_destruct(&assign);
1147
for (assign.num_children = 0; assign.num_children < 2;
1148
assign.num_children++)
1149
if (!slang_operation_construct
1150
(&assign.children[assign.num_children])) {
1151
slang_operation_destruct(&assign);
1156
for (i = 0; i < op->num_children; i++) {
1157
slang_variable *var;
1160
_slang_locate_variable(op->children[i].locals,
1161
op->children[i].a_id, GL_TRUE);
1166
if (var->initializer == NULL)
1169
if (!slang_operation_copy(&assign.children[0], &op->children[i])
1170
|| !slang_operation_copy(&assign.children[1],
1172
|| !_slang_assemble_assign(A, &assign, "=", slang_ref_forbid)
1173
|| !_slang_cleanup_stack(A, &assign)) {
1178
slang_operation_destruct(&assign);
1183
case slang_oper_asm:
1186
if (!_slang_assemble_operation(A, &op->children[0], slang_ref_force))
1188
for (i = 1; i < op->num_children; i++)
1189
if (!_slang_assemble_operation
1190
(A, &op->children[i], slang_ref_forbid))
1192
if (!call_asm_instruction(A, op->a_id))
1196
case slang_oper_break:
1197
if (!PLAB(A->file, slang_asm_jump, A->flow.loop_end))
1200
case slang_oper_continue:
1201
if (!PLAB(A->file, slang_asm_jump, A->flow.loop_start))
1204
case slang_oper_discard:
1205
if (!PUSH(A->file, slang_asm_discard))
1207
if (!PUSH(A->file, slang_asm_exit))
1210
case slang_oper_return:
1211
if (A->local.ret_size != 0) {
1212
/* push the result's address */
1213
if (!PLAB2(A->file, slang_asm_local_addr, 0, A->local.ret_size))
1215
if (!_slang_assemble_operation
1216
(A, &op->children[0], slang_ref_forbid))
1219
A->swz.num_components = 0;
1220
/* assign the operation to the function result (it was reserved on the stack) */
1221
if (!_slang_assemble_assignment(A, op->children))
1224
if (!PLAB(A->file, slang_asm_local_free, 4))
1227
if (!PLAB(A->file, slang_asm_jump, A->flow.function_end))
1230
case slang_oper_expression:
1231
if (ref == slang_ref_force)
1233
if (!_slang_assemble_operation(A, &op->children[0], ref))
1237
if (!_slang_assemble_if(A, op))
1240
case slang_oper_while:
1241
if (!_slang_assemble_while(A, op))
1245
if (!_slang_assemble_do(A, op))
1248
case slang_oper_for:
1249
if (!_slang_assemble_for(A, op))
1252
case slang_oper_void:
1254
case slang_oper_literal_bool:
1255
if (ref == slang_ref_force)
1257
if (!PLIT(A->file, slang_asm_bool_push, op->literal))
1259
A->ref = slang_ref_forbid;
1261
case slang_oper_literal_int:
1262
if (ref == slang_ref_force)
1264
if (!PLIT(A->file, slang_asm_int_push, op->literal))
1266
A->ref = slang_ref_forbid;
1268
case slang_oper_literal_float:
1269
if (ref == slang_ref_force)
1271
if (!PLIT(A->file, slang_asm_float_push, op->literal))
1273
A->ref = slang_ref_forbid;
1275
case slang_oper_identifier:
1277
slang_variable *var;
1280
/* find the variable and calculate its size */
1281
var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE);
1285
if (!sizeof_variable
1286
(A, &var->type.specifier, slang_qual_none, var->array_len,
1290
/* prepare stack for dereferencing */
1291
if (ref == slang_ref_forbid)
1292
if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
1295
/* push the variable's address */
1297
if (!PLAB(A->file, slang_asm_global_addr, var->address))
1301
if (!PLAB2(A->file, slang_asm_local_addr, var->address, size))
1305
/* perform the dereference */
1306
if (ref == slang_ref_forbid) {
1307
if (!PUSH(A->file, slang_asm_addr_copy))
1309
if (!PLAB(A->file, slang_asm_local_free, 4))
1311
if (!_slang_dereference(A, op))
1316
case slang_oper_sequence:
1317
if (ref == slang_ref_force)
1319
if (!_slang_assemble_operation(A, &op->children[0],
1320
slang_ref_forbid /*slang_ref_freelance */ ))
1322
if (!_slang_cleanup_stack(A, &op->children[0]))
1324
if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid))
1326
A->ref = slang_ref_forbid;
1328
case slang_oper_assign:
1329
if (!_slang_assemble_assign(A, op, "=", ref))
1332
case slang_oper_addassign:
1333
if (!_slang_assemble_assign(A, op, "+=", ref))
1337
case slang_oper_subassign:
1338
if (!_slang_assemble_assign(A, op, "-=", ref))
1342
case slang_oper_mulassign:
1343
if (!_slang_assemble_assign(A, op, "*=", ref))
1347
/*case slang_oper_modassign: */
1348
/*case slang_oper_lshassign: */
1349
/*case slang_oper_rshassign: */
1350
/*case slang_oper_orassign: */
1351
/*case slang_oper_xorassign: */
1352
/*case slang_oper_andassign: */
1353
case slang_oper_divassign:
1354
if (!_slang_assemble_assign(A, op, "/=", ref))
1358
case slang_oper_select:
1359
if (!_slang_assemble_select(A, op))
1361
A->ref = slang_ref_forbid;
1363
case slang_oper_logicalor:
1364
if (!_slang_assemble_logicalor(A, op))
1366
A->ref = slang_ref_forbid;
1368
case slang_oper_logicaland:
1369
if (!_slang_assemble_logicaland(A, op))
1371
A->ref = slang_ref_forbid;
1373
case slang_oper_logicalxor:
1374
if (!_slang_assemble_function_call_name(A, "^^", op->children, 2, GL_FALSE))
1376
A->ref = slang_ref_forbid;
1378
/*case slang_oper_bitor: */
1379
/*case slang_oper_bitxor: */
1380
/*case slang_oper_bitand: */
1381
case slang_oper_less:
1382
if (!_slang_assemble_function_call_name(A, "<", op->children, 2, GL_FALSE))
1384
A->ref = slang_ref_forbid;
1386
case slang_oper_greater:
1387
if (!_slang_assemble_function_call_name(A, ">", op->children, 2, GL_FALSE))
1389
A->ref = slang_ref_forbid;
1391
case slang_oper_lessequal:
1392
if (!_slang_assemble_function_call_name(A, "<=", op->children, 2, GL_FALSE))
1394
A->ref = slang_ref_forbid;
1396
case slang_oper_greaterequal:
1397
if (!_slang_assemble_function_call_name(A, ">=", op->children, 2, GL_FALSE))
1399
A->ref = slang_ref_forbid;
1401
/*case slang_oper_lshift: */
1402
/*case slang_oper_rshift: */
1403
case slang_oper_add:
1404
if (!_slang_assemble_function_call_name(A, "+", op->children, 2, GL_FALSE))
1406
A->ref = slang_ref_forbid;
1408
case slang_oper_subtract:
1409
if (!_slang_assemble_function_call_name(A, "-", op->children, 2, GL_FALSE))
1411
A->ref = slang_ref_forbid;
1413
case slang_oper_multiply:
1414
if (!_slang_assemble_function_call_name(A, "*", op->children, 2, GL_FALSE))
1416
A->ref = slang_ref_forbid;
1418
/*case slang_oper_modulus: */
1419
case slang_oper_divide:
1420
if (!_slang_assemble_function_call_name(A, "/", op->children, 2, GL_FALSE))
1422
A->ref = slang_ref_forbid;
1424
case slang_oper_equal:
1425
if (!_slang_assemble_operation(A, &op->children[0], slang_ref_forbid))
1427
if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid))
1429
if (!equality(A, op->children, GL_TRUE))
1431
A->ref = slang_ref_forbid;
1433
case slang_oper_notequal:
1434
if (!_slang_assemble_operation(A, &op->children[0], slang_ref_forbid))
1436
if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid))
1438
if (!equality(A, op->children, GL_FALSE))
1440
A->ref = slang_ref_forbid;
1442
case slang_oper_preincrement:
1443
if (!_slang_assemble_assign(A, op, "++", ref))
1447
case slang_oper_predecrement:
1448
if (!_slang_assemble_assign(A, op, "--", ref))
1452
case slang_oper_plus:
1453
if (!_slang_dereference(A, op))
1455
A->ref = slang_ref_forbid;
1457
case slang_oper_minus:
1458
if (!_slang_assemble_function_call_name
1459
(A, "-", op->children, 1, GL_FALSE))
1461
A->ref = slang_ref_forbid;
1463
/*case slang_oper_complement: */
1464
case slang_oper_not:
1465
if (!_slang_assemble_function_call_name
1466
(A, "!", op->children, 1, GL_FALSE))
1468
A->ref = slang_ref_forbid;
1470
case slang_oper_subscript:
1472
slang_assembly_typeinfo ti_arr, ti_elem;
1474
if (!slang_assembly_typeinfo_construct(&ti_arr))
1476
if (!slang_assembly_typeinfo_construct(&ti_elem)) {
1477
slang_assembly_typeinfo_destruct(&ti_arr);
1480
if (!handle_subscript(A, &ti_elem, &ti_arr, op, ref)) {
1481
slang_assembly_typeinfo_destruct(&ti_arr);
1482
slang_assembly_typeinfo_destruct(&ti_elem);
1485
slang_assembly_typeinfo_destruct(&ti_arr);
1486
slang_assembly_typeinfo_destruct(&ti_elem);
1489
case slang_oper_call:
1491
slang_function *fun;
1494
_slang_locate_function(A->space.funcs, op->a_id, op->children,
1495
op->num_children, &A->space, A->atoms);
1497
if (!_slang_assemble_constructor(A, op))
1501
if (!_slang_assemble_function_call
1502
(A, fun, op->children, op->num_children, GL_FALSE))
1505
A->ref = slang_ref_forbid;
1508
case slang_oper_field:
1510
slang_assembly_typeinfo ti_after, ti_before;
1512
if (!slang_assembly_typeinfo_construct(&ti_after))
1514
if (!slang_assembly_typeinfo_construct(&ti_before)) {
1515
slang_assembly_typeinfo_destruct(&ti_after);
1518
if (!handle_field(A, &ti_after, &ti_before, op, ref)) {
1519
slang_assembly_typeinfo_destruct(&ti_after);
1520
slang_assembly_typeinfo_destruct(&ti_before);
1523
slang_assembly_typeinfo_destruct(&ti_after);
1524
slang_assembly_typeinfo_destruct(&ti_before);
1527
case slang_oper_postincrement:
1528
if (!assemble_function_call_name_dummyint(A, "++", op->children))
1530
A->ref = slang_ref_forbid;
1532
case slang_oper_postdecrement:
1533
if (!assemble_function_call_name_dummyint(A, "--", op->children))
1535
A->ref = slang_ref_forbid;