~ubuntu-branches/ubuntu/quantal/mesa/quantal

« back to all changes in this revision

Viewing changes to src/mesa/shader/slang/slang_assemble.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-02-21 12:44:07 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20070221124407-rgcacs32mycrtadl
ImportĀ upstreamĀ versionĀ 6.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
 
36
36
/* slang_assembly */
37
37
 
38
 
static GLboolean slang_assembly_construct (slang_assembly *assem)
 
38
static GLboolean
 
39
slang_assembly_construct(slang_assembly * assem)
39
40
{
40
 
        assem->type = slang_asm_none;
41
 
        return GL_TRUE;
 
41
   assem->type = slang_asm_none;
 
42
   return GL_TRUE;
42
43
}
43
44
 
44
 
static GLvoid slang_assembly_destruct (slang_assembly *assem)
 
45
static GLvoid
 
46
slang_assembly_destruct(slang_assembly * assem)
45
47
{
46
48
}
47
49
 
50
52
 */
51
53
 
52
54
GLvoid
53
 
_slang_assembly_file_ctr (slang_assembly_file *self)
 
55
_slang_assembly_file_ctr(slang_assembly_file * self)
54
56
{
55
57
   self->code = NULL;
56
58
   self->count = 0;
57
59
   self->capacity = 0;
58
60
}
59
61
 
60
 
GLvoid slang_assembly_file_destruct (slang_assembly_file *file)
61
 
{
62
 
        GLuint i;
63
 
 
64
 
        for (i = 0; i < file->count; i++)
65
 
                slang_assembly_destruct (&file->code[i]);
66
 
        slang_alloc_free (file->code);
67
 
}
68
 
 
69
 
static GLboolean push_new (slang_assembly_file *file)
70
 
{
71
 
        if (file->count == file->capacity)
72
 
        {
73
 
                GLuint n;
74
 
 
75
 
                if (file->capacity == 0)
76
 
                        n = 256;
77
 
                else
78
 
                        n = file->capacity * 2;
79
 
                file->code = (slang_assembly *) slang_alloc_realloc (file->code,
80
 
                        file->capacity * sizeof (slang_assembly), n * sizeof (slang_assembly));
81
 
                if (file->code == NULL)
82
 
                        return GL_FALSE;
83
 
                file->capacity = n;
84
 
        }
85
 
        if (!slang_assembly_construct (&file->code[file->count]))
86
 
                return GL_FALSE;
87
 
        file->count++;
88
 
        return GL_TRUE;
89
 
}
90
 
 
91
 
static GLboolean push_gen (slang_assembly_file *file, slang_assembly_type type, GLfloat literal,
92
 
        GLuint label, GLuint size)
93
 
{
94
 
        slang_assembly *assem;
95
 
 
96
 
        if (!push_new (file))
97
 
                return GL_FALSE;
98
 
        assem = &file->code[file->count - 1];
99
 
        assem->type = type;
100
 
        assem->literal = literal;
101
 
        assem->param[0] = label;
102
 
        assem->param[1] = size;
103
 
        return GL_TRUE;
104
 
}
105
 
 
106
 
GLboolean slang_assembly_file_push (slang_assembly_file *file, slang_assembly_type type)
107
 
{
108
 
        return push_gen (file, type, (GLfloat) 0, 0, 0);
109
 
}
110
 
 
111
 
GLboolean slang_assembly_file_push_label (slang_assembly_file *file, slang_assembly_type type,
112
 
        GLuint label)
113
 
{
114
 
        return push_gen (file, type, (GLfloat) 0, label, 0);
115
 
}
116
 
 
117
 
GLboolean slang_assembly_file_push_label2 (slang_assembly_file *file, slang_assembly_type type,
118
 
        GLuint label1, GLuint label2)
119
 
{
120
 
        return push_gen (file, type, (GLfloat) 0, label1, label2);
121
 
}
122
 
 
123
 
GLboolean slang_assembly_file_push_literal (slang_assembly_file *file, slang_assembly_type type,
124
 
        GLfloat literal)
125
 
{
126
 
        return push_gen (file, type, literal, 0, 0);
 
62
GLvoid
 
63
slang_assembly_file_destruct(slang_assembly_file * file)
 
64
{
 
65
   GLuint i;
 
66
 
 
67
   for (i = 0; i < file->count; i++)
 
68
      slang_assembly_destruct(&file->code[i]);
 
69
   slang_alloc_free(file->code);
 
70
}
 
71
 
 
72
static GLboolean
 
73
push_new(slang_assembly_file * file)
 
74
{
 
75
   if (file->count == file->capacity) {
 
76
      GLuint n;
 
77
 
 
78
      if (file->capacity == 0)
 
79
         n = 256;
 
80
      else
 
81
         n = file->capacity * 2;
 
82
      file->code = (slang_assembly *)
 
83
         slang_alloc_realloc(file->code,
 
84
                             file->capacity * sizeof(slang_assembly),
 
85
                             n * sizeof(slang_assembly));
 
86
      if (file->code == NULL)
 
87
         return GL_FALSE;
 
88
      file->capacity = n;
 
89
   }
 
90
   if (!slang_assembly_construct(&file->code[file->count]))
 
91
      return GL_FALSE;
 
92
   file->count++;
 
93
   return GL_TRUE;
 
94
}
 
95
 
 
96
static GLboolean
 
97
push_gen(slang_assembly_file * file, slang_assembly_type type,
 
98
         GLfloat literal, GLuint label, GLuint size)
 
99
{
 
100
   slang_assembly *assem;
 
101
 
 
102
   if (!push_new(file))
 
103
      return GL_FALSE;
 
104
   assem = &file->code[file->count - 1];
 
105
   assem->type = type;
 
106
   assem->literal = literal;
 
107
   assem->param[0] = label;
 
108
   assem->param[1] = size;
 
109
   return GL_TRUE;
 
110
}
 
111
 
 
112
GLboolean
 
113
slang_assembly_file_push(slang_assembly_file * file, slang_assembly_type type)
 
114
{
 
115
   return push_gen(file, type, (GLfloat) 0, 0, 0);
 
116
}
 
117
 
 
118
GLboolean
 
119
slang_assembly_file_push_label(slang_assembly_file * file,
 
120
                               slang_assembly_type type, GLuint label)
 
121
{
 
122
   return push_gen(file, type, (GLfloat) 0, label, 0);
 
123
}
 
124
 
 
125
GLboolean
 
126
slang_assembly_file_push_label2(slang_assembly_file * file,
 
127
                                slang_assembly_type type, GLuint label1,
 
128
                                GLuint label2)
 
129
{
 
130
   return push_gen(file, type, (GLfloat) 0, label1, label2);
 
131
}
 
132
 
 
133
GLboolean
 
134
slang_assembly_file_push_literal(slang_assembly_file * file,
 
135
                                 slang_assembly_type type, GLfloat literal)
 
136
{
 
137
   return push_gen(file, type, literal, 0, 0);
127
138
}
128
139
 
129
140
#define PUSH slang_assembly_file_push
133
144
 
134
145
/* slang_assembly_file_restore_point */
135
146
 
136
 
GLboolean slang_assembly_file_restore_point_save (slang_assembly_file *file,
137
 
        slang_assembly_file_restore_point *point)
 
147
GLboolean
 
148
slang_assembly_file_restore_point_save(slang_assembly_file * file,
 
149
                                       slang_assembly_file_restore_point *
 
150
                                       point)
138
151
{
139
 
        point->count = file->count;
140
 
        return GL_TRUE;
 
152
   point->count = file->count;
 
153
   return GL_TRUE;
141
154
}
142
155
 
143
 
GLboolean slang_assembly_file_restore_point_load (slang_assembly_file *file,
144
 
        slang_assembly_file_restore_point *point)
 
156
GLboolean
 
157
slang_assembly_file_restore_point_load(slang_assembly_file * file,
 
158
                                       slang_assembly_file_restore_point *
 
159
                                       point)
145
160
{
146
 
        GLuint i;
 
161
   GLuint i;
147
162
 
148
 
        for (i = point->count; i < file->count; i++)
149
 
                slang_assembly_destruct (&file->code[i]);
150
 
        file->count = point->count;
151
 
        return GL_TRUE;
 
163
   for (i = point->count; i < file->count; i++)
 
164
      slang_assembly_destruct(&file->code[i]);
 
165
   file->count = point->count;
 
166
   return GL_TRUE;
152
167
}
153
168
 
154
169
/* utility functions */
155
170
 
156
 
static GLboolean sizeof_variable (slang_assemble_ctx *A, slang_type_specifier *spec,
157
 
        slang_type_qualifier qual, GLuint array_len, GLuint *size)
158
 
{
159
 
        slang_storage_aggregate agg;
160
 
 
161
 
        /* calculate the size of the variable's aggregate */
162
 
        if (!slang_storage_aggregate_construct (&agg))
163
 
                return GL_FALSE;
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))
166
 
        {
167
 
                slang_storage_aggregate_destruct (&agg);
168
 
                return GL_FALSE;
169
 
        }
170
 
        *size += _slang_sizeof_aggregate (&agg);
171
 
        slang_storage_aggregate_destruct (&agg);
172
 
 
173
 
        /* for reference variables consider the additional address overhead */
174
 
        if (qual == slang_qual_out || qual == slang_qual_inout)
175
 
                *size += 4;
176
 
 
177
 
        return GL_TRUE;
178
 
}
179
 
 
180
 
static GLboolean sizeof_variable2 (slang_assemble_ctx *A, slang_variable *var, GLuint *size)
181
 
{
182
 
        var->address = *size;
183
 
        if (var->type.qualifier == slang_qual_out || var->type.qualifier == slang_qual_inout)
184
 
                var->address += 4;
185
 
        return sizeof_variable (A, &var->type.specifier, var->type.qualifier, var->array_len, size);
186
 
}
187
 
 
188
 
static GLboolean sizeof_variables (slang_assemble_ctx *A, slang_variable_scope *vars, GLuint start,
189
 
        GLuint stop, GLuint *size)
190
 
{
191
 
        GLuint i;
192
 
 
193
 
        for (i = start; i < stop; i++)
194
 
                if (!sizeof_variable2 (A, &vars->variables[i], size))
195
 
                        return GL_FALSE;
196
 
        return GL_TRUE;
197
 
}
198
 
 
199
 
static GLboolean collect_locals (slang_assemble_ctx *A, slang_operation *op, GLuint *size)
200
 
{
201
 
        GLuint i;
202
 
 
203
 
        if (!sizeof_variables (A, op->locals, 0, op->locals->num_variables, size))
204
 
                return GL_FALSE;
205
 
        for (i = 0; i < op->num_children; i++)
206
 
                if (!collect_locals (A, &op->children[i], size))
207
 
                        return GL_FALSE;
208
 
        return GL_TRUE;
 
171
static GLboolean
 
172
sizeof_variable(slang_assemble_ctx * A, slang_type_specifier * spec,
 
173
                slang_type_qualifier qual, GLuint array_len, GLuint * size)
 
174
{
 
175
   slang_storage_aggregate agg;
 
176
 
 
177
   /* calculate the size of the variable's aggregate */
 
178
   if (!slang_storage_aggregate_construct(&agg))
 
179
      return GL_FALSE;
 
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);
 
184
      return GL_FALSE;
 
185
   }
 
186
   *size += _slang_sizeof_aggregate(&agg);
 
187
   slang_storage_aggregate_destruct(&agg);
 
188
 
 
189
   /* for reference variables consider the additional address overhead */
 
190
   if (qual == slang_qual_out || qual == slang_qual_inout)
 
191
      *size += 4;
 
192
 
 
193
   return GL_TRUE;
 
194
}
 
195
 
 
196
static GLboolean
 
197
sizeof_variable2(slang_assemble_ctx * A, slang_variable * var, GLuint * size)
 
198
{
 
199
   var->address = *size;
 
200
   if (var->type.qualifier == slang_qual_out
 
201
       || var->type.qualifier == slang_qual_inout)
 
202
      var->address += 4;
 
203
   return sizeof_variable(A, &var->type.specifier, var->type.qualifier,
 
204
                          var->array_len, size);
 
205
}
 
206
 
 
207
static GLboolean
 
208
sizeof_variables(slang_assemble_ctx * A, slang_variable_scope * vars,
 
209
                 GLuint start, GLuint stop, GLuint * size)
 
210
{
 
211
   GLuint i;
 
212
 
 
213
   for (i = start; i < stop; i++)
 
214
      if (!sizeof_variable2(A, &vars->variables[i], size))
 
215
         return GL_FALSE;
 
216
   return GL_TRUE;
 
217
}
 
218
 
 
219
static GLboolean
 
220
collect_locals(slang_assemble_ctx * A, slang_operation * op, GLuint * size)
 
221
{
 
222
   GLuint i;
 
223
 
 
224
   if (!sizeof_variables(A, op->locals, 0, op->locals->num_variables, size))
 
225
      return GL_FALSE;
 
226
   for (i = 0; i < op->num_children; i++)
 
227
      if (!collect_locals(A, &op->children[i], size))
 
228
         return GL_FALSE;
 
229
   return GL_TRUE;
209
230
}
210
231
 
211
232
/* _slang_locate_function() */
212
233
 
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)
 
234
slang_function *
 
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)
216
239
{
217
 
        GLuint i;
218
 
 
219
 
        for (i = 0; i < funcs->num_functions; i++)
220
 
        {
221
 
                GLuint j;
222
 
                slang_function *f = &funcs->functions[i];
223
 
 
224
 
                if (a_name != f->header.a_name)
225
 
                        continue;
226
 
                if (f->param_count != num_params)
227
 
                        continue;
228
 
                for (j = 0; j < num_params; j++)
229
 
                {
230
 
                        slang_assembly_typeinfo ti;
231
 
 
232
 
                        if (!slang_assembly_typeinfo_construct (&ti))
233
 
                                return NULL;
234
 
                        if (!_slang_typeof_operation_ (&params[j], space, &ti, atoms))
235
 
                        {
236
 
                                slang_assembly_typeinfo_destruct (&ti);
237
 
                                return NULL;
238
 
                        }
239
 
                        if (!slang_type_specifier_equal (&ti.spec, &f->parameters->variables[j].type.specifier))
240
 
                        {
241
 
                                slang_assembly_typeinfo_destruct (&ti);
242
 
                                break;
243
 
                        }
244
 
                        slang_assembly_typeinfo_destruct (&ti);
245
 
 
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))
250
 
                                break;
251
 
                }
252
 
                if (j == num_params)
253
 
                        return f;
254
 
        }
255
 
        if (funcs->outer_scope != NULL)
256
 
                return _slang_locate_function (funcs->outer_scope, a_name, params, num_params, space, atoms);
257
 
        return NULL;
 
240
   GLuint i;
 
241
 
 
242
   for (i = 0; i < funcs->num_functions; i++) {
 
243
      GLuint j;
 
244
      slang_function *f = &funcs->functions[i];
 
245
 
 
246
      if (a_name != f->header.a_name)
 
247
         continue;
 
248
      if (f->param_count != num_params)
 
249
         continue;
 
250
      for (j = 0; j < num_params; j++) {
 
251
         slang_assembly_typeinfo ti;
 
252
 
 
253
         if (!slang_assembly_typeinfo_construct(&ti))
 
254
            return NULL;
 
255
         if (!_slang_typeof_operation_(&params[j], space, &ti, atoms)) {
 
256
            slang_assembly_typeinfo_destruct(&ti);
 
257
            return NULL;
 
258
         }
 
259
         if (!slang_type_specifier_equal
 
260
             (&ti.spec, &f->parameters->variables[j].type.specifier)) {
 
261
            slang_assembly_typeinfo_destruct(&ti);
 
262
            break;
 
263
         }
 
264
         slang_assembly_typeinfo_destruct(&ti);
 
265
 
 
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))
 
270
            break;
 
271
      }
 
272
      if (j == num_params)
 
273
         return f;
 
274
   }
 
275
   if (funcs->outer_scope != NULL)
 
276
      return _slang_locate_function(funcs->outer_scope, a_name, params,
 
277
                                    num_params, space, atoms);
 
278
   return NULL;
258
279
}
259
280
 
260
281
/* _slang_assemble_function() */
261
282
 
262
 
GLboolean _slang_assemble_function (slang_assemble_ctx *A, slang_function *fun)
 
283
GLboolean
 
284
_slang_assemble_function(slang_assemble_ctx * A, slang_function * fun)
263
285
{
264
 
        GLuint param_size, local_size;
265
 
        GLuint skip, cleanup;
266
 
 
267
 
        fun->address = A->file->count;
268
 
 
269
 
        if (fun->body == NULL)
270
 
        {
271
 
                /* jump to the actual function body - we do not know it, so add the instruction
272
 
                 * to fixup table */
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)
276
 
                        return GL_FALSE;
277
 
                fun->fixups.table[fun->fixups.count] = fun->address;
278
 
                fun->fixups.count++;
279
 
                if (!PUSH (A->file, slang_asm_jump))
280
 
                        return GL_FALSE;
281
 
                return GL_TRUE;
282
 
        }
283
 
        else
284
 
        {
285
 
                GLuint i;
286
 
 
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);
291
 
        }
292
 
 
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. */
298
 
 
299
 
        /* calculate return value size */
300
 
        param_size = 0;
301
 
        if (fun->header.type.specifier.type != slang_spec_void)
302
 
                if (!sizeof_variable (A, &fun->header.type.specifier, slang_qual_none, 0, &param_size))
303
 
                        return GL_FALSE;
304
 
        A->local.ret_size = param_size;
305
 
 
306
 
        /* calculate formal parameter list size */
307
 
        if (!sizeof_variables (A, fun->parameters, 0, fun->param_count, &param_size))
308
 
                return GL_FALSE;
309
 
 
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,
317
 
                        &local_size))
318
 
                return GL_FALSE;
319
 
        if (!collect_locals (A, fun->body, &local_size))
320
 
                return GL_FALSE;
321
 
 
322
 
        /* allocate local variable storage */
323
 
        if (!PLAB (A->file, slang_asm_local_alloc, local_size - param_size - 4))
324
 
                return GL_FALSE;
325
 
 
326
 
        /* mark a new frame for function variable storage */
327
 
        if (!PLAB (A->file, slang_asm_enter, local_size))
328
 
                return GL_FALSE;
329
 
 
330
 
        /* jump directly to the actual code */
331
 
        skip = A->file->count;
332
 
        if (!push_new (A->file))
333
 
                return GL_FALSE;
334
 
        A->file->code[skip].type = slang_asm_jump;
335
 
 
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))
340
 
                return GL_FALSE;
341
 
        A->file->code[cleanup].type = slang_asm_jump;
342
 
 
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))
346
 
                return GL_FALSE;
347
 
 
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))
351
 
                return GL_FALSE;
352
 
 
353
 
        /* free local variable storage */
354
 
        if (!PLAB (A->file, slang_asm_local_free, local_size - param_size - 4))
355
 
                return GL_FALSE;
356
 
 
357
 
        /* return from the function */
358
 
        if (!PUSH (A->file, slang_asm_return))
359
 
                return GL_FALSE;
360
 
 
361
 
        return GL_TRUE;
 
286
   GLuint param_size, local_size;
 
287
   GLuint skip, cleanup;
 
288
 
 
289
   fun->address = A->file->count;
 
290
 
 
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
 
294
       */
 
295
      if (!slang_fixup_save(&fun->fixups, fun->address))
 
296
         return GL_FALSE;
 
297
      if (!PUSH(A->file, slang_asm_jump))
 
298
         return GL_FALSE;
 
299
      return GL_TRUE;
 
300
   }
 
301
   else {
 
302
      /* resolve all fixup table entries and delete it */
 
303
      GLuint i;
 
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);
 
307
   }
 
308
 
 
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.
 
315
    */
 
316
 
 
317
   /* calculate return value size */
 
318
   param_size = 0;
 
319
   if (fun->header.type.specifier.type != slang_spec_void)
 
320
      if (!sizeof_variable
 
321
          (A, &fun->header.type.specifier, slang_qual_none, 0, &param_size))
 
322
         return GL_FALSE;
 
323
   A->local.ret_size = param_size;
 
324
 
 
325
   /* calculate formal parameter list size */
 
326
   if (!sizeof_variables
 
327
       (A, fun->parameters, 0, fun->param_count, &param_size))
 
328
      return GL_FALSE;
 
329
 
 
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
 
334
    */
 
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,
 
340
        &local_size))
 
341
      return GL_FALSE;
 
342
   if (!collect_locals(A, fun->body, &local_size))
 
343
      return GL_FALSE;
 
344
 
 
345
   /* allocate local variable storage */
 
346
   if (!PLAB(A->file, slang_asm_local_alloc, local_size - param_size - 4))
 
347
      return GL_FALSE;
 
348
 
 
349
   /* mark a new frame for function variable storage */
 
350
   if (!PLAB(A->file, slang_asm_enter, local_size))
 
351
      return GL_FALSE;
 
352
 
 
353
   /* jump directly to the actual code */
 
354
   skip = A->file->count;
 
355
   if (!push_new(A->file))
 
356
      return GL_FALSE;
 
357
   A->file->code[skip].type = slang_asm_jump;
 
358
 
 
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))
 
363
      return GL_FALSE;
 
364
   A->file->code[cleanup].type = slang_asm_jump;
 
365
 
 
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))
 
370
      return GL_FALSE;
 
371
 
 
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))
 
375
      return GL_FALSE;
 
376
 
 
377
   /* free local variable storage */
 
378
   if (!PLAB(A->file, slang_asm_local_free, local_size - param_size - 4))
 
379
      return GL_FALSE;
 
380
 
 
381
   /* return from the function */
 
382
   if (!PUSH(A->file, slang_asm_return))
 
383
      return GL_FALSE;
 
384
 
 
385
   return GL_TRUE;
362
386
}
363
387
 
364
 
GLboolean _slang_cleanup_stack (slang_assemble_ctx *A, slang_operation *op)
 
388
GLboolean
 
389
_slang_cleanup_stack(slang_assemble_ctx * A, slang_operation * op)
365
390
{
366
 
        slang_assembly_typeinfo ti;
367
 
        GLuint size = 0;
368
 
 
369
 
        /* get type info of the operation and calculate its size */
370
 
        if (!slang_assembly_typeinfo_construct (&ti))
371
 
                return GL_FALSE;
372
 
        if (!_slang_typeof_operation (A, op, &ti))
373
 
        {
374
 
                slang_assembly_typeinfo_destruct (&ti);
375
 
                return GL_FALSE;
376
 
        }
377
 
        if (ti.spec.type != slang_spec_void) {
378
 
                if (A->ref == slang_ref_force) {
379
 
                        size = 4;
380
 
                }
381
 
                else if (!sizeof_variable (A, &ti.spec, slang_qual_none, 0, &size))
382
 
                {
383
 
                        slang_assembly_typeinfo_destruct (&ti);
384
 
                        return GL_FALSE;
385
 
                }
386
 
        }
387
 
        slang_assembly_typeinfo_destruct (&ti);
388
 
 
389
 
        /* if nonzero, free it from the stack */
390
 
        if (size != 0)
391
 
        {
392
 
                if (!PLAB (A->file, slang_asm_local_free, size))
393
 
                        return GL_FALSE;
394
 
        }
395
 
 
396
 
        return GL_TRUE;
 
391
   slang_assembly_typeinfo ti;
 
392
   GLuint size = 0;
 
393
 
 
394
   /* get type info of the operation and calculate its size */
 
395
   if (!slang_assembly_typeinfo_construct(&ti))
 
396
      return GL_FALSE;
 
397
   if (!_slang_typeof_operation(A, op, &ti)) {
 
398
      slang_assembly_typeinfo_destruct(&ti);
 
399
      return GL_FALSE;
 
400
   }
 
401
   if (ti.spec.type != slang_spec_void) {
 
402
      if (A->ref == slang_ref_force) {
 
403
         size = 4;
 
404
      }
 
405
      else if (!sizeof_variable(A, &ti.spec, slang_qual_none, 0, &size)) {
 
406
         slang_assembly_typeinfo_destruct(&ti);
 
407
         return GL_FALSE;
 
408
      }
 
409
   }
 
410
   slang_assembly_typeinfo_destruct(&ti);
 
411
 
 
412
   /* if nonzero, free it from the stack */
 
413
   if (size != 0) {
 
414
      if (!PLAB(A->file, slang_asm_local_free, size))
 
415
         return GL_FALSE;
 
416
   }
 
417
 
 
418
   return GL_TRUE;
397
419
}
398
420
 
399
421
/* _slang_assemble_operation() */
400
422
 
401
423
static GLboolean
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)
404
426
{
405
427
   GLuint src_offset;
406
428
   slang_assembly_type ty;
407
429
 
408
 
   *size -= _slang_sizeof_type (type);
 
430
   *size -= _slang_sizeof_type(type);
409
431
 
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
412
 
    * instructions).
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
 
436
    * to read.
414
437
    */
415
438
   if (is_swizzled)
416
439
      src_offset = swz->swizzle[*size / 4] * 4;
418
441
      src_offset = *size;
419
442
 
420
443
   /* dereference data slot of a basic type */
421
 
   if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
 
444
   if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
422
445
      return GL_FALSE;
423
 
   if (!PUSH (A->file, slang_asm_addr_deref))
 
446
   if (!PUSH(A->file, slang_asm_addr_deref))
424
447
      return GL_FALSE;
425
448
   if (src_offset != 0) {
426
 
      if (!PLAB (A->file, slang_asm_addr_push, src_offset))
 
449
      if (!PLAB(A->file, slang_asm_addr_push, src_offset))
427
450
         return GL_FALSE;
428
 
      if (!PUSH (A->file, slang_asm_addr_add))
 
451
      if (!PUSH(A->file, slang_asm_addr_add))
429
452
         return GL_FALSE;
430
453
   }
431
454
 
449
472
      ty = slang_asm_none;
450
473
   }
451
474
 
452
 
   return PUSH (A->file, ty);
 
475
   return PUSH(A->file, ty);
453
476
}
454
477
 
455
478
static GLboolean
456
 
dereference_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLuint *size,
457
 
                       slang_swizzle *swz, GLboolean is_swizzled)
 
479
dereference_aggregate(slang_assemble_ctx * A,
 
480
                      const slang_storage_aggregate * agg, GLuint * size,
 
481
                      slang_swizzle * swz, GLboolean is_swizzled)
458
482
{
459
483
   GLuint i;
460
484
 
464
488
 
465
489
      for (j = arr->length; j > 0; j--) {
466
490
         if (arr->type == slang_stor_aggregate) {
467
 
            if (!dereference_aggregate (A, arr->aggregate, size, swz, is_swizzled))
 
491
            if (!dereference_aggregate
 
492
                (A, arr->aggregate, size, swz, is_swizzled))
468
493
               return GL_FALSE;
469
494
         }
470
495
         else {
471
496
            if (is_swizzled && arr->type == slang_stor_vec4) {
472
 
               if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled))
473
 
                  return GL_FALSE;
474
 
               if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled))
475
 
                  return GL_FALSE;
476
 
               if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled))
477
 
                  return GL_FALSE;
478
 
               if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled))
 
497
               if (!dereference_basic
 
498
                   (A, slang_stor_float, size, swz, is_swizzled))
 
499
                  return GL_FALSE;
 
500
               if (!dereference_basic
 
501
                   (A, slang_stor_float, size, swz, is_swizzled))
 
502
                  return GL_FALSE;
 
503
               if (!dereference_basic
 
504
                   (A, slang_stor_float, size, swz, is_swizzled))
 
505
                  return GL_FALSE;
 
506
               if (!dereference_basic
 
507
                   (A, slang_stor_float, size, swz, is_swizzled))
479
508
                  return GL_FALSE;
480
509
            }
481
510
            else {
482
 
               if (!dereference_basic (A, arr->type, size, swz, is_swizzled))
 
511
               if (!dereference_basic(A, arr->type, size, swz, is_swizzled))
483
512
                  return GL_FALSE;
484
513
            }
485
514
         }
489
518
   return GL_TRUE;
490
519
}
491
520
 
492
 
GLboolean _slang_dereference (slang_assemble_ctx *A, slang_operation *op)
493
 
{
494
 
        slang_assembly_typeinfo ti;
495
 
        GLboolean result = GL_FALSE;
496
 
        slang_storage_aggregate agg;
497
 
        GLuint size;
498
 
 
499
 
        /* get type information of the given operation */
500
 
        if (!slang_assembly_typeinfo_construct (&ti))
501
 
                return GL_FALSE;
502
 
        if (!_slang_typeof_operation (A, op, &ti))
503
 
                goto end1;
504
 
 
505
 
        /* construct aggregate from the type info */
506
 
        if (!slang_storage_aggregate_construct (&agg))
507
 
                goto end1;
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))
510
 
                goto end;
511
 
 
512
 
        /* dereference the resulting aggregate */
513
 
        size = _slang_sizeof_aggregate (&agg);
514
 
        result = dereference_aggregate (A, &agg, &size, &ti.swz, ti.is_swizzled);
515
 
 
516
 
end:
517
 
        slang_storage_aggregate_destruct (&agg);
518
 
end1:
519
 
        slang_assembly_typeinfo_destruct (&ti);
520
 
        return result;
521
 
}
522
 
 
523
 
GLboolean _slang_assemble_function_call (slang_assemble_ctx *A, slang_function *fun,
524
 
        slang_operation *params, GLuint param_count, GLboolean assignment)
525
 
{
526
 
        GLuint i;
527
 
        slang_swizzle p_swz[64];
528
 
        slang_ref_type p_ref[64];
529
 
 
530
 
        /* TODO: fix this, allocate dynamically */
531
 
        if (param_count > 64)
532
 
                return GL_FALSE;
533
 
 
534
 
        /* make room for the return value, if any */
535
 
        if (fun->header.type.specifier.type != slang_spec_void)
536
 
        {
537
 
                GLuint ret_size = 0;
538
 
 
539
 
                if (!sizeof_variable (A, &fun->header.type.specifier, slang_qual_none, 0, &ret_size))
540
 
                        return GL_FALSE;
541
 
                if (!PLAB (A->file, slang_asm_local_alloc, ret_size))
542
 
                        return GL_FALSE;
543
 
        }
544
 
 
545
 
        /* push the actual parameters on the stack */
546
 
        for (i = 0; i < param_count; i++)
547
 
        {
548
 
                if (fun->parameters->variables[i].type.qualifier == slang_qual_inout ||
549
 
                        fun->parameters->variables[i].type.qualifier == slang_qual_out)
550
 
                {
551
 
                        if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
552
 
                                return GL_FALSE;
553
 
                        /* TODO: optimize the "out" parameter case */
554
 
                        if (!_slang_assemble_operation (A, &params[i], slang_ref_force))
555
 
                                return GL_FALSE;
556
 
                        p_swz[i] = A->swz;
557
 
                        p_ref[i] = A->ref;
558
 
                        if (!PUSH (A->file, slang_asm_addr_copy))
559
 
                                return GL_FALSE;
560
 
                        if (!PUSH (A->file, slang_asm_addr_deref))
561
 
                                return GL_FALSE;
562
 
                        if (i == 0 && assignment)
563
 
                        {
564
 
                                /* duplicate the resulting address */
565
 
                                if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
566
 
                                        return GL_FALSE;
567
 
                                if (!PUSH (A->file, slang_asm_addr_deref))
568
 
                                        return GL_FALSE;
569
 
                        }
570
 
                        if (!_slang_dereference (A, &params[i]))
571
 
                                return GL_FALSE;
572
 
                }
573
 
                else
574
 
                {
575
 
                        if (!_slang_assemble_operation (A, &params[i], slang_ref_forbid))
576
 
                                return GL_FALSE;
577
 
                        p_swz[i] = A->swz;
578
 
                        p_ref[i] = A->ref;
579
 
                }
580
 
        }
581
 
 
582
 
        /* call the function */
583
 
        if (!PLAB (A->file, slang_asm_call, fun->address))
584
 
                return GL_FALSE;
585
 
 
586
 
        /* pop the parameters from the stack */
587
 
        for (i = param_count; i > 0; i--)
588
 
        {
589
 
                GLuint j = i - 1;
590
 
 
591
 
                A->swz = p_swz[j];
592
 
                A->ref = p_ref[j];
593
 
                if (fun->parameters->variables[j].type.qualifier == slang_qual_inout ||
594
 
                        fun->parameters->variables[j].type.qualifier == slang_qual_out)
595
 
                {
596
 
                        /* for output parameter copy the contents of the formal parameter
597
 
                         * back to the original actual parameter */
598
 
                        if (!_slang_assemble_assignment (A, &params[j]))
599
 
                                return GL_FALSE;
600
 
                        /* pop the actual parameter's address */
601
 
                        if (!PLAB (A->file, slang_asm_local_free, 4))
602
 
                                return GL_FALSE;
603
 
                }
604
 
                else
605
 
                {
606
 
                        /* pop the value of the parameter */
607
 
                        if (!_slang_cleanup_stack (A, &params[j]))
608
 
                                return GL_FALSE;
609
 
                }
610
 
        }
611
 
 
612
 
        return GL_TRUE;
613
 
}
614
 
 
615
 
GLboolean _slang_assemble_function_call_name (slang_assemble_ctx *A, const char *name,
616
 
        slang_operation *params, GLuint param_count, GLboolean assignment)
617
 
{
618
 
        slang_atom atom;
619
 
        slang_function *fun;
620
 
 
621
 
        atom = slang_atom_pool_atom (A->atoms, name);
622
 
        if (atom == SLANG_ATOM_NULL)
623
 
                return GL_FALSE;
624
 
        fun = _slang_locate_function (A->space.funcs, atom, params, param_count, &A->space, A->atoms);
625
 
        if (fun == NULL)
626
 
                return GL_FALSE;
627
 
        return _slang_assemble_function_call (A, fun, params, param_count, assignment);
628
 
}
629
 
 
630
 
static GLboolean assemble_function_call_name_dummyint (slang_assemble_ctx *A, const char *name,
631
 
        slang_operation *params)
632
 
{
633
 
        slang_operation p[2];
634
 
        GLboolean result;
635
 
 
636
 
        p[0] = params[0];
637
 
        if (!slang_operation_construct (&p[1]))
638
 
                return GL_FALSE;
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]);
642
 
        return result;
 
521
GLboolean
 
522
_slang_dereference(slang_assemble_ctx * A, slang_operation * op)
 
523
{
 
524
   slang_assembly_typeinfo ti;
 
525
   GLboolean result = GL_FALSE;
 
526
   slang_storage_aggregate agg;
 
527
   GLuint size;
 
528
 
 
529
   /* get type information of the given operation */
 
530
   if (!slang_assembly_typeinfo_construct(&ti))
 
531
      return GL_FALSE;
 
532
   if (!_slang_typeof_operation(A, op, &ti))
 
533
      goto end1;
 
534
 
 
535
   /* construct aggregate from the type info */
 
536
   if (!slang_storage_aggregate_construct(&agg))
 
537
      goto end1;
 
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))
 
541
      goto end;
 
542
 
 
543
   /* dereference the resulting aggregate */
 
544
   size = _slang_sizeof_aggregate(&agg);
 
545
   result = dereference_aggregate(A, &agg, &size, &ti.swz, ti.is_swizzled);
 
546
 
 
547
 end:
 
548
   slang_storage_aggregate_destruct(&agg);
 
549
 end1:
 
550
   slang_assembly_typeinfo_destruct(&ti);
 
551
   return result;
 
552
}
 
553
 
 
554
GLboolean
 
555
_slang_assemble_function_call(slang_assemble_ctx * A, slang_function * fun,
 
556
                              slang_operation * params, GLuint param_count,
 
557
                              GLboolean assignment)
 
558
{
 
559
   GLuint i;
 
560
   slang_swizzle p_swz[64];
 
561
   slang_ref_type p_ref[64];
 
562
 
 
563
   /* TODO: fix this, allocate dynamically */
 
564
   if (param_count > 64)
 
565
      return GL_FALSE;
 
566
 
 
567
   /* make room for the return value, if any */
 
568
   if (fun->header.type.specifier.type != slang_spec_void) {
 
569
      GLuint ret_size = 0;
 
570
 
 
571
      if (!sizeof_variable
 
572
          (A, &fun->header.type.specifier, slang_qual_none, 0, &ret_size))
 
573
         return GL_FALSE;
 
574
      if (!PLAB(A->file, slang_asm_local_alloc, ret_size))
 
575
         return GL_FALSE;
 
576
   }
 
577
 
 
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))
 
583
            return GL_FALSE;
 
584
         /* TODO: optimize the "out" parameter case */
 
585
         if (!_slang_assemble_operation(A, &params[i], slang_ref_force))
 
586
            return GL_FALSE;
 
587
         p_swz[i] = A->swz;
 
588
         p_ref[i] = A->ref;
 
589
         if (!PUSH(A->file, slang_asm_addr_copy))
 
590
            return GL_FALSE;
 
591
         if (!PUSH(A->file, slang_asm_addr_deref))
 
592
            return GL_FALSE;
 
593
         if (i == 0 && assignment) {
 
594
            /* duplicate the resulting address */
 
595
            if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
 
596
               return GL_FALSE;
 
597
            if (!PUSH(A->file, slang_asm_addr_deref))
 
598
               return GL_FALSE;
 
599
         }
 
600
         if (!_slang_dereference(A, &params[i]))
 
601
            return GL_FALSE;
 
602
      }
 
603
      else {
 
604
         if (!_slang_assemble_operation(A, &params[i], slang_ref_forbid))
 
605
            return GL_FALSE;
 
606
         p_swz[i] = A->swz;
 
607
         p_ref[i] = A->ref;
 
608
      }
 
609
   }
 
610
 
 
611
   /* call the function */
 
612
   if (!PLAB(A->file, slang_asm_call, fun->address))
 
613
      return GL_FALSE;
 
614
 
 
615
   /* pop the parameters from the stack */
 
616
   for (i = param_count; i > 0; i--) {
 
617
      GLuint j = i - 1;
 
618
 
 
619
      A->swz = p_swz[j];
 
620
      A->ref = p_ref[j];
 
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
 
625
          */
 
626
         if (!_slang_assemble_assignment(A, &params[j]))
 
627
            return GL_FALSE;
 
628
         /* pop the actual parameter's address */
 
629
         if (!PLAB(A->file, slang_asm_local_free, 4))
 
630
            return GL_FALSE;
 
631
      }
 
632
      else {
 
633
         /* pop the value of the parameter */
 
634
         if (!_slang_cleanup_stack(A, &params[j]))
 
635
            return GL_FALSE;
 
636
      }
 
637
   }
 
638
 
 
639
   return GL_TRUE;
 
640
}
 
641
 
 
642
GLboolean
 
643
_slang_assemble_function_call_name(slang_assemble_ctx * A, const char *name,
 
644
                                   slang_operation * params,
 
645
                                   GLuint param_count, GLboolean assignment)
 
646
{
 
647
   slang_atom atom;
 
648
   slang_function *fun;
 
649
 
 
650
   atom = slang_atom_pool_atom(A->atoms, name);
 
651
   if (atom == SLANG_ATOM_NULL)
 
652
      return GL_FALSE;
 
653
   fun =
 
654
      _slang_locate_function(A->space.funcs, atom, params, param_count,
 
655
                             &A->space, A->atoms);
 
656
   if (fun == NULL)
 
657
      return GL_FALSE;
 
658
   return _slang_assemble_function_call(A, fun, params, param_count,
 
659
                                        assignment);
 
660
}
 
661
 
 
662
static GLboolean
 
663
assemble_function_call_name_dummyint(slang_assemble_ctx * A, const char *name,
 
664
                                     slang_operation * params)
 
665
{
 
666
   slang_operation p[2];
 
667
   GLboolean result;
 
668
 
 
669
   p[0] = params[0];
 
670
   if (!slang_operation_construct(&p[1]))
 
671
      return GL_FALSE;
 
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]);
 
675
   return result;
643
676
}
644
677
 
645
678
static const struct
646
679
{
647
 
        const char *name;
648
 
        slang_assembly_type code1, code2;
 
680
   const char *name;
 
681
   slang_assembly_type code1, code2;
649
682
} inst[] = {
650
 
        /* core */
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 },
 
683
   /* core */
 
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},
680
713
   /* vec4 */
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 },
688
 
 
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}
690
722
};
691
723
 
692
 
static GLboolean call_asm_instruction (slang_assemble_ctx *A, slang_atom a_name)
 
724
static GLboolean
 
725
call_asm_instruction(slang_assemble_ctx * A, slang_atom a_name)
693
726
{
694
 
        const char *id;
695
 
        GLuint i;
696
 
 
697
 
        id = slang_atom_pool_id (A->atoms, a_name);
698
 
 
699
 
        for (i = 0; inst[i].name != NULL; i++)
700
 
                if (slang_string_compare (id, inst[i].name) == 0)
701
 
                        break;
702
 
        if (inst[i].name == NULL)
703
 
                return GL_FALSE;
704
 
 
705
 
        if (!PLAB2 (A->file, inst[i].code1, 4, 0))
706
 
                return GL_FALSE;
707
 
        if (inst[i].code2 != slang_asm_none)
708
 
                if (!PLAB2 (A->file, inst[i].code2, 4, 0))
709
 
                        return GL_FALSE;
710
 
 
711
 
        /* clean-up the stack from the remaining dst address */
712
 
        if (!PLAB (A->file, slang_asm_local_free, 4))
713
 
                return GL_FALSE;
714
 
 
715
 
        return GL_TRUE;
 
727
   const char *id;
 
728
   GLuint i;
 
729
 
 
730
   id = slang_atom_pool_id(A->atoms, a_name);
 
731
 
 
732
   for (i = 0; inst[i].name != NULL; i++)
 
733
      if (slang_string_compare(id, inst[i].name) == 0)
 
734
         break;
 
735
   if (inst[i].name == NULL)
 
736
      return GL_FALSE;
 
737
 
 
738
   if (!PLAB2(A->file, inst[i].code1, 4, 0))
 
739
      return GL_FALSE;
 
740
   if (inst[i].code2 != slang_asm_none)
 
741
      if (!PLAB2(A->file, inst[i].code2, 4, 0))
 
742
         return GL_FALSE;
 
743
 
 
744
   /* clean-up the stack from the remaining dst address */
 
745
   if (!PLAB(A->file, slang_asm_local_free, 4))
 
746
      return GL_FALSE;
 
747
 
 
748
   return GL_TRUE;
716
749
}
717
750
 
718
751
static GLboolean
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)
721
755
{
722
756
   GLuint i;
723
757
 
727
761
 
728
762
      for (j = 0; j < arr->length; j++) {
729
763
         if (arr->type == slang_stor_aggregate) {
730
 
            if (!equality_aggregate (A, arr->aggregate, index, size, z_label))
 
764
            if (!equality_aggregate(A, arr->aggregate, index, size, z_label))
731
765
               return GL_FALSE;
732
766
         }
733
767
         else {
734
768
#if defined(USE_X86_ASM) || defined(SLANG_X86)
735
769
            if (arr->type == slang_stor_vec4) {
736
 
               if (!PLAB2 (A->file, slang_asm_vec4_equal_int, size + *index, *index))
 
770
               if (!PLAB2
 
771
                   (A->file, slang_asm_vec4_equal_int, size + *index, *index))
737
772
                  return GL_FALSE;
738
773
            }
739
774
            else
740
775
#endif
741
 
               if (!PLAB2 (A->file, slang_asm_float_equal_int, size + *index, *index))
742
 
                  return GL_FALSE;
 
776
            if (!PLAB2
 
777
                   (A->file, slang_asm_float_equal_int, size + *index,
 
778
                       *index))
 
779
               return GL_FALSE;
743
780
 
744
 
            *index += _slang_sizeof_type (arr->type);
745
 
            if (!PLAB (A->file, slang_asm_jump_if_zero, z_label))
 
781
            *index += _slang_sizeof_type(arr->type);
 
782
            if (!PLAB(A->file, slang_asm_jump_if_zero, z_label))
746
783
               return GL_FALSE;
747
784
         }
748
785
      }
751
788
   return GL_TRUE;
752
789
}
753
790
 
754
 
static GLboolean equality (slang_assemble_ctx *A, slang_operation *op, GLboolean equal)
755
 
{
756
 
        slang_assembly_typeinfo ti;
757
 
        GLboolean result = GL_FALSE;
758
 
        slang_storage_aggregate agg;
759
 
        GLuint index, size;
760
 
        GLuint skip_jump, true_label, true_jump, false_label, false_jump;
761
 
 
762
 
        /* get type of operation */
763
 
        if (!slang_assembly_typeinfo_construct (&ti))
764
 
                return GL_FALSE;
765
 
        if (!_slang_typeof_operation (A, op, &ti))
766
 
                goto end1;
767
 
 
768
 
        /* convert it to an aggregate */
769
 
        if (!slang_storage_aggregate_construct (&agg))
770
 
                goto end1;
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))
773
 
                goto end;
774
 
 
775
 
        /* compute the size of the agregate - there are two such aggregates on the stack */
776
 
        size = _slang_sizeof_aggregate (&agg);
777
 
 
778
 
        /* jump to the actual data-comparison code */
779
 
        skip_jump = A->file->count;
780
 
        if (!PUSH (A->file, slang_asm_jump))
781
 
                goto end;
782
 
 
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))
786
 
                goto end;
787
 
        if (!PLIT (A->file, slang_asm_bool_push, (GLfloat) 1))
788
 
                goto end;
789
 
        true_jump = A->file->count;
790
 
        if (!PUSH (A->file, slang_asm_jump))
791
 
                goto end;
792
 
 
793
 
        false_label = A->file->count;
794
 
        if (!PLAB (A->file, slang_asm_local_free, size * 2))
795
 
                goto end;
796
 
        if (!PLIT (A->file, slang_asm_bool_push, (GLfloat) 0))
797
 
                goto end;
798
 
        false_jump = A->file->count;
799
 
        if (!PUSH (A->file, slang_asm_jump))
800
 
                goto end;
801
 
 
802
 
        A->file->code[skip_jump].param[0] = A->file->count;
803
 
 
804
 
        /* compare the data on stack, it will eventually jump either to true or false label */
805
 
        index = 0;
806
 
        if (!equality_aggregate (A, &agg, &index, size, equal ? false_label : true_label))
807
 
                goto end;
808
 
        if (!PLAB (A->file, slang_asm_jump, equal ? true_label : false_label))
809
 
                goto end;
810
 
 
811
 
        A->file->code[true_jump].param[0] = A->file->count;
812
 
        A->file->code[false_jump].param[0] = A->file->count;
813
 
 
814
 
        result = GL_TRUE;
815
 
end:
816
 
        slang_storage_aggregate_destruct (&agg);
817
 
end1:
818
 
        slang_assembly_typeinfo_destruct (&ti);
819
 
        return result;
820
 
}
821
 
 
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)
824
 
{
825
 
        GLuint asize = 0, esize = 0;
826
 
 
827
 
        /* get type info of the master expression (matrix, vector or an array */
828
 
        if (!_slang_typeof_operation (A, &op->children[0], tia))
829
 
                return GL_FALSE;
830
 
        if (!sizeof_variable (A, &tia->spec, slang_qual_none, tia->array_len, &asize))
831
 
                return GL_FALSE;
832
 
 
833
 
        /* get type info of the result (matrix column, vector row or array element) */
834
 
        if (!_slang_typeof_operation (A, op, tie))
835
 
                return GL_FALSE;
836
 
        if (!sizeof_variable (A, &tie->spec, slang_qual_none, 0, &esize))
837
 
                return GL_FALSE;
838
 
 
839
 
        /* assemble the master expression */
840
 
        if (!_slang_assemble_operation (A, &op->children[0], ref))
841
 
                return GL_FALSE;
842
 
 
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))
846
 
                        return GL_FALSE;
847
 
 
848
 
        /* assemble the subscript expression */
849
 
        if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
850
 
                return GL_FALSE;
851
 
 
852
 
        if (ref == slang_ref_force && tia->is_swizzled)
853
 
        {
854
 
                GLuint i;
855
 
 
856
 
                /* copy the swizzle indexes to the swizzle_tmp */
857
 
                for (i = 0; i < tia->swz.num_components; i++)
858
 
                {
859
 
                        if (!PLAB2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
860
 
                                return GL_FALSE;
861
 
                        if (!PLAB (A->file, slang_asm_addr_push, i * 4))
862
 
                                return GL_FALSE;
863
 
                        if (!PUSH (A->file, slang_asm_addr_add))
864
 
                                return GL_FALSE;
865
 
                        if (!PLAB (A->file, slang_asm_addr_push, tia->swz.swizzle[i]))
866
 
                                return GL_FALSE;
867
 
                        if (!PUSH (A->file, slang_asm_addr_copy))
868
 
                                return GL_FALSE;
869
 
                        if (!PLAB (A->file, slang_asm_local_free, 4))
870
 
                                return GL_FALSE;
871
 
                }
872
 
 
873
 
                /* offset the pushed swizzle_tmp address and dereference it */
874
 
                if (!PUSH (A->file, slang_asm_int_to_addr))
875
 
                        return GL_FALSE;
876
 
                if (!PLAB (A->file, slang_asm_addr_push, 4))
877
 
                        return GL_FALSE;
878
 
                if (!PUSH (A->file, slang_asm_addr_multiply))
879
 
                        return GL_FALSE;
880
 
                if (!PUSH (A->file, slang_asm_addr_add))
881
 
                        return GL_FALSE;
882
 
                if (!PUSH (A->file, slang_asm_addr_deref))
883
 
                        return GL_FALSE;
884
 
        }
885
 
        else
886
 
        {
887
 
                /* convert the integer subscript to a relative address */
888
 
                if (!PUSH (A->file, slang_asm_int_to_addr))
889
 
                        return GL_FALSE;
890
 
        }
891
 
 
892
 
        if (!PLAB (A->file, slang_asm_addr_push, esize))
893
 
                return GL_FALSE;
894
 
        if (!PUSH (A->file, slang_asm_addr_multiply))
895
 
                return GL_FALSE;
896
 
 
897
 
        if (ref == slang_ref_force)
898
 
        {
899
 
                /* offset the base address with the relative address */
900
 
                if (!PUSH (A->file, slang_asm_addr_add))
901
 
                        return GL_FALSE;
902
 
        }
903
 
        else
904
 
        {
905
 
                GLuint i;
906
 
 
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))
910
 
                                return GL_FALSE;
911
 
                if (!PLAB (A->file, slang_asm_local_free, 4))
912
 
                        return GL_FALSE;
913
 
 
914
 
                /* free the rest of the master expression */
915
 
                if (!PLAB (A->file, slang_asm_local_free, asize - esize))
916
 
                        return GL_FALSE;
917
 
        }
918
 
 
919
 
        return GL_TRUE;
920
 
}
921
 
 
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)
924
 
{
925
 
        /* get type info of the result (field or swizzle) */
926
 
        if (!_slang_typeof_operation (A, op, tia))
927
 
                return GL_FALSE;
928
 
 
929
 
        /* get type info of the master expression being accessed (struct or vector) */
930
 
        if (!_slang_typeof_operation (A, &op->children[0], tib))
931
 
                return GL_FALSE;
932
 
 
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))
936
 
                        return GL_FALSE;
937
 
 
938
 
        /* assemble the master expression */
939
 
        if (!_slang_assemble_operation (A, &op->children[0], ref))
940
 
                return GL_FALSE;
941
 
 
942
 
        /* assemble the field expression */
943
 
        if (tia->is_swizzled)
944
 
        {
945
 
                if (ref == slang_ref_force)
946
 
                {
 
791
static GLboolean
 
792
equality(slang_assemble_ctx * A, slang_operation * op, GLboolean equal)
 
793
{
 
794
   slang_assembly_typeinfo ti;
 
795
   GLboolean result = GL_FALSE;
 
796
   slang_storage_aggregate agg;
 
797
   GLuint index, size;
 
798
   GLuint skip_jump, true_label, true_jump, false_label, false_jump;
 
799
 
 
800
   /* get type of operation */
 
801
   if (!slang_assembly_typeinfo_construct(&ti))
 
802
      return GL_FALSE;
 
803
   if (!_slang_typeof_operation(A, op, &ti))
 
804
      goto end1;
 
805
 
 
806
   /* convert it to an aggregate */
 
807
   if (!slang_storage_aggregate_construct(&agg))
 
808
      goto end1;
 
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))
 
812
      goto end;
 
813
 
 
814
   /* compute the size of the agregate - there are two such aggregates on the stack */
 
815
   size = _slang_sizeof_aggregate(&agg);
 
816
 
 
817
   /* jump to the actual data-comparison code */
 
818
   skip_jump = A->file->count;
 
819
   if (!PUSH(A->file, slang_asm_jump))
 
820
      goto end;
 
821
 
 
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))
 
825
      goto end;
 
826
   if (!PLIT(A->file, slang_asm_bool_push, (GLfloat) 1))
 
827
      goto end;
 
828
   true_jump = A->file->count;
 
829
   if (!PUSH(A->file, slang_asm_jump))
 
830
      goto end;
 
831
 
 
832
   false_label = A->file->count;
 
833
   if (!PLAB(A->file, slang_asm_local_free, size * 2))
 
834
      goto end;
 
835
   if (!PLIT(A->file, slang_asm_bool_push, (GLfloat) 0))
 
836
      goto end;
 
837
   false_jump = A->file->count;
 
838
   if (!PUSH(A->file, slang_asm_jump))
 
839
      goto end;
 
840
 
 
841
   A->file->code[skip_jump].param[0] = A->file->count;
 
842
 
 
843
   /* compare the data on stack, it will eventually jump either to true or false label */
 
844
   index = 0;
 
845
   if (!equality_aggregate
 
846
       (A, &agg, &index, size, equal ? false_label : true_label))
 
847
      goto end;
 
848
   if (!PLAB(A->file, slang_asm_jump, equal ? true_label : false_label))
 
849
      goto end;
 
850
 
 
851
   A->file->code[true_jump].param[0] = A->file->count;
 
852
   A->file->code[false_jump].param[0] = A->file->count;
 
853
 
 
854
   result = GL_TRUE;
 
855
 end:
 
856
   slang_storage_aggregate_destruct(&agg);
 
857
 end1:
 
858
   slang_assembly_typeinfo_destruct(&ti);
 
859
   return result;
 
860
}
 
861
 
 
862
static GLboolean
 
863
handle_subscript(slang_assemble_ctx * A, slang_assembly_typeinfo * tie,
 
864
                 slang_assembly_typeinfo * tia, slang_operation * op,
 
865
                 slang_ref_type ref)
 
866
{
 
867
   GLuint asize = 0, esize = 0;
 
868
 
 
869
   /* get type info of the master expression (matrix, vector or an array */
 
870
   if (!_slang_typeof_operation(A, &op->children[0], tia))
 
871
      return GL_FALSE;
 
872
   if (!sizeof_variable
 
873
       (A, &tia->spec, slang_qual_none, tia->array_len, &asize))
 
874
      return GL_FALSE;
 
875
 
 
876
   /* get type info of the result (matrix column, vector row or array element) */
 
877
   if (!_slang_typeof_operation(A, op, tie))
 
878
      return GL_FALSE;
 
879
   if (!sizeof_variable(A, &tie->spec, slang_qual_none, 0, &esize))
 
880
      return GL_FALSE;
 
881
 
 
882
   /* assemble the master expression */
 
883
   if (!_slang_assemble_operation(A, &op->children[0], ref))
 
884
      return GL_FALSE;
 
885
 
 
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))
 
889
         return GL_FALSE;
 
890
 
 
891
   /* assemble the subscript expression */
 
892
   if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid))
 
893
      return GL_FALSE;
 
894
 
 
895
   if (ref == slang_ref_force && tia->is_swizzled) {
 
896
      GLuint i;
 
897
 
 
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))
 
901
            return GL_FALSE;
 
902
         if (!PLAB(A->file, slang_asm_addr_push, i * 4))
 
903
            return GL_FALSE;
 
904
         if (!PUSH(A->file, slang_asm_addr_add))
 
905
            return GL_FALSE;
 
906
         if (!PLAB(A->file, slang_asm_addr_push, tia->swz.swizzle[i]))
 
907
            return GL_FALSE;
 
908
         if (!PUSH(A->file, slang_asm_addr_copy))
 
909
            return GL_FALSE;
 
910
         if (!PLAB(A->file, slang_asm_local_free, 4))
 
911
            return GL_FALSE;
 
912
      }
 
913
 
 
914
      /* offset the pushed swizzle_tmp address and dereference it */
 
915
      if (!PUSH(A->file, slang_asm_int_to_addr))
 
916
         return GL_FALSE;
 
917
      if (!PLAB(A->file, slang_asm_addr_push, 4))
 
918
         return GL_FALSE;
 
919
      if (!PUSH(A->file, slang_asm_addr_multiply))
 
920
         return GL_FALSE;
 
921
      if (!PUSH(A->file, slang_asm_addr_add))
 
922
         return GL_FALSE;
 
923
      if (!PUSH(A->file, slang_asm_addr_deref))
 
924
         return GL_FALSE;
 
925
   }
 
926
   else {
 
927
      /* convert the integer subscript to a relative address */
 
928
      if (!PUSH(A->file, slang_asm_int_to_addr))
 
929
         return GL_FALSE;
 
930
   }
 
931
 
 
932
   if (!PLAB(A->file, slang_asm_addr_push, esize))
 
933
      return GL_FALSE;
 
934
   if (!PUSH(A->file, slang_asm_addr_multiply))
 
935
      return GL_FALSE;
 
936
 
 
937
   if (ref == slang_ref_force) {
 
938
      /* offset the base address with the relative address */
 
939
      if (!PUSH(A->file, slang_asm_addr_add))
 
940
         return GL_FALSE;
 
941
   }
 
942
   else {
 
943
      GLuint i;
 
944
 
 
945
      /* move the selected element to the beginning of the master expression */
 
946
      for (i = 0; i < esize; i += 4)
 
947
         if (!PLAB2
 
948
             (A->file, slang_asm_float_move, asize - esize + i + 4, i + 4))
 
949
            return GL_FALSE;
 
950
      if (!PLAB(A->file, slang_asm_local_free, 4))
 
951
         return GL_FALSE;
 
952
 
 
953
      /* free the rest of the master expression */
 
954
      if (!PLAB(A->file, slang_asm_local_free, asize - esize))
 
955
         return GL_FALSE;
 
956
   }
 
957
 
 
958
   return GL_TRUE;
 
959
}
 
960
 
 
961
static GLboolean
 
962
handle_field(slang_assemble_ctx * A, slang_assembly_typeinfo * tia,
 
963
             slang_assembly_typeinfo * tib, slang_operation * op,
 
964
             slang_ref_type ref)
 
965
{
 
966
   /* get type info of the result (field or swizzle) */
 
967
   if (!_slang_typeof_operation(A, op, tia))
 
968
      return GL_FALSE;
 
969
 
 
970
   /* get type info of the master expression being accessed (struct or vector) */
 
971
   if (!_slang_typeof_operation(A, &op->children[0], tib))
 
972
      return GL_FALSE;
 
973
 
 
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))
 
977
         return GL_FALSE;
 
978
 
 
979
   /* assemble the master expression */
 
980
   if (!_slang_assemble_operation(A, &op->children[0], ref))
 
981
      return GL_FALSE;
 
982
 
 
983
   /* assemble the field expression */
 
984
   if (tia->is_swizzled) {
 
985
      if (ref == slang_ref_force) {
947
986
#if 0
948
 
                        if (tia->swz.num_components == 1)
949
 
                        {
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))
952
 
                                        return 0;
953
 
                                if (!PUSH (file, slang_asm_addr_add))
954
 
                                        return 0;
955
 
                        }
956
 
                        else
 
987
         if (tia->swz.num_components == 1) {
 
988
            /* simple case - adjust the vector's address to point to
 
989
             * the selected component
 
990
             */
 
991
            if (!PLAB(file, slang_asm_addr_push, tia->swz.swizzle[0] * 4))
 
992
               return 0;
 
993
            if (!PUSH(file, slang_asm_addr_add))
 
994
               return 0;
 
995
         }
 
996
         else
957
997
#endif
958
 
                        {
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
961
 
                                 * to this swizzle */
962
 
                                A->swz = tia->swz;
963
 
                        }
964
 
                }
965
 
                else
966
 
                {
967
 
                        /* swizzle the vector in-place using the swizzle temporary */
968
 
                        if (!_slang_assemble_constructor_from_swizzle (A, &tia->swz, &tia->spec, &tib->spec))
969
 
                                return GL_FALSE;
970
 
                }
971
 
        }
972
 
        else
973
 
        {
974
 
                GLuint i, struct_size = 0, field_offset = 0, field_size = 0;
 
998
         {
 
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
 
1002
             */
 
1003
            A->swz = tia->swz;
 
1004
         }
 
1005
      }
 
1006
      else {
 
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))
 
1010
            return GL_FALSE;
 
1011
      }
 
1012
   }
 
1013
   else {
 
1014
      GLuint i, struct_size = 0, field_offset = 0, field_size = 0;
975
1015
 
976
1016
      /*
977
1017
       * Calculate struct size, field offset and field size.
978
1018
       */
979
 
                for (i = 0; i < tib->spec._struct->fields->num_variables; i++)
980
 
                {
981
 
                        slang_variable *field;
982
 
                        slang_storage_aggregate agg;
983
 
                        GLuint size;
 
1019
      for (i = 0; i < tib->spec._struct->fields->num_variables; i++) {
 
1020
         slang_variable *field;
 
1021
         slang_storage_aggregate agg;
 
1022
         GLuint size;
984
1023
 
985
 
                        field = &tib->spec._struct->fields->variables[i];
986
 
                        if (!slang_storage_aggregate_construct (&agg))
987
 
                                return GL_FALSE;
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))
990
 
                        {
991
 
                                slang_storage_aggregate_destruct (&agg);
992
 
                                return GL_FALSE;
993
 
                        }
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))
 
1026
            return GL_FALSE;
 
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);
 
1031
            return GL_FALSE;
 
1032
         }
 
1033
         size = _slang_sizeof_aggregate(&agg);
 
1034
         slang_storage_aggregate_destruct(&agg);
996
1035
 
997
1036
         if (op->a_id == field->a_name) {
998
1037
            field_size = size;
999
1038
            field_offset = struct_size;
1000
1039
         }
1001
1040
         struct_size += size;
1002
 
                }
 
1041
      }
1003
1042
 
1004
 
                if (ref == slang_ref_force)
1005
 
                {
 
1043
      if (ref == slang_ref_force) {
1006
1044
         GLboolean shift;
1007
1045
 
1008
1046
         /*
1009
 
         * OPTIMIZATION: If selecting first field, no address shifting is needed.
1010
 
         */
 
1047
          * OPTIMIZATION: If selecting first field, no address shifting
 
1048
          * is needed.
 
1049
          */
1011
1050
         shift = (field_offset != 0);
1012
1051
 
1013
1052
         if (shift) {
1014
 
            if (!PLAB (A->file, slang_asm_addr_push, field_offset))
1015
 
               return GL_FALSE;
1016
 
                                if (!PUSH (A->file, slang_asm_addr_add))
1017
 
                                        return GL_FALSE;
1018
 
                        }
1019
 
                }
1020
 
                else
1021
 
                {
 
1053
            if (!PLAB(A->file, slang_asm_addr_push, field_offset))
 
1054
               return GL_FALSE;
 
1055
            if (!PUSH(A->file, slang_asm_addr_add))
 
1056
               return GL_FALSE;
 
1057
         }
 
1058
      }
 
1059
      else {
1022
1060
         GLboolean relocate, shrink;
1023
 
                        GLuint free_b = 0;
 
1061
         GLuint free_b = 0;
1024
1062
 
1025
1063
         /*
1026
 
         * OPTIMIZATION: If selecting last field, no relocation is needed.
1027
 
         */
 
1064
          * OPTIMIZATION: If selecting last field, no relocation is needed.
 
1065
          */
1028
1066
         relocate = (field_offset != (struct_size - field_size));
1029
1067
 
1030
1068
         /*
1031
 
         * OPTIMIZATION: If field and struct sizes are equal, no partial free is needed.
1032
 
         */
 
1069
          * OPTIMIZATION: If field and struct sizes are equal, no partial
 
1070
          * free is needed.
 
1071
          */
1033
1072
         shrink = (field_size != struct_size);
1034
1073
 
1035
 
                        if (relocate)
1036
 
                        {
1037
 
                                GLuint i;
1038
 
 
1039
 
                                /*
1040
 
                                 * Move the selected element to the end of the master expression.
1041
 
                                 * Do it in reverse order to avoid overwriting itself.
1042
 
                                 */
1043
 
            if (!PLAB (A->file, slang_asm_addr_push, field_offset))
1044
 
               return GL_FALSE;
1045
 
                                for (i = field_size; i > 0; i -= 4)
1046
 
                                        if (!PLAB2 (A->file, slang_asm_float_move, struct_size - field_size + i, i))
1047
 
                                                return GL_FALSE;
1048
 
                                free_b += 4;
1049
 
                        }
1050
 
 
1051
 
                        if (shrink)
1052
 
                        {
1053
 
                                /* free the rest of the master expression */
1054
 
                                free_b += struct_size - field_size;
1055
 
                        }
1056
 
 
1057
 
                        if (free_b)
1058
 
                        {
1059
 
                                if (!PLAB (A->file, slang_asm_local_free, free_b))
1060
 
                                        return GL_FALSE;
1061
 
                        }
1062
 
                }
1063
 
        }
1064
 
 
1065
 
        return GL_TRUE;
 
1074
         if (relocate) {
 
1075
            GLuint i;
 
1076
 
 
1077
            /*
 
1078
             * Move the selected element to the end of the master expression.
 
1079
             * Do it in reverse order to avoid overwriting itself.
 
1080
             */
 
1081
            if (!PLAB(A->file, slang_asm_addr_push, field_offset))
 
1082
               return GL_FALSE;
 
1083
            for (i = field_size; i > 0; i -= 4)
 
1084
               if (!PLAB2
 
1085
                   (A->file, slang_asm_float_move,
 
1086
                    struct_size - field_size + i, i))
 
1087
                  return GL_FALSE;
 
1088
            free_b += 4;
 
1089
         }
 
1090
 
 
1091
         if (shrink) {
 
1092
            /* free the rest of the master expression */
 
1093
            free_b += struct_size - field_size;
 
1094
         }
 
1095
 
 
1096
         if (free_b) {
 
1097
            if (!PLAB(A->file, slang_asm_local_free, free_b))
 
1098
               return GL_FALSE;
 
1099
         }
 
1100
      }
 
1101
   }
 
1102
 
 
1103
   return GL_TRUE;
1066
1104
}
1067
1105
 
1068
 
GLboolean _slang_assemble_operation (slang_assemble_ctx *A, slang_operation *op, slang_ref_type ref)
 
1106
GLboolean
 
1107
_slang_assemble_operation(slang_assemble_ctx * A, slang_operation * op,
 
1108
                          slang_ref_type ref)
1069
1109
{
1070
 
        /* set default results */
1071
 
        A->ref = /*(ref == slang_ref_freelance) ? slang_ref_force : */ref;
1072
 
        A->swz.num_components = 0;
1073
 
 
1074
 
        switch (op->type)
1075
 
        {
1076
 
        case slang_oper_block_no_new_scope:
1077
 
        case slang_oper_block_new_scope:
1078
 
                {
1079
 
                        GLuint i;
1080
 
 
1081
 
                        for (i = 0; i < op->num_children; i++)
1082
 
                        {
1083
 
                                if (!_slang_assemble_operation (A, &op->children[i], slang_ref_forbid/*slang_ref_freelance*/))
1084
 
                                        return GL_FALSE;
1085
 
                                if (!_slang_cleanup_stack (A, &op->children[i]))
1086
 
                                        return GL_FALSE;
1087
 
                        }
1088
 
                }
1089
 
                break;
1090
 
        case slang_oper_variable_decl:
1091
 
                {
1092
 
                        GLuint i;
1093
 
                        slang_operation assign;
1094
 
                        GLboolean result;
1095
 
 
1096
 
                        /* Construct assignment expression placeholder. */
1097
 
                        if (!slang_operation_construct (&assign))
1098
 
                                return GL_FALSE;
1099
 
                        assign.type = slang_oper_assign;
1100
 
                        assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));
1101
 
                        if (assign.children == NULL)
1102
 
                        {
1103
 
                                slang_operation_destruct (&assign);
1104
 
                                return GL_FALSE;
1105
 
                        }
1106
 
                        for (assign.num_children = 0; assign.num_children < 2; assign.num_children++)
1107
 
                                if (!slang_operation_construct (&assign.children[assign.num_children]))
1108
 
                                {
1109
 
                                        slang_operation_destruct (&assign);
1110
 
                                        return GL_FALSE;
1111
 
                                }
1112
 
 
1113
 
                        result = GL_TRUE;
1114
 
                        for (i = 0; i < op->num_children; i++)
1115
 
                        {
1116
 
                                slang_variable *var;
1117
 
 
1118
 
                                var = _slang_locate_variable (op->children[i].locals, op->children[i].a_id, GL_TRUE);
1119
 
                                if (var == NULL)
1120
 
                                {
1121
 
                                        result = GL_FALSE;
1122
 
                                        break;
1123
 
                                }
1124
 
                                if (var->initializer == NULL)
1125
 
                                        continue;
1126
 
 
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))
1131
 
                                {
1132
 
                                        result = GL_FALSE;
1133
 
                                        break;
1134
 
                                }
1135
 
                        }
1136
 
                        slang_operation_destruct (&assign);
1137
 
                        if (!result)
1138
 
                                return GL_FALSE;
1139
 
                }
1140
 
                break;
1141
 
        case slang_oper_asm:
1142
 
                {
1143
 
                        GLuint i;
1144
 
 
1145
 
                        if (!_slang_assemble_operation (A, &op->children[0], slang_ref_force))
1146
 
                                return GL_FALSE;
1147
 
                        for (i = 1; i < op->num_children; i++)
1148
 
                                if (!_slang_assemble_operation (A, &op->children[i], slang_ref_forbid))
1149
 
                                        return GL_FALSE;
1150
 
                        if (!call_asm_instruction (A, op->a_id))
1151
 
                                return GL_FALSE;
1152
 
                }
1153
 
                break;
1154
 
        case slang_oper_break:
1155
 
                if (!PLAB (A->file, slang_asm_jump, A->flow.loop_end))
1156
 
                        return GL_FALSE;
1157
 
                break;
1158
 
        case slang_oper_continue:
1159
 
                if (!PLAB (A->file, slang_asm_jump, A->flow.loop_start))
1160
 
                        return GL_FALSE;
1161
 
                break;
1162
 
        case slang_oper_discard:
1163
 
                if (!PUSH (A->file, slang_asm_discard))
1164
 
                        return GL_FALSE;
1165
 
                if (!PUSH (A->file, slang_asm_exit))
1166
 
                        return GL_FALSE;
1167
 
                break;
1168
 
        case slang_oper_return:
1169
 
                if (A->local.ret_size != 0)
1170
 
                {
1171
 
                        /* push the result's address */
1172
 
                        if (!PLAB2 (A->file, slang_asm_local_addr, 0, A->local.ret_size))
1173
 
                                return GL_FALSE;
1174
 
                        if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
1175
 
                                return GL_FALSE;
1176
 
 
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))
1180
 
                                return GL_FALSE;
1181
 
 
1182
 
                        if (!PLAB (A->file, slang_asm_local_free, 4))
1183
 
                                return GL_FALSE;
1184
 
                }
1185
 
                if (!PLAB (A->file, slang_asm_jump, A->flow.function_end))
1186
 
                        return GL_FALSE;
1187
 
                break;
1188
 
        case slang_oper_expression:
1189
 
                if (ref == slang_ref_force)
1190
 
                        return GL_FALSE;
1191
 
                if (!_slang_assemble_operation (A, &op->children[0], ref))
1192
 
                        return GL_FALSE;
1193
 
                break;
1194
 
        case slang_oper_if:
1195
 
                if (!_slang_assemble_if (A, op))
1196
 
                        return GL_FALSE;
1197
 
                break;
1198
 
        case slang_oper_while:
1199
 
                if (!_slang_assemble_while (A, op))
1200
 
                        return GL_FALSE;
1201
 
                break;
1202
 
        case slang_oper_do:
1203
 
                if (!_slang_assemble_do (A, op))
1204
 
                        return GL_FALSE;
1205
 
                break;
1206
 
        case slang_oper_for:
1207
 
                if (!_slang_assemble_for (A, op))
1208
 
                        return GL_FALSE;
1209
 
                break;
1210
 
        case slang_oper_void:
1211
 
                break;
1212
 
        case slang_oper_literal_bool:
1213
 
                if (ref == slang_ref_force)
1214
 
                        return GL_FALSE;
1215
 
                if (!PLIT (A->file, slang_asm_bool_push, op->literal))
1216
 
                        return GL_FALSE;
1217
 
                A->ref = slang_ref_forbid;
1218
 
                break;
1219
 
        case slang_oper_literal_int:
1220
 
                if (ref == slang_ref_force)
1221
 
                        return GL_FALSE;
1222
 
                if (!PLIT (A->file, slang_asm_int_push, op->literal))
1223
 
                        return GL_FALSE;
1224
 
                A->ref = slang_ref_forbid;
1225
 
                break;
1226
 
        case slang_oper_literal_float:
1227
 
                if (ref == slang_ref_force)
1228
 
                        return GL_FALSE;
1229
 
                if (!PLIT (A->file, slang_asm_float_push, op->literal))
1230
 
                        return GL_FALSE;
1231
 
                A->ref = slang_ref_forbid;
1232
 
                break;
1233
 
        case slang_oper_identifier:
1234
 
                {
1235
 
                        slang_variable *var;
1236
 
                        GLuint size;
1237
 
 
1238
 
                        /* find the variable and calculate its size */
1239
 
                        var = _slang_locate_variable (op->locals, op->a_id, GL_TRUE);
1240
 
                        if (var == NULL)
1241
 
                                return GL_FALSE;
1242
 
                        size = 0;
1243
 
                        if (!sizeof_variable (A, &var->type.specifier, slang_qual_none, var->array_len, &size))
1244
 
                                return GL_FALSE;
1245
 
 
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))
1249
 
                                        return GL_FALSE;
1250
 
 
1251
 
                        /* push the variable's address */
1252
 
                        if (var->global)
1253
 
                        {
1254
 
                                if (!PLAB (A->file, slang_asm_global_addr, var->address))
1255
 
                                        return GL_FALSE;
1256
 
                        }
1257
 
                        else
1258
 
                        {
1259
 
                                if (!PLAB2 (A->file, slang_asm_local_addr, var->address, size))
1260
 
                                        return GL_FALSE;
1261
 
                        }
1262
 
 
1263
 
                        /* perform the dereference */
1264
 
                        if (ref == slang_ref_forbid)
1265
 
                        {
1266
 
                                if (!PUSH (A->file, slang_asm_addr_copy))
1267
 
                                        return GL_FALSE;
1268
 
                                if (!PLAB (A->file, slang_asm_local_free, 4))
1269
 
                                        return GL_FALSE;
1270
 
                                if (!_slang_dereference (A, op))
1271
 
                                        return GL_FALSE;
1272
 
                        }
1273
 
                }
1274
 
                break;
1275
 
        case slang_oper_sequence:
1276
 
                if (ref == slang_ref_force)
1277
 
                        return GL_FALSE;
1278
 
                if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid/*slang_ref_freelance*/))
1279
 
                        return GL_FALSE;
1280
 
                if (!_slang_cleanup_stack (A, &op->children[0]))
1281
 
                        return GL_FALSE;
1282
 
                if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
1283
 
                        return GL_FALSE;
1284
 
                A->ref = slang_ref_forbid;
1285
 
                break;
1286
 
        case slang_oper_assign:
1287
 
                if (!_slang_assemble_assign (A, op, "=", ref))
1288
 
                        return GL_FALSE;
1289
 
                break;
1290
 
        case slang_oper_addassign:
1291
 
                if (!_slang_assemble_assign (A, op, "+=", ref))
1292
 
                        return GL_FALSE;
1293
 
                A->ref = ref;
1294
 
                break;
1295
 
        case slang_oper_subassign:
1296
 
                if (!_slang_assemble_assign (A, op, "-=", ref))
1297
 
                        return GL_FALSE;
1298
 
                A->ref = ref;
1299
 
                break;
1300
 
        case slang_oper_mulassign:
1301
 
                if (!_slang_assemble_assign (A, op, "*=", ref))
1302
 
                        return GL_FALSE;
1303
 
                A->ref = ref;
1304
 
                break;
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))
1313
 
                        return GL_FALSE;
1314
 
                A->ref = ref;
1315
 
                break;
1316
 
        case slang_oper_select:
1317
 
                if (!_slang_assemble_select (A, op))
1318
 
                        return GL_FALSE;
1319
 
                A->ref = slang_ref_forbid;
1320
 
                break;
1321
 
        case slang_oper_logicalor:
1322
 
                if (!_slang_assemble_logicalor (A, op))
1323
 
                        return GL_FALSE;
1324
 
                A->ref = slang_ref_forbid;
1325
 
                break;
1326
 
        case slang_oper_logicaland:
1327
 
                if (!_slang_assemble_logicaland (A, op))
1328
 
                        return GL_FALSE;
1329
 
                A->ref = slang_ref_forbid;
1330
 
                break;
1331
 
        case slang_oper_logicalxor:
1332
 
                if (!_slang_assemble_function_call_name (A, "^^", op->children, 2, GL_FALSE))
1333
 
                        return GL_FALSE;
1334
 
                A->ref = slang_ref_forbid;
1335
 
                break;
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))
1341
 
                        return GL_FALSE;
1342
 
                A->ref = slang_ref_forbid;
1343
 
                break;
1344
 
        case slang_oper_greater:
1345
 
                if (!_slang_assemble_function_call_name (A, ">", op->children, 2, GL_FALSE))
1346
 
                        return GL_FALSE;
1347
 
                A->ref = slang_ref_forbid;
1348
 
                break;
1349
 
        case slang_oper_lessequal:
1350
 
                if (!_slang_assemble_function_call_name (A, "<=", op->children, 2, GL_FALSE))
1351
 
                        return GL_FALSE;
1352
 
                A->ref = slang_ref_forbid;
1353
 
                break;
1354
 
        case slang_oper_greaterequal:
1355
 
                if (!_slang_assemble_function_call_name (A, ">=", op->children, 2, GL_FALSE))
1356
 
                        return GL_FALSE;
1357
 
                A->ref = slang_ref_forbid;
1358
 
                break;
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))
1363
 
                        return GL_FALSE;
1364
 
                A->ref = slang_ref_forbid;
1365
 
                break;
1366
 
        case slang_oper_subtract:
1367
 
                if (!_slang_assemble_function_call_name (A, "-", op->children, 2, GL_FALSE))
1368
 
                        return GL_FALSE;
1369
 
                A->ref = slang_ref_forbid;
1370
 
                break;
1371
 
        case slang_oper_multiply:
1372
 
                if (!_slang_assemble_function_call_name (A, "*", op->children, 2, GL_FALSE))
1373
 
                        return GL_FALSE;
1374
 
                A->ref = slang_ref_forbid;
1375
 
                break;
1376
 
        /*case slang_oper_modulus:*/
1377
 
        case slang_oper_divide:
1378
 
                if (!_slang_assemble_function_call_name (A, "/", op->children, 2, GL_FALSE))
1379
 
                        return GL_FALSE;
1380
 
                A->ref = slang_ref_forbid;
1381
 
                break;
1382
 
        case slang_oper_equal:
1383
 
                if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
1384
 
                        return GL_FALSE;
1385
 
                if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
1386
 
                        return GL_FALSE;
1387
 
                if (!equality (A, op->children, GL_TRUE))
1388
 
                        return GL_FALSE;
1389
 
                A->ref = slang_ref_forbid;
1390
 
                break;
1391
 
        case slang_oper_notequal:
1392
 
                if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
1393
 
                        return GL_FALSE;
1394
 
                if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
1395
 
                        return GL_FALSE;
1396
 
                if (!equality (A, op->children, GL_FALSE))
1397
 
                        return GL_FALSE;
1398
 
                A->ref = slang_ref_forbid;
1399
 
                break;
1400
 
        case slang_oper_preincrement:
1401
 
                if (!_slang_assemble_assign (A, op, "++", ref))
1402
 
                        return GL_FALSE;
1403
 
                A->ref = ref;
1404
 
                break;
1405
 
        case slang_oper_predecrement:
1406
 
                if (!_slang_assemble_assign (A, op, "--", ref))
1407
 
                        return GL_FALSE;
1408
 
                A->ref = ref;
1409
 
                break;
1410
 
        case slang_oper_plus:
1411
 
                if (!_slang_dereference (A, op))
1412
 
                        return GL_FALSE;
1413
 
                A->ref = slang_ref_forbid;
1414
 
                break;
1415
 
        case slang_oper_minus:
1416
 
                if (!_slang_assemble_function_call_name (A, "-", op->children, 1, GL_FALSE))
1417
 
                        return GL_FALSE;
1418
 
                A->ref = slang_ref_forbid;
1419
 
                break;
1420
 
        /*case slang_oper_complement:*/
1421
 
        case slang_oper_not:
1422
 
                if (!_slang_assemble_function_call_name (A, "!", op->children, 1, GL_FALSE))
1423
 
                        return GL_FALSE;
1424
 
                A->ref = slang_ref_forbid;
1425
 
                break;
1426
 
        case slang_oper_subscript:
1427
 
                {
1428
 
                        slang_assembly_typeinfo ti_arr, ti_elem;
1429
 
 
1430
 
                        if (!slang_assembly_typeinfo_construct (&ti_arr))
1431
 
                                return GL_FALSE;
1432
 
                        if (!slang_assembly_typeinfo_construct (&ti_elem))
1433
 
                        {
1434
 
                                slang_assembly_typeinfo_destruct (&ti_arr);
1435
 
                                return GL_FALSE;
1436
 
                        }
1437
 
                        if (!handle_subscript (A, &ti_elem, &ti_arr, op, ref))
1438
 
                        {
1439
 
                                slang_assembly_typeinfo_destruct (&ti_arr);
1440
 
                                slang_assembly_typeinfo_destruct (&ti_elem);
1441
 
                                return GL_FALSE;
1442
 
                        }
1443
 
                        slang_assembly_typeinfo_destruct (&ti_arr);
1444
 
                        slang_assembly_typeinfo_destruct (&ti_elem);
1445
 
                }
1446
 
                break;
1447
 
        case slang_oper_call:
1448
 
                {
1449
 
                        slang_function *fun;
1450
 
 
1451
 
                        fun = _slang_locate_function (A->space.funcs, op->a_id, op->children, op->num_children,
1452
 
                                &A->space, A->atoms);
1453
 
                        if (fun == NULL)
1454
 
                        {
1455
 
                                if (!_slang_assemble_constructor (A, op))
1456
 
                                        return GL_FALSE;
1457
 
                        }
1458
 
                        else
1459
 
                        {
1460
 
                                if (!_slang_assemble_function_call (A, fun, op->children, op->num_children, GL_FALSE))
1461
 
                                        return GL_FALSE;
1462
 
                        }
1463
 
                        A->ref = slang_ref_forbid;
1464
 
                }
1465
 
                break;
1466
 
        case slang_oper_field:
1467
 
                {
1468
 
                        slang_assembly_typeinfo ti_after, ti_before;
1469
 
 
1470
 
                        if (!slang_assembly_typeinfo_construct (&ti_after))
1471
 
                                return GL_FALSE;
1472
 
                        if (!slang_assembly_typeinfo_construct (&ti_before))
1473
 
                        {
1474
 
                                slang_assembly_typeinfo_destruct (&ti_after);
1475
 
                                return GL_FALSE;
1476
 
                        }
1477
 
                        if (!handle_field (A, &ti_after, &ti_before, op, ref))
1478
 
                        {
1479
 
                                slang_assembly_typeinfo_destruct (&ti_after);
1480
 
                                slang_assembly_typeinfo_destruct (&ti_before);
1481
 
                                return GL_FALSE;
1482
 
                        }
1483
 
                        slang_assembly_typeinfo_destruct (&ti_after);
1484
 
                        slang_assembly_typeinfo_destruct (&ti_before);
1485
 
                }
1486
 
                break;
1487
 
        case slang_oper_postincrement:
1488
 
                if (!assemble_function_call_name_dummyint (A, "++", op->children))
1489
 
                        return GL_FALSE;
1490
 
                A->ref = slang_ref_forbid;
1491
 
                break;
1492
 
        case slang_oper_postdecrement:
1493
 
                if (!assemble_function_call_name_dummyint (A, "--", op->children))
1494
 
                        return GL_FALSE;
1495
 
                A->ref = slang_ref_forbid;
1496
 
                break;
1497
 
        default:
1498
 
                return GL_FALSE;
1499
 
        }
1500
 
 
1501
 
        return GL_TRUE;
 
1110
   /* set default results */
 
1111
   A->ref = /*(ref == slang_ref_freelance) ? slang_ref_force : */ ref;
 
1112
   A->swz.num_components = 0;
 
1113
 
 
1114
   switch (op->type) {
 
1115
   case slang_oper_block_no_new_scope:
 
1116
   case slang_oper_block_new_scope:
 
1117
      {
 
1118
         GLuint i;
 
1119
 
 
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 */ ))
 
1124
               return GL_FALSE;
 
1125
            if (!_slang_cleanup_stack(A, &op->children[i]))
 
1126
               return GL_FALSE;
 
1127
         }
 
1128
      }
 
1129
      break;
 
1130
   case slang_oper_variable_decl:
 
1131
      {
 
1132
         GLuint i;
 
1133
         slang_operation assign;
 
1134
         GLboolean result;
 
1135
 
 
1136
         /* Construct assignment expression placeholder. */
 
1137
         if (!slang_operation_construct(&assign))
 
1138
            return GL_FALSE;
 
1139
         assign.type = slang_oper_assign;
 
1140
         assign.children =
 
1141
            (slang_operation *) slang_alloc_malloc(2 *
 
1142
                                                   sizeof(slang_operation));
 
1143
         if (assign.children == NULL) {
 
1144
            slang_operation_destruct(&assign);
 
1145
            return GL_FALSE;
 
1146
         }
 
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);
 
1152
               return GL_FALSE;
 
1153
            }
 
1154
 
 
1155
         result = GL_TRUE;
 
1156
         for (i = 0; i < op->num_children; i++) {
 
1157
            slang_variable *var;
 
1158
 
 
1159
            var =
 
1160
               _slang_locate_variable(op->children[i].locals,
 
1161
                                      op->children[i].a_id, GL_TRUE);
 
1162
            if (var == NULL) {
 
1163
               result = GL_FALSE;
 
1164
               break;
 
1165
            }
 
1166
            if (var->initializer == NULL)
 
1167
               continue;
 
1168
 
 
1169
            if (!slang_operation_copy(&assign.children[0], &op->children[i])
 
1170
                || !slang_operation_copy(&assign.children[1],
 
1171
                                         var->initializer)
 
1172
                || !_slang_assemble_assign(A, &assign, "=", slang_ref_forbid)
 
1173
                || !_slang_cleanup_stack(A, &assign)) {
 
1174
               result = GL_FALSE;
 
1175
               break;
 
1176
            }
 
1177
         }
 
1178
         slang_operation_destruct(&assign);
 
1179
         if (!result)
 
1180
            return GL_FALSE;
 
1181
      }
 
1182
      break;
 
1183
   case slang_oper_asm:
 
1184
      {
 
1185
         GLuint i;
 
1186
         if (!_slang_assemble_operation(A, &op->children[0], slang_ref_force))
 
1187
            return GL_FALSE;
 
1188
         for (i = 1; i < op->num_children; i++)
 
1189
            if (!_slang_assemble_operation
 
1190
                (A, &op->children[i], slang_ref_forbid))
 
1191
               return GL_FALSE;
 
1192
         if (!call_asm_instruction(A, op->a_id))
 
1193
            return GL_FALSE;
 
1194
      }
 
1195
      break;
 
1196
   case slang_oper_break:
 
1197
      if (!PLAB(A->file, slang_asm_jump, A->flow.loop_end))
 
1198
         return GL_FALSE;
 
1199
      break;
 
1200
   case slang_oper_continue:
 
1201
      if (!PLAB(A->file, slang_asm_jump, A->flow.loop_start))
 
1202
         return GL_FALSE;
 
1203
      break;
 
1204
   case slang_oper_discard:
 
1205
      if (!PUSH(A->file, slang_asm_discard))
 
1206
         return GL_FALSE;
 
1207
      if (!PUSH(A->file, slang_asm_exit))
 
1208
         return GL_FALSE;
 
1209
      break;
 
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))
 
1214
            return GL_FALSE;
 
1215
         if (!_slang_assemble_operation
 
1216
             (A, &op->children[0], slang_ref_forbid))
 
1217
            return GL_FALSE;
 
1218
 
 
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))
 
1222
            return GL_FALSE;
 
1223
 
 
1224
         if (!PLAB(A->file, slang_asm_local_free, 4))
 
1225
            return GL_FALSE;
 
1226
      }
 
1227
      if (!PLAB(A->file, slang_asm_jump, A->flow.function_end))
 
1228
         return GL_FALSE;
 
1229
      break;
 
1230
   case slang_oper_expression:
 
1231
      if (ref == slang_ref_force)
 
1232
         return GL_FALSE;
 
1233
      if (!_slang_assemble_operation(A, &op->children[0], ref))
 
1234
         return GL_FALSE;
 
1235
      break;
 
1236
   case slang_oper_if:
 
1237
      if (!_slang_assemble_if(A, op))
 
1238
         return GL_FALSE;
 
1239
      break;
 
1240
   case slang_oper_while:
 
1241
      if (!_slang_assemble_while(A, op))
 
1242
         return GL_FALSE;
 
1243
      break;
 
1244
   case slang_oper_do:
 
1245
      if (!_slang_assemble_do(A, op))
 
1246
         return GL_FALSE;
 
1247
      break;
 
1248
   case slang_oper_for:
 
1249
      if (!_slang_assemble_for(A, op))
 
1250
         return GL_FALSE;
 
1251
      break;
 
1252
   case slang_oper_void:
 
1253
      break;
 
1254
   case slang_oper_literal_bool:
 
1255
      if (ref == slang_ref_force)
 
1256
         return GL_FALSE;
 
1257
      if (!PLIT(A->file, slang_asm_bool_push, op->literal))
 
1258
         return GL_FALSE;
 
1259
      A->ref = slang_ref_forbid;
 
1260
      break;
 
1261
   case slang_oper_literal_int:
 
1262
      if (ref == slang_ref_force)
 
1263
         return GL_FALSE;
 
1264
      if (!PLIT(A->file, slang_asm_int_push, op->literal))
 
1265
         return GL_FALSE;
 
1266
      A->ref = slang_ref_forbid;
 
1267
      break;
 
1268
   case slang_oper_literal_float:
 
1269
      if (ref == slang_ref_force)
 
1270
         return GL_FALSE;
 
1271
      if (!PLIT(A->file, slang_asm_float_push, op->literal))
 
1272
         return GL_FALSE;
 
1273
      A->ref = slang_ref_forbid;
 
1274
      break;
 
1275
   case slang_oper_identifier:
 
1276
      {
 
1277
         slang_variable *var;
 
1278
         GLuint size;
 
1279
 
 
1280
         /* find the variable and calculate its size */
 
1281
         var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE);
 
1282
         if (var == NULL)
 
1283
            return GL_FALSE;
 
1284
         size = 0;
 
1285
         if (!sizeof_variable
 
1286
             (A, &var->type.specifier, slang_qual_none, var->array_len,
 
1287
              &size))
 
1288
            return GL_FALSE;
 
1289
 
 
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))
 
1293
               return GL_FALSE;
 
1294
 
 
1295
         /* push the variable's address */
 
1296
         if (var->global) {
 
1297
            if (!PLAB(A->file, slang_asm_global_addr, var->address))
 
1298
               return GL_FALSE;
 
1299
         }
 
1300
         else {
 
1301
            if (!PLAB2(A->file, slang_asm_local_addr, var->address, size))
 
1302
               return GL_FALSE;
 
1303
         }
 
1304
 
 
1305
         /* perform the dereference */
 
1306
         if (ref == slang_ref_forbid) {
 
1307
            if (!PUSH(A->file, slang_asm_addr_copy))
 
1308
               return GL_FALSE;
 
1309
            if (!PLAB(A->file, slang_asm_local_free, 4))
 
1310
               return GL_FALSE;
 
1311
            if (!_slang_dereference(A, op))
 
1312
               return GL_FALSE;
 
1313
         }
 
1314
      }
 
1315
      break;
 
1316
   case slang_oper_sequence:
 
1317
      if (ref == slang_ref_force)
 
1318
         return GL_FALSE;
 
1319
      if (!_slang_assemble_operation(A, &op->children[0],
 
1320
                                     slang_ref_forbid /*slang_ref_freelance */ ))
 
1321
         return GL_FALSE;
 
1322
      if (!_slang_cleanup_stack(A, &op->children[0]))
 
1323
         return GL_FALSE;
 
1324
      if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid))
 
1325
         return GL_FALSE;
 
1326
      A->ref = slang_ref_forbid;
 
1327
      break;
 
1328
   case slang_oper_assign:
 
1329
      if (!_slang_assemble_assign(A, op, "=", ref))
 
1330
         return GL_FALSE;
 
1331
      break;
 
1332
   case slang_oper_addassign:
 
1333
      if (!_slang_assemble_assign(A, op, "+=", ref))
 
1334
         return GL_FALSE;
 
1335
      A->ref = ref;
 
1336
      break;
 
1337
   case slang_oper_subassign:
 
1338
      if (!_slang_assemble_assign(A, op, "-=", ref))
 
1339
         return GL_FALSE;
 
1340
      A->ref = ref;
 
1341
      break;
 
1342
   case slang_oper_mulassign:
 
1343
      if (!_slang_assemble_assign(A, op, "*=", ref))
 
1344
         return GL_FALSE;
 
1345
      A->ref = ref;
 
1346
      break;
 
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))
 
1355
         return GL_FALSE;
 
1356
      A->ref = ref;
 
1357
      break;
 
1358
   case slang_oper_select:
 
1359
      if (!_slang_assemble_select(A, op))
 
1360
         return GL_FALSE;
 
1361
      A->ref = slang_ref_forbid;
 
1362
      break;
 
1363
   case slang_oper_logicalor:
 
1364
      if (!_slang_assemble_logicalor(A, op))
 
1365
         return GL_FALSE;
 
1366
      A->ref = slang_ref_forbid;
 
1367
      break;
 
1368
   case slang_oper_logicaland:
 
1369
      if (!_slang_assemble_logicaland(A, op))
 
1370
         return GL_FALSE;
 
1371
      A->ref = slang_ref_forbid;
 
1372
      break;
 
1373
   case slang_oper_logicalxor:
 
1374
      if (!_slang_assemble_function_call_name(A, "^^", op->children, 2, GL_FALSE))
 
1375
         return GL_FALSE;
 
1376
      A->ref = slang_ref_forbid;
 
1377
      break;
 
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))
 
1383
         return GL_FALSE;
 
1384
      A->ref = slang_ref_forbid;
 
1385
      break;
 
1386
   case slang_oper_greater:
 
1387
      if (!_slang_assemble_function_call_name(A, ">", op->children, 2, GL_FALSE))
 
1388
         return GL_FALSE;
 
1389
      A->ref = slang_ref_forbid;
 
1390
      break;
 
1391
   case slang_oper_lessequal:
 
1392
      if (!_slang_assemble_function_call_name(A, "<=", op->children, 2, GL_FALSE))
 
1393
         return GL_FALSE;
 
1394
      A->ref = slang_ref_forbid;
 
1395
      break;
 
1396
   case slang_oper_greaterequal:
 
1397
      if (!_slang_assemble_function_call_name(A, ">=", op->children, 2, GL_FALSE))
 
1398
         return GL_FALSE;
 
1399
      A->ref = slang_ref_forbid;
 
1400
      break;
 
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))
 
1405
         return GL_FALSE;
 
1406
      A->ref = slang_ref_forbid;
 
1407
      break;
 
1408
   case slang_oper_subtract:
 
1409
      if (!_slang_assemble_function_call_name(A, "-", op->children, 2, GL_FALSE))
 
1410
         return GL_FALSE;
 
1411
      A->ref = slang_ref_forbid;
 
1412
      break;
 
1413
   case slang_oper_multiply:
 
1414
      if (!_slang_assemble_function_call_name(A, "*", op->children, 2, GL_FALSE))
 
1415
         return GL_FALSE;
 
1416
      A->ref = slang_ref_forbid;
 
1417
      break;
 
1418
      /*case slang_oper_modulus: */
 
1419
   case slang_oper_divide:
 
1420
      if (!_slang_assemble_function_call_name(A, "/", op->children, 2, GL_FALSE))
 
1421
         return GL_FALSE;
 
1422
      A->ref = slang_ref_forbid;
 
1423
      break;
 
1424
   case slang_oper_equal:
 
1425
      if (!_slang_assemble_operation(A, &op->children[0], slang_ref_forbid))
 
1426
         return GL_FALSE;
 
1427
      if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid))
 
1428
         return GL_FALSE;
 
1429
      if (!equality(A, op->children, GL_TRUE))
 
1430
         return GL_FALSE;
 
1431
      A->ref = slang_ref_forbid;
 
1432
      break;
 
1433
   case slang_oper_notequal:
 
1434
      if (!_slang_assemble_operation(A, &op->children[0], slang_ref_forbid))
 
1435
         return GL_FALSE;
 
1436
      if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid))
 
1437
         return GL_FALSE;
 
1438
      if (!equality(A, op->children, GL_FALSE))
 
1439
         return GL_FALSE;
 
1440
      A->ref = slang_ref_forbid;
 
1441
      break;
 
1442
   case slang_oper_preincrement:
 
1443
      if (!_slang_assemble_assign(A, op, "++", ref))
 
1444
         return GL_FALSE;
 
1445
      A->ref = ref;
 
1446
      break;
 
1447
   case slang_oper_predecrement:
 
1448
      if (!_slang_assemble_assign(A, op, "--", ref))
 
1449
         return GL_FALSE;
 
1450
      A->ref = ref;
 
1451
      break;
 
1452
   case slang_oper_plus:
 
1453
      if (!_slang_dereference(A, op))
 
1454
         return GL_FALSE;
 
1455
      A->ref = slang_ref_forbid;
 
1456
      break;
 
1457
   case slang_oper_minus:
 
1458
      if (!_slang_assemble_function_call_name
 
1459
          (A, "-", op->children, 1, GL_FALSE))
 
1460
         return GL_FALSE;
 
1461
      A->ref = slang_ref_forbid;
 
1462
      break;
 
1463
      /*case slang_oper_complement: */
 
1464
   case slang_oper_not:
 
1465
      if (!_slang_assemble_function_call_name
 
1466
          (A, "!", op->children, 1, GL_FALSE))
 
1467
         return GL_FALSE;
 
1468
      A->ref = slang_ref_forbid;
 
1469
      break;
 
1470
   case slang_oper_subscript:
 
1471
      {
 
1472
         slang_assembly_typeinfo ti_arr, ti_elem;
 
1473
 
 
1474
         if (!slang_assembly_typeinfo_construct(&ti_arr))
 
1475
            return GL_FALSE;
 
1476
         if (!slang_assembly_typeinfo_construct(&ti_elem)) {
 
1477
            slang_assembly_typeinfo_destruct(&ti_arr);
 
1478
            return GL_FALSE;
 
1479
         }
 
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);
 
1483
            return GL_FALSE;
 
1484
         }
 
1485
         slang_assembly_typeinfo_destruct(&ti_arr);
 
1486
         slang_assembly_typeinfo_destruct(&ti_elem);
 
1487
      }
 
1488
      break;
 
1489
   case slang_oper_call:
 
1490
      {
 
1491
         slang_function *fun;
 
1492
 
 
1493
         fun =
 
1494
            _slang_locate_function(A->space.funcs, op->a_id, op->children,
 
1495
                                   op->num_children, &A->space, A->atoms);
 
1496
         if (fun == NULL) {
 
1497
            if (!_slang_assemble_constructor(A, op))
 
1498
               return GL_FALSE;
 
1499
         }
 
1500
         else {
 
1501
            if (!_slang_assemble_function_call
 
1502
                (A, fun, op->children, op->num_children, GL_FALSE))
 
1503
               return GL_FALSE;
 
1504
         }
 
1505
         A->ref = slang_ref_forbid;
 
1506
      }
 
1507
      break;
 
1508
   case slang_oper_field:
 
1509
      {
 
1510
         slang_assembly_typeinfo ti_after, ti_before;
 
1511
 
 
1512
         if (!slang_assembly_typeinfo_construct(&ti_after))
 
1513
            return GL_FALSE;
 
1514
         if (!slang_assembly_typeinfo_construct(&ti_before)) {
 
1515
            slang_assembly_typeinfo_destruct(&ti_after);
 
1516
            return GL_FALSE;
 
1517
         }
 
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);
 
1521
            return GL_FALSE;
 
1522
         }
 
1523
         slang_assembly_typeinfo_destruct(&ti_after);
 
1524
         slang_assembly_typeinfo_destruct(&ti_before);
 
1525
      }
 
1526
      break;
 
1527
   case slang_oper_postincrement:
 
1528
      if (!assemble_function_call_name_dummyint(A, "++", op->children))
 
1529
         return GL_FALSE;
 
1530
      A->ref = slang_ref_forbid;
 
1531
      break;
 
1532
   case slang_oper_postdecrement:
 
1533
      if (!assemble_function_call_name_dummyint(A, "--", op->children))
 
1534
         return GL_FALSE;
 
1535
      A->ref = slang_ref_forbid;
 
1536
      break;
 
1537
   default:
 
1538
      return GL_FALSE;
 
1539
   }
 
1540
 
 
1541
   return GL_TRUE;
1502
1542
}
1503