summaryrefslogtreecommitdiff
path: root/src/mesa/shader/slang
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2007-01-16 11:22:57 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2007-01-16 11:22:57 +0000
commit6a3fdc3a1ea6c306d9543791bf172dd1052d7382 (patch)
treec372c6daff13e435e79914c2e40dfe9d370c337b /src/mesa/shader/slang
parent0b412f8f156b46b0e7220a2b61e0f41781769f66 (diff)
parenta03fc8277180e2171519165a724849e2254ef0b7 (diff)
Merge branch 'master' of git+ssh://keithw@git.freedesktop.org/git/mesa/mesa into vbo-0.2
Conflicts: src/mesa/array_cache/sources src/mesa/drivers/dri/i965/brw_context.c src/mesa/drivers/dri/i965/brw_draw.c src/mesa/drivers/dri/i965/brw_fallback.c src/mesa/drivers/dri/i965/brw_vs_emit.c src/mesa/drivers/dri/i965/brw_vs_tnl.c src/mesa/drivers/dri/mach64/mach64_context.c src/mesa/main/extensions.c src/mesa/main/getstring.c src/mesa/tnl/sources src/mesa/tnl/t_save_api.c src/mesa/tnl/t_save_playback.c src/mesa/tnl/t_vtx_api.c src/mesa/tnl/t_vtx_exec.c src/mesa/vbo/vbo_attrib.h src/mesa/vbo/vbo_exec_api.c src/mesa/vbo/vbo_save_api.c src/mesa/vbo/vbo_save_draw.c
Diffstat (limited to 'src/mesa/shader/slang')
-rw-r--r--src/mesa/shader/slang/slang_assemble.c2473
-rw-r--r--src/mesa/shader/slang/slang_assemble.h288
-rw-r--r--src/mesa/shader/slang/slang_assemble_assignment.c184
-rw-r--r--src/mesa/shader/slang/slang_assemble_assignment.h17
-rw-r--r--src/mesa/shader/slang/slang_assemble_constructor.c628
-rw-r--r--src/mesa/shader/slang/slang_assemble_constructor.h45
-rw-r--r--src/mesa/shader/slang/slang_assemble_typeinfo.c1036
-rw-r--r--src/mesa/shader/slang/slang_assemble_typeinfo.h138
-rw-r--r--src/mesa/shader/slang/slang_compile.c3152
-rw-r--r--src/mesa/shader/slang/slang_compile_function.c252
-rw-r--r--src/mesa/shader/slang/slang_compile_function.h80
-rw-r--r--src/mesa/shader/slang/slang_compile_operation.c125
-rw-r--r--src/mesa/shader/slang/slang_compile_operation.h173
-rw-r--r--src/mesa/shader/slang/slang_compile_variable.c574
-rw-r--r--src/mesa/shader/slang/slang_compile_variable.h119
-rw-r--r--src/mesa/shader/slang/slang_execute.c1032
-rw-r--r--src/mesa/shader/slang/slang_execute.h66
-rw-r--r--src/mesa/shader/slang/slang_execute_x86.c1114
-rw-r--r--src/mesa/shader/slang/slang_link.h115
-rw-r--r--src/mesa/shader/slang/slang_preprocess.c8
-rw-r--r--src/mesa/shader/slang/slang_utility.c125
-rw-r--r--src/mesa/shader/slang/sources23
22 files changed, 6172 insertions, 5595 deletions
diff --git a/src/mesa/shader/slang/slang_assemble.c b/src/mesa/shader/slang/slang_assemble.c
index 36fb2305f6..0cba5d5d00 100644
--- a/src/mesa/shader/slang/slang_assemble.c
+++ b/src/mesa/shader/slang/slang_assemble.c
@@ -35,13 +35,15 @@
/* slang_assembly */
-static GLboolean slang_assembly_construct (slang_assembly *assem)
+static GLboolean
+slang_assembly_construct(slang_assembly * assem)
{
- assem->type = slang_asm_none;
- return GL_TRUE;
+ assem->type = slang_asm_none;
+ return GL_TRUE;
}
-static GLvoid slang_assembly_destruct (slang_assembly *assem)
+static GLvoid
+slang_assembly_destruct(slang_assembly * assem)
{
}
@@ -50,80 +52,89 @@ static GLvoid slang_assembly_destruct (slang_assembly *assem)
*/
GLvoid
-_slang_assembly_file_ctr (slang_assembly_file *self)
+_slang_assembly_file_ctr(slang_assembly_file * self)
{
self->code = NULL;
self->count = 0;
self->capacity = 0;
}
-GLvoid slang_assembly_file_destruct (slang_assembly_file *file)
+GLvoid
+slang_assembly_file_destruct(slang_assembly_file * file)
{
- GLuint i;
+ GLuint i;
- for (i = 0; i < file->count; i++)
- slang_assembly_destruct (&file->code[i]);
- slang_alloc_free (file->code);
+ for (i = 0; i < file->count; i++)
+ slang_assembly_destruct(&file->code[i]);
+ slang_alloc_free(file->code);
}
-static GLboolean push_new (slang_assembly_file *file)
+static GLboolean
+push_new(slang_assembly_file * file)
{
- if (file->count == file->capacity)
- {
- GLuint n;
-
- if (file->capacity == 0)
- n = 256;
- else
- n = file->capacity * 2;
- file->code = (slang_assembly *) slang_alloc_realloc (file->code,
- file->capacity * sizeof (slang_assembly), n * sizeof (slang_assembly));
- if (file->code == NULL)
- return GL_FALSE;
- file->capacity = n;
- }
- if (!slang_assembly_construct (&file->code[file->count]))
- return GL_FALSE;
- file->count++;
- return GL_TRUE;
+ if (file->count == file->capacity) {
+ GLuint n;
+
+ if (file->capacity == 0)
+ n = 256;
+ else
+ n = file->capacity * 2;
+ file->code = (slang_assembly *)
+ slang_alloc_realloc(file->code,
+ file->capacity * sizeof(slang_assembly),
+ n * sizeof(slang_assembly));
+ if (file->code == NULL)
+ return GL_FALSE;
+ file->capacity = n;
+ }
+ if (!slang_assembly_construct(&file->code[file->count]))
+ return GL_FALSE;
+ file->count++;
+ return GL_TRUE;
}
-static GLboolean push_gen (slang_assembly_file *file, slang_assembly_type type, GLfloat literal,
- GLuint label, GLuint size)
+static GLboolean
+push_gen(slang_assembly_file * file, slang_assembly_type type,
+ GLfloat literal, GLuint label, GLuint size)
{
- slang_assembly *assem;
-
- if (!push_new (file))
- return GL_FALSE;
- assem = &file->code[file->count - 1];
- assem->type = type;
- assem->literal = literal;
- assem->param[0] = label;
- assem->param[1] = size;
- return GL_TRUE;
+ slang_assembly *assem;
+
+ if (!push_new(file))
+ return GL_FALSE;
+ assem = &file->code[file->count - 1];
+ assem->type = type;
+ assem->literal = literal;
+ assem->param[0] = label;
+ assem->param[1] = size;
+ return GL_TRUE;
}
-GLboolean slang_assembly_file_push (slang_assembly_file *file, slang_assembly_type type)
+GLboolean
+slang_assembly_file_push(slang_assembly_file * file, slang_assembly_type type)
{
- return push_gen (file, type, (GLfloat) 0, 0, 0);
+ return push_gen(file, type, (GLfloat) 0, 0, 0);
}
-GLboolean slang_assembly_file_push_label (slang_assembly_file *file, slang_assembly_type type,
- GLuint label)
+GLboolean
+slang_assembly_file_push_label(slang_assembly_file * file,
+ slang_assembly_type type, GLuint label)
{
- return push_gen (file, type, (GLfloat) 0, label, 0);
+ return push_gen(file, type, (GLfloat) 0, label, 0);
}
-GLboolean slang_assembly_file_push_label2 (slang_assembly_file *file, slang_assembly_type type,
- GLuint label1, GLuint label2)
+GLboolean
+slang_assembly_file_push_label2(slang_assembly_file * file,
+ slang_assembly_type type, GLuint label1,
+ GLuint label2)
{
- return push_gen (file, type, (GLfloat) 0, label1, label2);
+ return push_gen(file, type, (GLfloat) 0, label1, label2);
}
-GLboolean slang_assembly_file_push_literal (slang_assembly_file *file, slang_assembly_type type,
- GLfloat literal)
+GLboolean
+slang_assembly_file_push_literal(slang_assembly_file * file,
+ slang_assembly_type type, GLfloat literal)
{
- return push_gen (file, type, literal, 0, 0);
+ return push_gen(file, type, literal, 0, 0);
}
#define PUSH slang_assembly_file_push
@@ -133,284 +144,296 @@ GLboolean slang_assembly_file_push_literal (slang_assembly_file *file, slang_ass
/* slang_assembly_file_restore_point */
-GLboolean slang_assembly_file_restore_point_save (slang_assembly_file *file,
- slang_assembly_file_restore_point *point)
+GLboolean
+slang_assembly_file_restore_point_save(slang_assembly_file * file,
+ slang_assembly_file_restore_point *
+ point)
{
- point->count = file->count;
- return GL_TRUE;
+ point->count = file->count;
+ return GL_TRUE;
}
-GLboolean slang_assembly_file_restore_point_load (slang_assembly_file *file,
- slang_assembly_file_restore_point *point)
+GLboolean
+slang_assembly_file_restore_point_load(slang_assembly_file * file,
+ slang_assembly_file_restore_point *
+ point)
{
- GLuint i;
+ GLuint i;
- for (i = point->count; i < file->count; i++)
- slang_assembly_destruct (&file->code[i]);
- file->count = point->count;
- return GL_TRUE;
+ for (i = point->count; i < file->count; i++)
+ slang_assembly_destruct(&file->code[i]);
+ file->count = point->count;
+ return GL_TRUE;
}
/* utility functions */
-static GLboolean sizeof_variable (slang_assemble_ctx *A, slang_type_specifier *spec,
- slang_type_qualifier qual, GLuint array_len, GLuint *size)
+static GLboolean
+sizeof_variable(slang_assemble_ctx * A, slang_type_specifier * spec,
+ slang_type_qualifier qual, GLuint array_len, GLuint * size)
{
- slang_storage_aggregate agg;
-
- /* calculate the size of the variable's aggregate */
- if (!slang_storage_aggregate_construct (&agg))
- return GL_FALSE;
- if (!_slang_aggregate_variable (&agg, spec, array_len, A->space.funcs, A->space.structs,
- A->space.vars, A->mach, A->file, A->atoms))
- {
- slang_storage_aggregate_destruct (&agg);
- return GL_FALSE;
- }
- *size += _slang_sizeof_aggregate (&agg);
- slang_storage_aggregate_destruct (&agg);
-
- /* for reference variables consider the additional address overhead */
- if (qual == slang_qual_out || qual == slang_qual_inout)
- *size += 4;
-
- return GL_TRUE;
+ slang_storage_aggregate agg;
+
+ /* calculate the size of the variable's aggregate */
+ if (!slang_storage_aggregate_construct(&agg))
+ return GL_FALSE;
+ if (!_slang_aggregate_variable
+ (&agg, spec, array_len, A->space.funcs, A->space.structs,
+ A->space.vars, A->mach, A->file, A->atoms)) {
+ slang_storage_aggregate_destruct(&agg);
+ return GL_FALSE;
+ }
+ *size += _slang_sizeof_aggregate(&agg);
+ slang_storage_aggregate_destruct(&agg);
+
+ /* for reference variables consider the additional address overhead */
+ if (qual == slang_qual_out || qual == slang_qual_inout)
+ *size += 4;
+
+ return GL_TRUE;
}
-static GLboolean sizeof_variable2 (slang_assemble_ctx *A, slang_variable *var, GLuint *size)
+static GLboolean
+sizeof_variable2(slang_assemble_ctx * A, slang_variable * var, GLuint * size)
{
- var->address = *size;
- if (var->type.qualifier == slang_qual_out || var->type.qualifier == slang_qual_inout)
- var->address += 4;
- return sizeof_variable (A, &var->type.specifier, var->type.qualifier, var->array_len, size);
+ var->address = *size;
+ if (var->type.qualifier == slang_qual_out
+ || var->type.qualifier == slang_qual_inout)
+ var->address += 4;
+ return sizeof_variable(A, &var->type.specifier, var->type.qualifier,
+ var->array_len, size);
}
-static GLboolean sizeof_variables (slang_assemble_ctx *A, slang_variable_scope *vars, GLuint start,
- GLuint stop, GLuint *size)
+static GLboolean
+sizeof_variables(slang_assemble_ctx * A, slang_variable_scope * vars,
+ GLuint start, GLuint stop, GLuint * size)
{
- GLuint i;
+ GLuint i;
- for (i = start; i < stop; i++)
- if (!sizeof_variable2 (A, &vars->variables[i], size))
- return GL_FALSE;
- return GL_TRUE;
+ for (i = start; i < stop; i++)
+ if (!sizeof_variable2(A, &vars->variables[i], size))
+ return GL_FALSE;
+ return GL_TRUE;
}
-static GLboolean collect_locals (slang_assemble_ctx *A, slang_operation *op, GLuint *size)
+static GLboolean
+collect_locals(slang_assemble_ctx * A, slang_operation * op, GLuint * size)
{
- GLuint i;
-
- if (!sizeof_variables (A, op->locals, 0, op->locals->num_variables, size))
- return GL_FALSE;
- for (i = 0; i < op->num_children; i++)
- if (!collect_locals (A, &op->children[i], size))
- return GL_FALSE;
- return GL_TRUE;
+ GLuint i;
+
+ if (!sizeof_variables(A, op->locals, 0, op->locals->num_variables, size))
+ return GL_FALSE;
+ for (i = 0; i < op->num_children; i++)
+ if (!collect_locals(A, &op->children[i], size))
+ return GL_FALSE;
+ return GL_TRUE;
}
/* _slang_locate_function() */
-slang_function *_slang_locate_function (slang_function_scope *funcs, slang_atom a_name,
- slang_operation *params, GLuint num_params, slang_assembly_name_space *space,
- slang_atom_pool *atoms)
+slang_function *
+_slang_locate_function(const slang_function_scope * funcs, slang_atom a_name,
+ const slang_operation * params, GLuint num_params,
+ const slang_assembly_name_space * space,
+ slang_atom_pool * atoms)
{
- GLuint i;
-
- for (i = 0; i < funcs->num_functions; i++)
- {
- GLuint j;
- slang_function *f = &funcs->functions[i];
-
- if (a_name != f->header.a_name)
- continue;
- if (f->param_count != num_params)
- continue;
- for (j = 0; j < num_params; j++)
- {
- slang_assembly_typeinfo ti;
-
- if (!slang_assembly_typeinfo_construct (&ti))
- return NULL;
- if (!_slang_typeof_operation_ (&params[j], space, &ti, atoms))
- {
- slang_assembly_typeinfo_destruct (&ti);
- return NULL;
- }
- if (!slang_type_specifier_equal (&ti.spec, &f->parameters->variables[j].type.specifier))
- {
- slang_assembly_typeinfo_destruct (&ti);
- break;
- }
- slang_assembly_typeinfo_destruct (&ti);
-
- /* "out" and "inout" formal parameter requires the actual parameter to be l-value */
- if (!ti.can_be_referenced &&
- (f->parameters->variables[j].type.qualifier == slang_qual_out ||
- f->parameters->variables[j].type.qualifier == slang_qual_inout))
- break;
- }
- if (j == num_params)
- return f;
- }
- if (funcs->outer_scope != NULL)
- return _slang_locate_function (funcs->outer_scope, a_name, params, num_params, space, atoms);
- return NULL;
+ GLuint i;
+
+ for (i = 0; i < funcs->num_functions; i++) {
+ GLuint j;
+ slang_function *f = &funcs->functions[i];
+
+ if (a_name != f->header.a_name)
+ continue;
+ if (f->param_count != num_params)
+ continue;
+ for (j = 0; j < num_params; j++) {
+ slang_assembly_typeinfo ti;
+
+ if (!slang_assembly_typeinfo_construct(&ti))
+ return NULL;
+ if (!_slang_typeof_operation_(&params[j], space, &ti, atoms)) {
+ slang_assembly_typeinfo_destruct(&ti);
+ return NULL;
+ }
+ if (!slang_type_specifier_equal
+ (&ti.spec, &f->parameters->variables[j].type.specifier)) {
+ slang_assembly_typeinfo_destruct(&ti);
+ break;
+ }
+ slang_assembly_typeinfo_destruct(&ti);
+
+ /* "out" and "inout" formal parameter requires the actual parameter to be l-value */
+ if (!ti.can_be_referenced &&
+ (f->parameters->variables[j].type.qualifier == slang_qual_out ||
+ f->parameters->variables[j].type.qualifier == slang_qual_inout))
+ break;
+ }
+ if (j == num_params)
+ return f;
+ }
+ if (funcs->outer_scope != NULL)
+ return _slang_locate_function(funcs->outer_scope, a_name, params,
+ num_params, space, atoms);
+ return NULL;
}
/* _slang_assemble_function() */
-GLboolean _slang_assemble_function (slang_assemble_ctx *A, slang_function *fun)
+GLboolean
+_slang_assemble_function(slang_assemble_ctx * A, slang_function * fun)
{
- GLuint param_size, local_size;
- GLuint skip, cleanup;
-
- fun->address = A->file->count;
-
- if (fun->body == NULL)
- {
- /* jump to the actual function body - we do not know it, so add the instruction
- * to fixup table */
- fun->fixups.table = (GLuint *) slang_alloc_realloc (fun->fixups.table,
- fun->fixups.count * sizeof (GLuint), (fun->fixups.count + 1) * sizeof (GLuint));
- if (fun->fixups.table == NULL)
- return GL_FALSE;
- fun->fixups.table[fun->fixups.count] = fun->address;
- fun->fixups.count++;
- if (!PUSH (A->file, slang_asm_jump))
- return GL_FALSE;
- return GL_TRUE;
- }
- else
- {
- GLuint i;
-
- /* resolve all fixup table entries and delete it */
- for (i = 0; i < fun->fixups.count; i++)
- A->file->code[fun->fixups.table[i]].param[0] = fun->address;
- slang_fixup_table_free (&fun->fixups);
- }
-
- /* At this point traverse function formal parameters and code to calculate
- * total memory size to be allocated on the stack.
- * During this process the variables will be assigned local addresses to
- * reference them in the code.
- * No storage optimizations are performed so exclusive scopes are not detected and shared. */
-
- /* calculate return value size */
- param_size = 0;
- if (fun->header.type.specifier.type != slang_spec_void)
- if (!sizeof_variable (A, &fun->header.type.specifier, slang_qual_none, 0, &param_size))
- return GL_FALSE;
- A->local.ret_size = param_size;
-
- /* calculate formal parameter list size */
- if (!sizeof_variables (A, fun->parameters, 0, fun->param_count, &param_size))
- return GL_FALSE;
-
- /* calculate local variables size - take into account the four-byte return address and
- * temporaries for various tasks (4 for addr and 16 for swizzle temporaries).
- * these include variables from the formal parameter scope and from the code */
- A->local.addr_tmp = param_size + 4;
- A->local.swizzle_tmp = param_size + 4 + 4;
- local_size = param_size + 4 + 4 + 16;
- if (!sizeof_variables (A, fun->parameters, fun->param_count, fun->parameters->num_variables,
- &local_size))
- return GL_FALSE;
- if (!collect_locals (A, fun->body, &local_size))
- return GL_FALSE;
-
- /* allocate local variable storage */
- if (!PLAB (A->file, slang_asm_local_alloc, local_size - param_size - 4))
- return GL_FALSE;
-
- /* mark a new frame for function variable storage */
- if (!PLAB (A->file, slang_asm_enter, local_size))
- return GL_FALSE;
-
- /* jump directly to the actual code */
- skip = A->file->count;
- if (!push_new (A->file))
- return GL_FALSE;
- A->file->code[skip].type = slang_asm_jump;
-
- /* all "return" statements will be directed here */
- A->flow.function_end = A->file->count;
- cleanup = A->file->count;
- if (!push_new (A->file))
- return GL_FALSE;
- A->file->code[cleanup].type = slang_asm_jump;
-
- /* execute the function body */
- A->file->code[skip].param[0] = A->file->count;
- if (!_slang_assemble_operation (A, fun->body, /*slang_ref_freelance*/slang_ref_forbid))
- return GL_FALSE;
-
- /* this is the end of the function - restore the old function frame */
- A->file->code[cleanup].param[0] = A->file->count;
- if (!PUSH (A->file, slang_asm_leave))
- return GL_FALSE;
-
- /* free local variable storage */
- if (!PLAB (A->file, slang_asm_local_free, local_size - param_size - 4))
- return GL_FALSE;
-
- /* return from the function */
- if (!PUSH (A->file, slang_asm_return))
- return GL_FALSE;
-
- return GL_TRUE;
+ GLuint param_size, local_size;
+ GLuint skip, cleanup;
+
+ fun->address = A->file->count;
+
+ if (fun->body == NULL) {
+ /* jump to the actual function body - we do not know it, so add
+ * the instruction to fixup table
+ */
+ if (!slang_fixup_save(&fun->fixups, fun->address))
+ return GL_FALSE;
+ if (!PUSH(A->file, slang_asm_jump))
+ return GL_FALSE;
+ return GL_TRUE;
+ }
+ else {
+ /* resolve all fixup table entries and delete it */
+ GLuint i;
+ for (i = 0; i < fun->fixups.count; i++)
+ A->file->code[fun->fixups.table[i]].param[0] = fun->address;
+ slang_fixup_table_free(&fun->fixups);
+ }
+
+ /* At this point traverse function formal parameters and code to calculate
+ * total memory size to be allocated on the stack.
+ * During this process the variables will be assigned local addresses to
+ * reference them in the code.
+ * No storage optimizations are performed so exclusive scopes are not
+ * detected and shared.
+ */
+
+ /* calculate return value size */
+ param_size = 0;
+ if (fun->header.type.specifier.type != slang_spec_void)
+ if (!sizeof_variable
+ (A, &fun->header.type.specifier, slang_qual_none, 0, &param_size))
+ return GL_FALSE;
+ A->local.ret_size = param_size;
+
+ /* calculate formal parameter list size */
+ if (!sizeof_variables
+ (A, fun->parameters, 0, fun->param_count, &param_size))
+ return GL_FALSE;
+
+ /* calculate local variables size - take into account the four-byte
+ * return address and temporaries for various tasks (4 for addr and
+ * 16 for swizzle temporaries). these include variables from the
+ * formal parameter scope and from the code
+ */
+ A->local.addr_tmp = param_size + 4;
+ A->local.swizzle_tmp = param_size + 4 + 4;
+ local_size = param_size + 4 + 4 + 16;
+ if (!sizeof_variables
+ (A, fun->parameters, fun->param_count, fun->parameters->num_variables,
+ &local_size))
+ return GL_FALSE;
+ if (!collect_locals(A, fun->body, &local_size))
+ return GL_FALSE;
+
+ /* allocate local variable storage */
+ if (!PLAB(A->file, slang_asm_local_alloc, local_size - param_size - 4))
+ return GL_FALSE;
+
+ /* mark a new frame for function variable storage */
+ if (!PLAB(A->file, slang_asm_enter, local_size))
+ return GL_FALSE;
+
+ /* jump directly to the actual code */
+ skip = A->file->count;
+ if (!push_new(A->file))
+ return GL_FALSE;
+ A->file->code[skip].type = slang_asm_jump;
+
+ /* all "return" statements will be directed here */
+ A->flow.function_end = A->file->count;
+ cleanup = A->file->count;
+ if (!push_new(A->file))
+ return GL_FALSE;
+ A->file->code[cleanup].type = slang_asm_jump;
+
+ /* execute the function body */
+ A->file->code[skip].param[0] = A->file->count;
+ if (!_slang_assemble_operation
+ (A, fun->body, /*slang_ref_freelance */ slang_ref_forbid))
+ return GL_FALSE;
+
+ /* this is the end of the function - restore the old function frame */
+ A->file->code[cleanup].param[0] = A->file->count;
+ if (!PUSH(A->file, slang_asm_leave))
+ return GL_FALSE;
+
+ /* free local variable storage */
+ if (!PLAB(A->file, slang_asm_local_free, local_size - param_size - 4))
+ return GL_FALSE;
+
+ /* return from the function */
+ if (!PUSH(A->file, slang_asm_return))
+ return GL_FALSE;
+
+ return GL_TRUE;
}
-GLboolean _slang_cleanup_stack (slang_assemble_ctx *A, slang_operation *op)
+GLboolean
+_slang_cleanup_stack(slang_assemble_ctx * A, slang_operation * op)
{
- slang_assembly_typeinfo ti;
- GLuint size = 0;
-
- /* get type info of the operation and calculate its size */
- if (!slang_assembly_typeinfo_construct (&ti))
- return GL_FALSE;
- if (!_slang_typeof_operation (A, op, &ti))
- {
- slang_assembly_typeinfo_destruct (&ti);
- return GL_FALSE;
- }
- if (ti.spec.type != slang_spec_void) {
- if (A->ref == slang_ref_force) {
- size = 4;
- }
- else if (!sizeof_variable (A, &ti.spec, slang_qual_none, 0, &size))
- {
- slang_assembly_typeinfo_destruct (&ti);
- return GL_FALSE;
- }
- }
- slang_assembly_typeinfo_destruct (&ti);
-
- /* if nonzero, free it from the stack */
- if (size != 0)
- {
- if (!PLAB (A->file, slang_asm_local_free, size))
- return GL_FALSE;
- }
-
- return GL_TRUE;
+ slang_assembly_typeinfo ti;
+ GLuint size = 0;
+
+ /* get type info of the operation and calculate its size */
+ if (!slang_assembly_typeinfo_construct(&ti))
+ return GL_FALSE;
+ if (!_slang_typeof_operation(A, op, &ti)) {
+ slang_assembly_typeinfo_destruct(&ti);
+ return GL_FALSE;
+ }
+ if (ti.spec.type != slang_spec_void) {
+ if (A->ref == slang_ref_force) {
+ size = 4;
+ }
+ else if (!sizeof_variable(A, &ti.spec, slang_qual_none, 0, &size)) {
+ slang_assembly_typeinfo_destruct(&ti);
+ return GL_FALSE;
+ }
+ }
+ slang_assembly_typeinfo_destruct(&ti);
+
+ /* if nonzero, free it from the stack */
+ if (size != 0) {
+ if (!PLAB(A->file, slang_asm_local_free, size))
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
}
/* _slang_assemble_operation() */
static GLboolean
-dereference_basic (slang_assemble_ctx *A, slang_storage_type type, GLuint *size, slang_swizzle *swz,
- GLboolean is_swizzled)
+dereference_basic(slang_assemble_ctx * A, slang_storage_type type,
+ GLuint * size, slang_swizzle * swz, GLboolean is_swizzled)
{
GLuint src_offset;
slang_assembly_type ty;
- *size -= _slang_sizeof_type (type);
+ *size -= _slang_sizeof_type(type);
- /* If swizzling is taking place, we are forced to use scalar operations, even if we have
- * vec4 instructions enabled (this should be actually done with special vec4 shuffle
- * instructions).
- * Adjust the size and calculate the offset within source variable to read.
+ /* If swizzling is taking place, we are forced to use scalar
+ * operations, even if we have vec4 instructions enabled (this
+ * should be actually done with special vec4 shuffle instructions).
+ * Adjust the size and calculate the offset within source variable
+ * to read.
*/
if (is_swizzled)
src_offset = swz->swizzle[*size / 4] * 4;
@@ -418,14 +441,14 @@ dereference_basic (slang_assemble_ctx *A, slang_storage_type type, GLuint *size,
src_offset = *size;
/* dereference data slot of a basic type */
- if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
+ if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
return GL_FALSE;
- if (!PUSH (A->file, slang_asm_addr_deref))
+ if (!PUSH(A->file, slang_asm_addr_deref))
return GL_FALSE;
if (src_offset != 0) {
- if (!PLAB (A->file, slang_asm_addr_push, src_offset))
+ if (!PLAB(A->file, slang_asm_addr_push, src_offset))
return GL_FALSE;
- if (!PUSH (A->file, slang_asm_addr_add))
+ if (!PUSH(A->file, slang_asm_addr_add))
return GL_FALSE;
}
@@ -449,12 +472,13 @@ dereference_basic (slang_assemble_ctx *A, slang_storage_type type, GLuint *size,
ty = slang_asm_none;
}
- return PUSH (A->file, ty);
+ return PUSH(A->file, ty);
}
static GLboolean
-dereference_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLuint *size,
- slang_swizzle *swz, GLboolean is_swizzled)
+dereference_aggregate(slang_assemble_ctx * A,
+ const slang_storage_aggregate * agg, GLuint * size,
+ slang_swizzle * swz, GLboolean is_swizzled)
{
GLuint i;
@@ -464,22 +488,27 @@ dereference_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg
for (j = arr->length; j > 0; j--) {
if (arr->type == slang_stor_aggregate) {
- if (!dereference_aggregate (A, arr->aggregate, size, swz, is_swizzled))
+ if (!dereference_aggregate
+ (A, arr->aggregate, size, swz, is_swizzled))
return GL_FALSE;
}
else {
if (is_swizzled && arr->type == slang_stor_vec4) {
- if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled))
+ if (!dereference_basic
+ (A, slang_stor_float, size, swz, is_swizzled))
return GL_FALSE;
- if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled))
+ if (!dereference_basic
+ (A, slang_stor_float, size, swz, is_swizzled))
return GL_FALSE;
- if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled))
+ if (!dereference_basic
+ (A, slang_stor_float, size, swz, is_swizzled))
return GL_FALSE;
- if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled))
+ if (!dereference_basic
+ (A, slang_stor_float, size, swz, is_swizzled))
return GL_FALSE;
}
else {
- if (!dereference_basic (A, arr->type, size, swz, is_swizzled))
+ if (!dereference_basic(A, arr->type, size, swz, is_swizzled))
return GL_FALSE;
}
}
@@ -489,235 +518,240 @@ dereference_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg
return GL_TRUE;
}
-GLboolean _slang_dereference (slang_assemble_ctx *A, slang_operation *op)
+GLboolean
+_slang_dereference(slang_assemble_ctx * A, slang_operation * op)
{
- slang_assembly_typeinfo ti;
- GLboolean result = GL_FALSE;
- slang_storage_aggregate agg;
- GLuint size;
-
- /* get type information of the given operation */
- if (!slang_assembly_typeinfo_construct (&ti))
- return GL_FALSE;
- if (!_slang_typeof_operation (A, op, &ti))
- goto end1;
-
- /* construct aggregate from the type info */
- if (!slang_storage_aggregate_construct (&agg))
- goto end1;
- if (!_slang_aggregate_variable (&agg, &ti.spec, ti.array_len, A->space.funcs, A->space.structs,
- A->space.vars, A->mach, A->file, A->atoms))
- goto end;
-
- /* dereference the resulting aggregate */
- size = _slang_sizeof_aggregate (&agg);
- result = dereference_aggregate (A, &agg, &size, &ti.swz, ti.is_swizzled);
-
-end:
- slang_storage_aggregate_destruct (&agg);
-end1:
- slang_assembly_typeinfo_destruct (&ti);
- return result;
+ slang_assembly_typeinfo ti;
+ GLboolean result = GL_FALSE;
+ slang_storage_aggregate agg;
+ GLuint size;
+
+ /* get type information of the given operation */
+ if (!slang_assembly_typeinfo_construct(&ti))
+ return GL_FALSE;
+ if (!_slang_typeof_operation(A, op, &ti))
+ goto end1;
+
+ /* construct aggregate from the type info */
+ if (!slang_storage_aggregate_construct(&agg))
+ goto end1;
+ if (!_slang_aggregate_variable
+ (&agg, &ti.spec, ti.array_len, A->space.funcs, A->space.structs,
+ A->space.vars, A->mach, A->file, A->atoms))
+ goto end;
+
+ /* dereference the resulting aggregate */
+ size = _slang_sizeof_aggregate(&agg);
+ result = dereference_aggregate(A, &agg, &size, &ti.swz, ti.is_swizzled);
+
+ end:
+ slang_storage_aggregate_destruct(&agg);
+ end1:
+ slang_assembly_typeinfo_destruct(&ti);
+ return result;
}
-GLboolean _slang_assemble_function_call (slang_assemble_ctx *A, slang_function *fun,
- slang_operation *params, GLuint param_count, GLboolean assignment)
+GLboolean
+_slang_assemble_function_call(slang_assemble_ctx * A, slang_function * fun,
+ slang_operation * params, GLuint param_count,
+ GLboolean assignment)
{
- GLuint i;
- slang_swizzle p_swz[64];
- slang_ref_type p_ref[64];
-
- /* TODO: fix this, allocate dynamically */
- if (param_count > 64)
- return GL_FALSE;
-
- /* make room for the return value, if any */
- if (fun->header.type.specifier.type != slang_spec_void)
- {
- GLuint ret_size = 0;
-
- if (!sizeof_variable (A, &fun->header.type.specifier, slang_qual_none, 0, &ret_size))
- return GL_FALSE;
- if (!PLAB (A->file, slang_asm_local_alloc, ret_size))
- return GL_FALSE;
- }
-
- /* push the actual parameters on the stack */
- for (i = 0; i < param_count; i++)
- {
- if (fun->parameters->variables[i].type.qualifier == slang_qual_inout ||
- fun->parameters->variables[i].type.qualifier == slang_qual_out)
- {
- if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
- return GL_FALSE;
- /* TODO: optimize the "out" parameter case */
- if (!_slang_assemble_operation (A, &params[i], slang_ref_force))
- return GL_FALSE;
- p_swz[i] = A->swz;
- p_ref[i] = A->ref;
- if (!PUSH (A->file, slang_asm_addr_copy))
- return GL_FALSE;
- if (!PUSH (A->file, slang_asm_addr_deref))
- return GL_FALSE;
- if (i == 0 && assignment)
- {
- /* duplicate the resulting address */
- if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
- return GL_FALSE;
- if (!PUSH (A->file, slang_asm_addr_deref))
- return GL_FALSE;
- }
- if (!_slang_dereference (A, &params[i]))
- return GL_FALSE;
- }
- else
- {
- if (!_slang_assemble_operation (A, &params[i], slang_ref_forbid))
- return GL_FALSE;
- p_swz[i] = A->swz;
- p_ref[i] = A->ref;
- }
- }
-
- /* call the function */
- if (!PLAB (A->file, slang_asm_call, fun->address))
- return GL_FALSE;
-
- /* pop the parameters from the stack */
- for (i = param_count; i > 0; i--)
- {
- GLuint j = i - 1;
-
- A->swz = p_swz[j];
- A->ref = p_ref[j];
- if (fun->parameters->variables[j].type.qualifier == slang_qual_inout ||
- fun->parameters->variables[j].type.qualifier == slang_qual_out)
- {
- /* for output parameter copy the contents of the formal parameter
- * back to the original actual parameter */
- if (!_slang_assemble_assignment (A, &params[j]))
- return GL_FALSE;
- /* pop the actual parameter's address */
- if (!PLAB (A->file, slang_asm_local_free, 4))
- return GL_FALSE;
- }
- else
- {
- /* pop the value of the parameter */
- if (!_slang_cleanup_stack (A, &params[j]))
- return GL_FALSE;
- }
- }
-
- return GL_TRUE;
+ GLuint i;
+ slang_swizzle p_swz[64];
+ slang_ref_type p_ref[64];
+
+ /* TODO: fix this, allocate dynamically */
+ if (param_count > 64)
+ return GL_FALSE;
+
+ /* make room for the return value, if any */
+ if (fun->header.type.specifier.type != slang_spec_void) {
+ GLuint ret_size = 0;
+
+ if (!sizeof_variable
+ (A, &fun->header.type.specifier, slang_qual_none, 0, &ret_size))
+ return GL_FALSE;
+ if (!PLAB(A->file, slang_asm_local_alloc, ret_size))
+ return GL_FALSE;
+ }
+
+ /* push the actual parameters on the stack */
+ for (i = 0; i < param_count; i++) {
+ if (fun->parameters->variables[i].type.qualifier == slang_qual_inout ||
+ fun->parameters->variables[i].type.qualifier == slang_qual_out) {
+ if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
+ return GL_FALSE;
+ /* TODO: optimize the "out" parameter case */
+ if (!_slang_assemble_operation(A, &params[i], slang_ref_force))
+ return GL_FALSE;
+ p_swz[i] = A->swz;
+ p_ref[i] = A->ref;
+ if (!PUSH(A->file, slang_asm_addr_copy))
+ return GL_FALSE;
+ if (!PUSH(A->file, slang_asm_addr_deref))
+ return GL_FALSE;
+ if (i == 0 && assignment) {
+ /* duplicate the resulting address */
+ if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
+ return GL_FALSE;
+ if (!PUSH(A->file, slang_asm_addr_deref))
+ return GL_FALSE;
+ }
+ if (!_slang_dereference(A, &params[i]))
+ return GL_FALSE;
+ }
+ else {
+ if (!_slang_assemble_operation(A, &params[i], slang_ref_forbid))
+ return GL_FALSE;
+ p_swz[i] = A->swz;
+ p_ref[i] = A->ref;
+ }
+ }
+
+ /* call the function */
+ if (!PLAB(A->file, slang_asm_call, fun->address))
+ return GL_FALSE;
+
+ /* pop the parameters from the stack */
+ for (i = param_count; i > 0; i--) {
+ GLuint j = i - 1;
+
+ A->swz = p_swz[j];
+ A->ref = p_ref[j];
+ if (fun->parameters->variables[j].type.qualifier == slang_qual_inout ||
+ fun->parameters->variables[j].type.qualifier == slang_qual_out) {
+ /* for output parameter copy the contents of the formal parameter
+ * back to the original actual parameter
+ */
+ if (!_slang_assemble_assignment(A, &params[j]))
+ return GL_FALSE;
+ /* pop the actual parameter's address */
+ if (!PLAB(A->file, slang_asm_local_free, 4))
+ return GL_FALSE;
+ }
+ else {
+ /* pop the value of the parameter */
+ if (!_slang_cleanup_stack(A, &params[j]))
+ return GL_FALSE;
+ }
+ }
+
+ return GL_TRUE;
}
-GLboolean _slang_assemble_function_call_name (slang_assemble_ctx *A, const char *name,
- slang_operation *params, GLuint param_count, GLboolean assignment)
+GLboolean
+_slang_assemble_function_call_name(slang_assemble_ctx * A, const char *name,
+ slang_operation * params,
+ GLuint param_count, GLboolean assignment)
{
- slang_atom atom;
- slang_function *fun;
-
- atom = slang_atom_pool_atom (A->atoms, name);
- if (atom == SLANG_ATOM_NULL)
- return GL_FALSE;
- fun = _slang_locate_function (A->space.funcs, atom, params, param_count, &A->space, A->atoms);
- if (fun == NULL)
- return GL_FALSE;
- return _slang_assemble_function_call (A, fun, params, param_count, assignment);
+ slang_atom atom;
+ slang_function *fun;
+
+ atom = slang_atom_pool_atom(A->atoms, name);
+ if (atom == SLANG_ATOM_NULL)
+ return GL_FALSE;
+ fun =
+ _slang_locate_function(A->space.funcs, atom, params, param_count,
+ &A->space, A->atoms);
+ if (fun == NULL)
+ return GL_FALSE;
+ return _slang_assemble_function_call(A, fun, params, param_count,
+ assignment);
}
-static GLboolean assemble_function_call_name_dummyint (slang_assemble_ctx *A, const char *name,
- slang_operation *params)
+static GLboolean
+assemble_function_call_name_dummyint(slang_assemble_ctx * A, const char *name,
+ slang_operation * params)
{
- slang_operation p[2];
- GLboolean result;
-
- p[0] = params[0];
- if (!slang_operation_construct (&p[1]))
- return GL_FALSE;
- p[1].type = slang_oper_literal_int;
- result = _slang_assemble_function_call_name (A, name, p, 2, GL_FALSE);
- slang_operation_destruct (&p[1]);
- return result;
+ slang_operation p[2];
+ GLboolean result;
+
+ p[0] = params[0];
+ if (!slang_operation_construct(&p[1]))
+ return GL_FALSE;
+ p[1].type = slang_oper_literal_int;
+ result = _slang_assemble_function_call_name(A, name, p, 2, GL_FALSE);
+ slang_operation_destruct(&p[1]);
+ return result;
}
static const struct
{
- const char *name;
- slang_assembly_type code1, code2;
+ const char *name;
+ slang_assembly_type code1, code2;
} inst[] = {
- /* core */
- { "float_add", slang_asm_float_add, slang_asm_float_copy },
- { "float_multiply", slang_asm_float_multiply, slang_asm_float_copy },
- { "float_divide", slang_asm_float_divide, slang_asm_float_copy },
- { "float_negate", slang_asm_float_negate, slang_asm_float_copy },
- { "float_less", slang_asm_float_less, slang_asm_bool_copy },
- { "float_equal", slang_asm_float_equal_exp,slang_asm_bool_copy },
- { "float_to_int", slang_asm_float_to_int, slang_asm_int_copy },
- { "float_sine", slang_asm_float_sine, slang_asm_float_copy },
- { "float_arcsine", slang_asm_float_arcsine, slang_asm_float_copy },
- { "float_arctan", slang_asm_float_arctan, slang_asm_float_copy },
- { "float_power", slang_asm_float_power, slang_asm_float_copy },
- { "float_log2", slang_asm_float_log2, slang_asm_float_copy },
- { "float_floor", slang_asm_float_floor, slang_asm_float_copy },
- { "float_ceil", slang_asm_float_ceil, slang_asm_float_copy },
- { "float_noise1", slang_asm_float_noise1, slang_asm_float_copy },
- { "float_noise2", slang_asm_float_noise2, slang_asm_float_copy },
- { "float_noise3", slang_asm_float_noise3, slang_asm_float_copy },
- { "float_noise4", slang_asm_float_noise4, slang_asm_float_copy },
- { "int_to_float", slang_asm_int_to_float, slang_asm_float_copy },
- { "vec4_tex1d", slang_asm_vec4_tex1d, slang_asm_none },
- { "vec4_tex2d", slang_asm_vec4_tex2d, slang_asm_none },
- { "vec4_tex3d", slang_asm_vec4_tex3d, slang_asm_none },
- { "vec4_texcube", slang_asm_vec4_texcube, slang_asm_none },
- { "vec4_shad1d", slang_asm_vec4_shad1d, slang_asm_none },
- { "vec4_shad2d", slang_asm_vec4_shad2d, slang_asm_none },
- /* GL_MESA_shader_debug */
- { "float_print", slang_asm_float_deref, slang_asm_float_print },
- { "int_print", slang_asm_int_deref, slang_asm_int_print },
- { "bool_print", slang_asm_bool_deref, slang_asm_bool_print },
+ /* core */
+ {"float_add", slang_asm_float_add, slang_asm_float_copy},
+ {"float_multiply", slang_asm_float_multiply, slang_asm_float_copy},
+ {"float_divide", slang_asm_float_divide, slang_asm_float_copy},
+ {"float_negate", slang_asm_float_negate, slang_asm_float_copy},
+ {"float_less", slang_asm_float_less, slang_asm_bool_copy},
+ {"float_equal", slang_asm_float_equal_exp, slang_asm_bool_copy},
+ {"float_to_int", slang_asm_float_to_int, slang_asm_int_copy},
+ {"float_sine", slang_asm_float_sine, slang_asm_float_copy},
+ {"float_arcsine", slang_asm_float_arcsine, slang_asm_float_copy},
+ {"float_arctan", slang_asm_float_arctan, slang_asm_float_copy},
+ {"float_power", slang_asm_float_power, slang_asm_float_copy},
+ {"float_log2", slang_asm_float_log2, slang_asm_float_copy},
+ {"float_floor", slang_asm_float_floor, slang_asm_float_copy},
+ {"float_ceil", slang_asm_float_ceil, slang_asm_float_copy},
+ {"float_noise1", slang_asm_float_noise1, slang_asm_float_copy},
+ {"float_noise2", slang_asm_float_noise2, slang_asm_float_copy},
+ {"float_noise3", slang_asm_float_noise3, slang_asm_float_copy},
+ {"float_noise4", slang_asm_float_noise4, slang_asm_float_copy},
+ {"int_to_float", slang_asm_int_to_float, slang_asm_float_copy},
+ {"vec4_tex1d", slang_asm_vec4_tex1d, slang_asm_none},
+ {"vec4_tex2d", slang_asm_vec4_tex2d, slang_asm_none},
+ {"vec4_tex3d", slang_asm_vec4_tex3d, slang_asm_none},
+ {"vec4_texcube", slang_asm_vec4_texcube, slang_asm_none},
+ {"vec4_shad1d", slang_asm_vec4_shad1d, slang_asm_none},
+ {"vec4_shad2d", slang_asm_vec4_shad2d, slang_asm_none},
+ /* GL_MESA_shader_debug */
+ {"float_print", slang_asm_float_deref, slang_asm_float_print},
+ {"int_print", slang_asm_int_deref, slang_asm_int_print},
+ {"bool_print", slang_asm_bool_deref, slang_asm_bool_print},
/* vec4 */
- { "float_to_vec4", slang_asm_float_to_vec4, slang_asm_none },
- { "vec4_add", slang_asm_vec4_add, slang_asm_none },
- { "vec4_subtract", slang_asm_vec4_subtract, slang_asm_none },
- { "vec4_multiply", slang_asm_vec4_multiply, slang_asm_none },
- { "vec4_divide", slang_asm_vec4_divide, slang_asm_none },
- { "vec4_negate", slang_asm_vec4_negate, slang_asm_none },
- { "vec4_dot", slang_asm_vec4_dot, slang_asm_none },
-
- { NULL, slang_asm_none, slang_asm_none }
+ {"float_to_vec4", slang_asm_float_to_vec4, slang_asm_none},
+ {"vec4_add", slang_asm_vec4_add, slang_asm_none},
+ {"vec4_subtract", slang_asm_vec4_subtract, slang_asm_none},
+ {"vec4_multiply", slang_asm_vec4_multiply, slang_asm_none},
+ {"vec4_divide", slang_asm_vec4_divide, slang_asm_none},
+ {"vec4_negate", slang_asm_vec4_negate, slang_asm_none},
+ {"vec4_dot", slang_asm_vec4_dot, slang_asm_none},
+ {NULL, slang_asm_none, slang_asm_none}
};
-static GLboolean call_asm_instruction (slang_assemble_ctx *A, slang_atom a_name)
+static GLboolean
+call_asm_instruction(slang_assemble_ctx * A, slang_atom a_name)
{
- const char *id;
- GLuint i;
+ const char *id;
+ GLuint i;
- id = slang_atom_pool_id (A->atoms, a_name);
+ id = slang_atom_pool_id(A->atoms, a_name);
- for (i = 0; inst[i].name != NULL; i++)
- if (slang_string_compare (id, inst[i].name) == 0)
- break;
- if (inst[i].name == NULL)
- return GL_FALSE;
+ for (i = 0; inst[i].name != NULL; i++)
+ if (slang_string_compare(id, inst[i].name) == 0)
+ break;
+ if (inst[i].name == NULL)
+ return GL_FALSE;
- if (!PLAB2 (A->file, inst[i].code1, 4, 0))
- return GL_FALSE;
- if (inst[i].code2 != slang_asm_none)
- if (!PLAB2 (A->file, inst[i].code2, 4, 0))
- return GL_FALSE;
+ if (!PLAB2(A->file, inst[i].code1, 4, 0))
+ return GL_FALSE;
+ if (inst[i].code2 != slang_asm_none)
+ if (!PLAB2(A->file, inst[i].code2, 4, 0))
+ return GL_FALSE;
- /* clean-up the stack from the remaining dst address */
- if (!PLAB (A->file, slang_asm_local_free, 4))
- return GL_FALSE;
+ /* clean-up the stack from the remaining dst address */
+ if (!PLAB(A->file, slang_asm_local_free, 4))
+ return GL_FALSE;
- return GL_TRUE;
+ return GL_TRUE;
}
static GLboolean
-equality_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLuint *index,
- GLuint size, GLuint z_label)
+equality_aggregate(slang_assemble_ctx * A,
+ const slang_storage_aggregate * agg, GLuint * index,
+ GLuint size, GLuint z_label)
{
GLuint i;
@@ -727,22 +761,25 @@ equality_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, G
for (j = 0; j < arr->length; j++) {
if (arr->type == slang_stor_aggregate) {
- if (!equality_aggregate (A, arr->aggregate, index, size, z_label))
+ if (!equality_aggregate(A, arr->aggregate, index, size, z_label))
return GL_FALSE;
}
else {
#if defined(USE_X86_ASM) || defined(SLANG_X86)
if (arr->type == slang_stor_vec4) {
- if (!PLAB2 (A->file, slang_asm_vec4_equal_int, size + *index, *index))
+ if (!PLAB2
+ (A->file, slang_asm_vec4_equal_int, size + *index, *index))
return GL_FALSE;
}
else
#endif
- if (!PLAB2 (A->file, slang_asm_float_equal_int, size + *index, *index))
- return GL_FALSE;
+ if (!PLAB2
+ (A->file, slang_asm_float_equal_int, size + *index,
+ *index))
+ return GL_FALSE;
- *index += _slang_sizeof_type (arr->type);
- if (!PLAB (A->file, slang_asm_jump_if_zero, z_label))
+ *index += _slang_sizeof_type(arr->type);
+ if (!PLAB(A->file, slang_asm_jump_if_zero, z_label))
return GL_FALSE;
}
}
@@ -751,753 +788,755 @@ equality_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, G
return GL_TRUE;
}
-static GLboolean equality (slang_assemble_ctx *A, slang_operation *op, GLboolean equal)
+static GLboolean
+equality(slang_assemble_ctx * A, slang_operation * op, GLboolean equal)
{
- slang_assembly_typeinfo ti;
- GLboolean result = GL_FALSE;
- slang_storage_aggregate agg;
- GLuint index, size;
- GLuint skip_jump, true_label, true_jump, false_label, false_jump;
-
- /* get type of operation */
- if (!slang_assembly_typeinfo_construct (&ti))
- return GL_FALSE;
- if (!_slang_typeof_operation (A, op, &ti))
- goto end1;
-
- /* convert it to an aggregate */
- if (!slang_storage_aggregate_construct (&agg))
- goto end1;
- if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs,
- A->space.vars, A->mach, A->file, A->atoms))
- goto end;
-
- /* compute the size of the agregate - there are two such aggregates on the stack */
- size = _slang_sizeof_aggregate (&agg);
-
- /* jump to the actual data-comparison code */
- skip_jump = A->file->count;
- if (!PUSH (A->file, slang_asm_jump))
- goto end;
-
- /* pop off the stack the compared data and push 1 */
- true_label = A->file->count;
- if (!PLAB (A->file, slang_asm_local_free, size * 2))
- goto end;
- if (!PLIT (A->file, slang_asm_bool_push, (GLfloat) 1))
- goto end;
- true_jump = A->file->count;
- if (!PUSH (A->file, slang_asm_jump))
- goto end;
-
- false_label = A->file->count;
- if (!PLAB (A->file, slang_asm_local_free, size * 2))
- goto end;
- if (!PLIT (A->file, slang_asm_bool_push, (GLfloat) 0))
- goto end;
- false_jump = A->file->count;
- if (!PUSH (A->file, slang_asm_jump))
- goto end;
-
- A->file->code[skip_jump].param[0] = A->file->count;
-
- /* compare the data on stack, it will eventually jump either to true or false label */
- index = 0;
- if (!equality_aggregate (A, &agg, &index, size, equal ? false_label : true_label))
- goto end;
- if (!PLAB (A->file, slang_asm_jump, equal ? true_label : false_label))
- goto end;
-
- A->file->code[true_jump].param[0] = A->file->count;
- A->file->code[false_jump].param[0] = A->file->count;
-
- result = GL_TRUE;
-end:
- slang_storage_aggregate_destruct (&agg);
-end1:
- slang_assembly_typeinfo_destruct (&ti);
- return result;
+ slang_assembly_typeinfo ti;
+ GLboolean result = GL_FALSE;
+ slang_storage_aggregate agg;
+ GLuint index, size;
+ GLuint skip_jump, true_label, true_jump, false_label, false_jump;
+
+ /* get type of operation */
+ if (!slang_assembly_typeinfo_construct(&ti))
+ return GL_FALSE;
+ if (!_slang_typeof_operation(A, op, &ti))
+ goto end1;
+
+ /* convert it to an aggregate */
+ if (!slang_storage_aggregate_construct(&agg))
+ goto end1;
+ if (!_slang_aggregate_variable
+ (&agg, &ti.spec, 0, A->space.funcs, A->space.structs, A->space.vars,
+ A->mach, A->file, A->atoms))
+ goto end;
+
+ /* compute the size of the agregate - there are two such aggregates on the stack */
+ size = _slang_sizeof_aggregate(&agg);
+
+ /* jump to the actual data-comparison code */
+ skip_jump = A->file->count;
+ if (!PUSH(A->file, slang_asm_jump))
+ goto end;
+
+ /* pop off the stack the compared data and push 1 */
+ true_label = A->file->count;
+ if (!PLAB(A->file, slang_asm_local_free, size * 2))
+ goto end;
+ if (!PLIT(A->file, slang_asm_bool_push, (GLfloat) 1))
+ goto end;
+ true_jump = A->file->count;
+ if (!PUSH(A->file, slang_asm_jump))
+ goto end;
+
+ false_label = A->file->count;
+ if (!PLAB(A->file, slang_asm_local_free, size * 2))
+ goto end;
+ if (!PLIT(A->file, slang_asm_bool_push, (GLfloat) 0))
+ goto end;
+ false_jump = A->file->count;
+ if (!PUSH(A->file, slang_asm_jump))
+ goto end;
+
+ A->file->code[skip_jump].param[0] = A->file->count;
+
+ /* compare the data on stack, it will eventually jump either to true or false label */
+ index = 0;
+ if (!equality_aggregate
+ (A, &agg, &index, size, equal ? false_label : true_label))
+ goto end;
+ if (!PLAB(A->file, slang_asm_jump, equal ? true_label : false_label))
+ goto end;
+
+ A->file->code[true_jump].param[0] = A->file->count;
+ A->file->code[false_jump].param[0] = A->file->count;
+
+ result = GL_TRUE;
+ end:
+ slang_storage_aggregate_destruct(&agg);
+ end1:
+ slang_assembly_typeinfo_destruct(&ti);
+ return result;
}
-static GLboolean handle_subscript (slang_assemble_ctx *A, slang_assembly_typeinfo *tie,
- slang_assembly_typeinfo *tia, slang_operation *op, slang_ref_type ref)
+static GLboolean
+handle_subscript(slang_assemble_ctx * A, slang_assembly_typeinfo * tie,
+ slang_assembly_typeinfo * tia, slang_operation * op,
+ slang_ref_type ref)
{
- GLuint asize = 0, esize = 0;
-
- /* get type info of the master expression (matrix, vector or an array */
- if (!_slang_typeof_operation (A, &op->children[0], tia))
- return GL_FALSE;
- if (!sizeof_variable (A, &tia->spec, slang_qual_none, tia->array_len, &asize))
- return GL_FALSE;
-
- /* get type info of the result (matrix column, vector row or array element) */
- if (!_slang_typeof_operation (A, op, tie))
- return GL_FALSE;
- if (!sizeof_variable (A, &tie->spec, slang_qual_none, 0, &esize))
- return GL_FALSE;
-
- /* assemble the master expression */
- if (!_slang_assemble_operation (A, &op->children[0], ref))
- return GL_FALSE;
-
- /* when indexing an l-value swizzle, push the swizzle_tmp */
- if (ref == slang_ref_force && tia->is_swizzled)
- if (!PLAB2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
- return GL_FALSE;
-
- /* assemble the subscript expression */
- if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
- return GL_FALSE;
-
- if (ref == slang_ref_force && tia->is_swizzled)
- {
- GLuint i;
-
- /* copy the swizzle indexes to the swizzle_tmp */
- for (i = 0; i < tia->swz.num_components; i++)
- {
- if (!PLAB2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
- return GL_FALSE;
- if (!PLAB (A->file, slang_asm_addr_push, i * 4))
- return GL_FALSE;
- if (!PUSH (A->file, slang_asm_addr_add))
- return GL_FALSE;
- if (!PLAB (A->file, slang_asm_addr_push, tia->swz.swizzle[i]))
- return GL_FALSE;
- if (!PUSH (A->file, slang_asm_addr_copy))
- return GL_FALSE;
- if (!PLAB (A->file, slang_asm_local_free, 4))
- return GL_FALSE;
- }
-
- /* offset the pushed swizzle_tmp address and dereference it */
- if (!PUSH (A->file, slang_asm_int_to_addr))
- return GL_FALSE;
- if (!PLAB (A->file, slang_asm_addr_push, 4))
- return GL_FALSE;
- if (!PUSH (A->file, slang_asm_addr_multiply))
- return GL_FALSE;
- if (!PUSH (A->file, slang_asm_addr_add))
- return GL_FALSE;
- if (!PUSH (A->file, slang_asm_addr_deref))
- return GL_FALSE;
- }
- else
- {
- /* convert the integer subscript to a relative address */
- if (!PUSH (A->file, slang_asm_int_to_addr))
- return GL_FALSE;
- }
-
- if (!PLAB (A->file, slang_asm_addr_push, esize))
- return GL_FALSE;
- if (!PUSH (A->file, slang_asm_addr_multiply))
- return GL_FALSE;
-
- if (ref == slang_ref_force)
- {
- /* offset the base address with the relative address */
- if (!PUSH (A->file, slang_asm_addr_add))
- return GL_FALSE;
- }
- else
- {
- GLuint i;
-
- /* move the selected element to the beginning of the master expression */
- for (i = 0; i < esize; i += 4)
- if (!PLAB2 (A->file, slang_asm_float_move, asize - esize + i + 4, i + 4))
- return GL_FALSE;
- if (!PLAB (A->file, slang_asm_local_free, 4))
- return GL_FALSE;
-
- /* free the rest of the master expression */
- if (!PLAB (A->file, slang_asm_local_free, asize - esize))
- return GL_FALSE;
- }
-
- return GL_TRUE;
+ GLuint asize = 0, esize = 0;
+
+ /* get type info of the master expression (matrix, vector or an array */
+ if (!_slang_typeof_operation(A, &op->children[0], tia))
+ return GL_FALSE;
+ if (!sizeof_variable
+ (A, &tia->spec, slang_qual_none, tia->array_len, &asize))
+ return GL_FALSE;
+
+ /* get type info of the result (matrix column, vector row or array element) */
+ if (!_slang_typeof_operation(A, op, tie))
+ return GL_FALSE;
+ if (!sizeof_variable(A, &tie->spec, slang_qual_none, 0, &esize))
+ return GL_FALSE;
+
+ /* assemble the master expression */
+ if (!_slang_assemble_operation(A, &op->children[0], ref))
+ return GL_FALSE;
+
+ /* when indexing an l-value swizzle, push the swizzle_tmp */
+ if (ref == slang_ref_force && tia->is_swizzled)
+ if (!PLAB2(A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
+ return GL_FALSE;
+
+ /* assemble the subscript expression */
+ if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid))
+ return GL_FALSE;
+
+ if (ref == slang_ref_force && tia->is_swizzled) {
+ GLuint i;
+
+ /* copy the swizzle indexes to the swizzle_tmp */
+ for (i = 0; i < tia->swz.num_components; i++) {
+ if (!PLAB2(A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
+ return GL_FALSE;
+ if (!PLAB(A->file, slang_asm_addr_push, i * 4))
+ return GL_FALSE;
+ if (!PUSH(A->file, slang_asm_addr_add))
+ return GL_FALSE;
+ if (!PLAB(A->file, slang_asm_addr_push, tia->swz.swizzle[i]))
+ return GL_FALSE;
+ if (!PUSH(A->file, slang_asm_addr_copy))
+ return GL_FALSE;
+ if (!PLAB(A->file, slang_asm_local_free, 4))
+ return GL_FALSE;
+ }
+
+ /* offset the pushed swizzle_tmp address and dereference it */
+ if (!PUSH(A->file, slang_asm_int_to_addr))
+ return GL_FALSE;
+ if (!PLAB(A->file, slang_asm_addr_push, 4))
+ return GL_FALSE;
+ if (!PUSH(A->file, slang_asm_addr_multiply))
+ return GL_FALSE;
+ if (!PUSH(A->file, slang_asm_addr_add))
+ return GL_FALSE;
+ if (!PUSH(A->file, slang_asm_addr_deref))
+ return GL_FALSE;
+ }
+ else {
+ /* convert the integer subscript to a relative address */
+ if (!PUSH(A->file, slang_asm_int_to_addr))
+ return GL_FALSE;
+ }
+
+ if (!PLAB(A->file, slang_asm_addr_push, esize))
+ return GL_FALSE;
+ if (!PUSH(A->file, slang_asm_addr_multiply))
+ return GL_FALSE;
+
+ if (ref == slang_ref_force) {
+ /* offset the base address with the relative address */
+ if (!PUSH(A->file, slang_asm_addr_add))
+ return GL_FALSE;
+ }
+ else {
+ GLuint i;
+
+ /* move the selected element to the beginning of the master expression */
+ for (i = 0; i < esize; i += 4)
+ if (!PLAB2
+ (A->file, slang_asm_float_move, asize - esize + i + 4, i + 4))
+ return GL_FALSE;
+ if (!PLAB(A->file, slang_asm_local_free, 4))
+ return GL_FALSE;
+
+ /* free the rest of the master expression */
+ if (!PLAB(A->file, slang_asm_local_free, asize - esize))
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
}
-static GLboolean handle_field (slang_assemble_ctx *A, slang_assembly_typeinfo *tia,
- slang_assembly_typeinfo *tib, slang_operation *op, slang_ref_type ref)
+static GLboolean
+handle_field(slang_assemble_ctx * A, slang_assembly_typeinfo * tia,
+ slang_assembly_typeinfo * tib, slang_operation * op,
+ slang_ref_type ref)
{
- /* get type info of the result (field or swizzle) */
- if (!_slang_typeof_operation (A, op, tia))
- return GL_FALSE;
-
- /* get type info of the master expression being accessed (struct or vector) */
- if (!_slang_typeof_operation (A, &op->children[0], tib))
- return GL_FALSE;
-
- /* if swizzling a vector in-place, the swizzle temporary is needed */
- if (ref == slang_ref_forbid && tia->is_swizzled)
- if (!PLAB2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
- return GL_FALSE;
-
- /* assemble the master expression */
- if (!_slang_assemble_operation (A, &op->children[0], ref))
- return GL_FALSE;
-
- /* assemble the field expression */
- if (tia->is_swizzled)
- {
- if (ref == slang_ref_force)
- {
+ /* get type info of the result (field or swizzle) */
+ if (!_slang_typeof_operation(A, op, tia))
+ return GL_FALSE;
+
+ /* get type info of the master expression being accessed (struct or vector) */
+ if (!_slang_typeof_operation(A, &op->children[0], tib))
+ return GL_FALSE;
+
+ /* if swizzling a vector in-place, the swizzle temporary is needed */
+ if (ref == slang_ref_forbid && tia->is_swizzled)
+ if (!PLAB2(A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
+ return GL_FALSE;
+
+ /* assemble the master expression */
+ if (!_slang_assemble_operation(A, &op->children[0], ref))
+ return GL_FALSE;
+
+ /* assemble the field expression */
+ if (tia->is_swizzled) {
+ if (ref == slang_ref_force) {
#if 0
- if (tia->swz.num_components == 1)
- {
- /* simple case - adjust the vector's address to point to the selected component */
- if (!PLAB (file, slang_asm_addr_push, tia->swz.swizzle[0] * 4))
- return 0;
- if (!PUSH (file, slang_asm_addr_add))
- return 0;
- }
- else
+ if (tia->swz.num_components == 1) {
+ /* simple case - adjust the vector's address to point to
+ * the selected component
+ */
+ if (!PLAB(file, slang_asm_addr_push, tia->swz.swizzle[0] * 4))
+ return 0;
+ if (!PUSH(file, slang_asm_addr_add))
+ return 0;
+ }
+ else
#endif
- {
- /* two or more vector components are being referenced - the so-called write mask
- * must be passed to the upper operations and applied when assigning value
- * to this swizzle */
- A->swz = tia->swz;
- }
- }
- else
- {
- /* swizzle the vector in-place using the swizzle temporary */
- if (!_slang_assemble_constructor_from_swizzle (A, &tia->swz, &tia->spec, &tib->spec))
- return GL_FALSE;
- }
- }
- else
- {
- GLuint i, struct_size = 0, field_offset = 0, field_size = 0;
+ {
+ /* two or more vector components are being referenced -
+ * the so-called write mask must be passed to the upper
+ * operations and applied when assigning value to this swizzle
+ */
+ A->swz = tia->swz;
+ }
+ }
+ else {
+ /* swizzle the vector in-place using the swizzle temporary */
+ if (!_slang_assemble_constructor_from_swizzle
+ (A, &tia->swz, &tia->spec, &tib->spec))
+ return GL_FALSE;
+ }
+ }
+ else {
+ GLuint i, struct_size = 0, field_offset = 0, field_size = 0;
/*
* Calculate struct size, field offset and field size.
*/
- for (i = 0; i < tib->spec._struct->fields->num_variables; i++)
- {
- slang_variable *field;
- slang_storage_aggregate agg;
- GLuint size;
-
- field = &tib->spec._struct->fields->variables[i];
- if (!slang_storage_aggregate_construct (&agg))
- return GL_FALSE;
- if (!_slang_aggregate_variable (&agg, &field->type.specifier, field->array_len,
- A->space.funcs, A->space.structs, A->space.vars, A->mach, A->file, A->atoms))
- {
- slang_storage_aggregate_destruct (&agg);
- return GL_FALSE;
- }
- size = _slang_sizeof_aggregate (&agg);
- slang_storage_aggregate_destruct (&agg);
+ for (i = 0; i < tib->spec._struct->fields->num_variables; i++) {
+ slang_variable *field;
+ slang_storage_aggregate agg;
+ GLuint size;
+
+ field = &tib->spec._struct->fields->variables[i];
+ if (!slang_storage_aggregate_construct(&agg))
+ return GL_FALSE;
+ if (!_slang_aggregate_variable
+ (&agg, &field->type.specifier, field->array_len, A->space.funcs,
+ A->space.structs, A->space.vars, A->mach, A->file, A->atoms)) {
+ slang_storage_aggregate_destruct(&agg);
+ return GL_FALSE;
+ }
+ size = _slang_sizeof_aggregate(&agg);
+ slang_storage_aggregate_destruct(&agg);
if (op->a_id == field->a_name) {
field_size = size;
field_offset = struct_size;
}
struct_size += size;
- }
+ }
- if (ref == slang_ref_force)
- {
+ if (ref == slang_ref_force) {
GLboolean shift;
/*
- * OPTIMIZATION: If selecting first field, no address shifting is needed.
- */
+ * OPTIMIZATION: If selecting first field, no address shifting
+ * is needed.
+ */
shift = (field_offset != 0);
if (shift) {
- if (!PLAB (A->file, slang_asm_addr_push, field_offset))
+ if (!PLAB(A->file, slang_asm_addr_push, field_offset))
+ return GL_FALSE;
+ if (!PUSH(A->file, slang_asm_addr_add))
return GL_FALSE;
- if (!PUSH (A->file, slang_asm_addr_add))
- return GL_FALSE;
- }
- }
- else
- {
+ }
+ }
+ else {
GLboolean relocate, shrink;
- GLuint free_b = 0;
+ GLuint free_b = 0;
/*
- * OPTIMIZATION: If selecting last field, no relocation is needed.
- */
+ * OPTIMIZATION: If selecting last field, no relocation is needed.
+ */
relocate = (field_offset != (struct_size - field_size));
/*
- * OPTIMIZATION: If field and struct sizes are equal, no partial free is needed.
- */
+ * OPTIMIZATION: If field and struct sizes are equal, no partial
+ * free is needed.
+ */
shrink = (field_size != struct_size);
- if (relocate)
- {
- GLuint i;
+ if (relocate) {
+ GLuint i;
+
+ /*
+ * Move the selected element to the end of the master expression.
+ * Do it in reverse order to avoid overwriting itself.
+ */
+ if (!PLAB(A->file, slang_asm_addr_push, field_offset))
+ return GL_FALSE;
+ for (i = field_size; i > 0; i -= 4)
+ if (!PLAB2
+ (A->file, slang_asm_float_move,
+ struct_size - field_size + i, i))
+ return GL_FALSE;
+ free_b += 4;
+ }
+
+ if (shrink) {
+ /* free the rest of the master expression */
+ free_b += struct_size - field_size;
+ }
- /*
- * Move the selected element to the end of the master expression.
- * Do it in reverse order to avoid overwriting itself.
- */
- if (!PLAB (A->file, slang_asm_addr_push, field_offset))
+ if (free_b) {
+ if (!PLAB(A->file, slang_asm_local_free, free_b))
return GL_FALSE;
- for (i = field_size; i > 0; i -= 4)
- if (!PLAB2 (A->file, slang_asm_float_move, struct_size - field_size + i, i))
- return GL_FALSE;
- free_b += 4;
- }
-
- if (shrink)
- {
- /* free the rest of the master expression */
- free_b += struct_size - field_size;
- }
-
- if (free_b)
- {
- if (!PLAB (A->file, slang_asm_local_free, free_b))
- return GL_FALSE;
- }
- }
- }
-
- return GL_TRUE;
+ }
+ }
+ }
+
+ return GL_TRUE;
}
-GLboolean _slang_assemble_operation (slang_assemble_ctx *A, slang_operation *op, slang_ref_type ref)
+GLboolean
+_slang_assemble_operation(slang_assemble_ctx * A, slang_operation * op,
+ slang_ref_type ref)
{
- /* set default results */
- A->ref = /*(ref == slang_ref_freelance) ? slang_ref_force : */ref;
- A->swz.num_components = 0;
-
- switch (op->type)
- {
- case slang_oper_block_no_new_scope:
- case slang_oper_block_new_scope:
- {
- GLuint i;
-
- for (i = 0; i < op->num_children; i++)
- {
- if (!_slang_assemble_operation (A, &op->children[i], slang_ref_forbid/*slang_ref_freelance*/))
- return GL_FALSE;
- if (!_slang_cleanup_stack (A, &op->children[i]))
- return GL_FALSE;
- }
- }
- break;
- case slang_oper_variable_decl:
- {
- GLuint i;
- slang_operation assign;
- GLboolean result;
-
- /* Construct assignment expression placeholder. */
- if (!slang_operation_construct (&assign))
- return GL_FALSE;
- assign.type = slang_oper_assign;
- assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));
- if (assign.children == NULL)
- {
- slang_operation_destruct (&assign);
- return GL_FALSE;
- }
- for (assign.num_children = 0; assign.num_children < 2; assign.num_children++)
- if (!slang_operation_construct (&assign.children[assign.num_children]))
- {
- slang_operation_destruct (&assign);
- return GL_FALSE;
- }
-
- result = GL_TRUE;
- for (i = 0; i < op->num_children; i++)
- {
- slang_variable *var;
-
- var = _slang_locate_variable (op->children[i].locals, op->children[i].a_id, GL_TRUE);
- if (var == NULL)
- {
- result = GL_FALSE;
- break;
- }
- if (var->initializer == NULL)
- continue;
-
- if (!slang_operation_copy (&assign.children[0], &op->children[i]) ||
- !slang_operation_copy (&assign.children[1], var->initializer) ||
- !_slang_assemble_assign (A, &assign, "=", slang_ref_forbid) ||
- !_slang_cleanup_stack (A, &assign))
- {
- result = GL_FALSE;
- break;
- }
- }
- slang_operation_destruct (&assign);
- if (!result)
- return GL_FALSE;
- }
- break;
- case slang_oper_asm:
- {
- GLuint i;
-
- if (!_slang_assemble_operation (A, &op->children[0], slang_ref_force))
- return GL_FALSE;
- for (i = 1; i < op->num_children; i++)
- if (!_slang_assemble_operation (A, &op->children[i], slang_ref_forbid))
- return GL_FALSE;
- if (!call_asm_instruction (A, op->a_id))
- return GL_FALSE;
- }
- break;
- case slang_oper_break:
- if (!PLAB (A->file, slang_asm_jump, A->flow.loop_end))
- return GL_FALSE;
- break;
- case slang_oper_continue:
- if (!PLAB (A->file, slang_asm_jump, A->flow.loop_start))
- return GL_FALSE;
- break;
- case slang_oper_discard:
- if (!PUSH (A->file, slang_asm_discard))
- return GL_FALSE;
- if (!PUSH (A->file, slang_asm_exit))
- return GL_FALSE;
- break;
- case slang_oper_return:
- if (A->local.ret_size != 0)
- {
- /* push the result's address */
- if (!PLAB2 (A->file, slang_asm_local_addr, 0, A->local.ret_size))
- return GL_FALSE;
- if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
- return GL_FALSE;
-
- A->swz.num_components = 0;
- /* assign the operation to the function result (it was reserved on the stack) */
- if (!_slang_assemble_assignment (A, op->children))
- return GL_FALSE;
-
- if (!PLAB (A->file, slang_asm_local_free, 4))
- return GL_FALSE;
- }
- if (!PLAB (A->file, slang_asm_jump, A->flow.function_end))
- return GL_FALSE;
- break;
- case slang_oper_expression:
- if (ref == slang_ref_force)
- return GL_FALSE;
- if (!_slang_assemble_operation (A, &op->children[0], ref))
- return GL_FALSE;
- break;
- case slang_oper_if:
- if (!_slang_assemble_if (A, op))
- return GL_FALSE;
- break;
- case slang_oper_while:
- if (!_slang_assemble_while (A, op))
- return GL_FALSE;
- break;
- case slang_oper_do:
- if (!_slang_assemble_do (A, op))
- return GL_FALSE;
- break;
- case slang_oper_for:
- if (!_slang_assemble_for (A, op))
- return GL_FALSE;
- break;
- case slang_oper_void:
- break;
- case slang_oper_literal_bool:
- if (ref == slang_ref_force)
- return GL_FALSE;
- if (!PLIT (A->file, slang_asm_bool_push, op->literal))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_literal_int:
- if (ref == slang_ref_force)
- return GL_FALSE;
- if (!PLIT (A->file, slang_asm_int_push, op->literal))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_literal_float:
- if (ref == slang_ref_force)
- return GL_FALSE;
- if (!PLIT (A->file, slang_asm_float_push, op->literal))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_identifier:
- {
- slang_variable *var;
- GLuint size;
-
- /* find the variable and calculate its size */
- var = _slang_locate_variable (op->locals, op->a_id, GL_TRUE);
- if (var == NULL)
- return GL_FALSE;
- size = 0;
- if (!sizeof_variable (A, &var->type.specifier, slang_qual_none, var->array_len, &size))
- return GL_FALSE;
-
- /* prepare stack for dereferencing */
- if (ref == slang_ref_forbid)
- if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
- return GL_FALSE;
-
- /* push the variable's address */
- if (var->global)
- {
- if (!PLAB (A->file, slang_asm_global_addr, var->address))
- return GL_FALSE;
- }
- else
- {
- if (!PLAB2 (A->file, slang_asm_local_addr, var->address, size))
- return GL_FALSE;
- }
-
- /* perform the dereference */
- if (ref == slang_ref_forbid)
- {
- if (!PUSH (A->file, slang_asm_addr_copy))
- return GL_FALSE;
- if (!PLAB (A->file, slang_asm_local_free, 4))
- return GL_FALSE;
- if (!_slang_dereference (A, op))
- return GL_FALSE;
- }
- }
- break;
- case slang_oper_sequence:
- if (ref == slang_ref_force)
- return GL_FALSE;
- if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid/*slang_ref_freelance*/))
- return GL_FALSE;
- if (!_slang_cleanup_stack (A, &op->children[0]))
- return GL_FALSE;
- if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_assign:
- if (!_slang_assemble_assign (A, op, "=", ref))
- return GL_FALSE;
- break;
- case slang_oper_addassign:
- if (!_slang_assemble_assign (A, op, "+=", ref))
- return GL_FALSE;
- A->ref = ref;
- break;
- case slang_oper_subassign:
- if (!_slang_assemble_assign (A, op, "-=", ref))
- return GL_FALSE;
- A->ref = ref;
- break;
- case slang_oper_mulassign:
- if (!_slang_assemble_assign (A, op, "*=", ref))
- return GL_FALSE;
- A->ref = ref;
- break;
- /*case slang_oper_modassign:*/
- /*case slang_oper_lshassign:*/
- /*case slang_oper_rshassign:*/
- /*case slang_oper_orassign:*/
- /*case slang_oper_xorassign:*/
- /*case slang_oper_andassign:*/
- case slang_oper_divassign:
- if (!_slang_assemble_assign (A, op, "/=", ref))
- return GL_FALSE;
- A->ref = ref;
- break;
- case slang_oper_select:
- if (!_slang_assemble_select (A, op))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_logicalor:
- if (!_slang_assemble_logicalor (A, op))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_logicaland:
- if (!_slang_assemble_logicaland (A, op))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_logicalxor:
- if (!_slang_assemble_function_call_name (A, "^^", op->children, 2, GL_FALSE))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- /*case slang_oper_bitor:*/
- /*case slang_oper_bitxor:*/
- /*case slang_oper_bitand:*/
- case slang_oper_less:
- if (!_slang_assemble_function_call_name (A, "<", op->children, 2, GL_FALSE))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_greater:
- if (!_slang_assemble_function_call_name (A, ">", op->children, 2, GL_FALSE))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_lessequal:
- if (!_slang_assemble_function_call_name (A, "<=", op->children, 2, GL_FALSE))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_greaterequal:
- if (!_slang_assemble_function_call_name (A, ">=", op->children, 2, GL_FALSE))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- /*case slang_oper_lshift:*/
- /*case slang_oper_rshift:*/
- case slang_oper_add:
- if (!_slang_assemble_function_call_name (A, "+", op->children, 2, GL_FALSE))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_subtract:
- if (!_slang_assemble_function_call_name (A, "-", op->children, 2, GL_FALSE))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_multiply:
- if (!_slang_assemble_function_call_name (A, "*", op->children, 2, GL_FALSE))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- /*case slang_oper_modulus:*/
- case slang_oper_divide:
- if (!_slang_assemble_function_call_name (A, "/", op->children, 2, GL_FALSE))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_equal:
- if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
- return GL_FALSE;
- if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
- return GL_FALSE;
- if (!equality (A, op->children, GL_TRUE))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_notequal:
- if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
- return GL_FALSE;
- if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
- return GL_FALSE;
- if (!equality (A, op->children, GL_FALSE))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_preincrement:
- if (!_slang_assemble_assign (A, op, "++", ref))
- return GL_FALSE;
- A->ref = ref;
- break;
- case slang_oper_predecrement:
- if (!_slang_assemble_assign (A, op, "--", ref))
- return GL_FALSE;
- A->ref = ref;
- break;
- case slang_oper_plus:
- if (!_slang_dereference (A, op))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_minus:
- if (!_slang_assemble_function_call_name (A, "-", op->children, 1, GL_FALSE))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- /*case slang_oper_complement:*/
- case slang_oper_not:
- if (!_slang_assemble_function_call_name (A, "!", op->children, 1, GL_FALSE))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_subscript:
- {
- slang_assembly_typeinfo ti_arr, ti_elem;
-
- if (!slang_assembly_typeinfo_construct (&ti_arr))
- return GL_FALSE;
- if (!slang_assembly_typeinfo_construct (&ti_elem))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- return GL_FALSE;
- }
- if (!handle_subscript (A, &ti_elem, &ti_arr, op, ref))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
- return GL_FALSE;
- }
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
- }
- break;
- case slang_oper_call:
- {
- slang_function *fun;
-
- fun = _slang_locate_function (A->space.funcs, op->a_id, op->children, op->num_children,
- &A->space, A->atoms);
- if (fun == NULL)
- {
- if (!_slang_assemble_constructor (A, op))
- return GL_FALSE;
- }
- else
- {
- if (!_slang_assemble_function_call (A, fun, op->children, op->num_children, GL_FALSE))
- return GL_FALSE;
- }
- A->ref = slang_ref_forbid;
- }
- break;
- case slang_oper_field:
- {
- slang_assembly_typeinfo ti_after, ti_before;
-
- if (!slang_assembly_typeinfo_construct (&ti_after))
- return GL_FALSE;
- if (!slang_assembly_typeinfo_construct (&ti_before))
- {
- slang_assembly_typeinfo_destruct (&ti_after);
- return GL_FALSE;
- }
- if (!handle_field (A, &ti_after, &ti_before, op, ref))
- {
- slang_assembly_typeinfo_destruct (&ti_after);
- slang_assembly_typeinfo_destruct (&ti_before);
- return GL_FALSE;
- }
- slang_assembly_typeinfo_destruct (&ti_after);
- slang_assembly_typeinfo_destruct (&ti_before);
- }
- break;
- case slang_oper_postincrement:
- if (!assemble_function_call_name_dummyint (A, "++", op->children))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- case slang_oper_postdecrement:
- if (!assemble_function_call_name_dummyint (A, "--", op->children))
- return GL_FALSE;
- A->ref = slang_ref_forbid;
- break;
- default:
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
+ /* set default results */
+ A->ref = /*(ref == slang_ref_freelance) ? slang_ref_force : */ ref;
+ A->swz.num_components = 0;
+
+ switch (op->type) {
+ case slang_oper_block_no_new_scope:
+ case slang_oper_block_new_scope:
+ {
+ GLuint i;
+
+ for (i = 0; i < op->num_children; i++) {
+ if (!_slang_assemble_operation
+ (A, &op->children[i],
+ slang_ref_forbid /*slang_ref_freelance */ ))
+ return GL_FALSE;
+ if (!_slang_cleanup_stack(A, &op->children[i]))
+ return GL_FALSE;
+ }
+ }
+ break;
+ case slang_oper_variable_decl:
+ {
+ GLuint i;
+ slang_operation assign;
+ GLboolean result;
+
+ /* Construct assignment expression placeholder. */
+ if (!slang_operation_construct(&assign))
+ return GL_FALSE;
+ assign.type = slang_oper_assign;
+ assign.children =
+ (slang_operation *) slang_alloc_malloc(2 *
+ sizeof(slang_operation));
+ if (assign.children == NULL) {
+ slang_operation_destruct(&assign);
+ return GL_FALSE;
+ }
+ for (assign.num_children = 0; assign.num_children < 2;
+ assign.num_children++)
+ if (!slang_operation_construct
+ (&assign.children[assign.num_children])) {
+ slang_operation_destruct(&assign);
+ return GL_FALSE;
+ }
+
+ result = GL_TRUE;
+ for (i = 0; i < op->num_children; i++) {
+ slang_variable *var;
+
+ var =
+ _slang_locate_variable(op->children[i].locals,
+ op->children[i].a_id, GL_TRUE);
+ if (var == NULL) {
+ result = GL_FALSE;
+ break;
+ }
+ if (var->initializer == NULL)
+ continue;
+
+ if (!slang_operation_copy(&assign.children[0], &op->children[i])
+ || !slang_operation_copy(&assign.children[1],
+ var->initializer)
+ || !_slang_assemble_assign(A, &assign, "=", slang_ref_forbid)
+ || !_slang_cleanup_stack(A, &assign)) {
+ result = GL_FALSE;
+ break;
+ }
+ }
+ slang_operation_destruct(&assign);
+ if (!result)
+ return GL_FALSE;
+ }
+ break;
+ case slang_oper_asm:
+ {
+ GLuint i;
+ if (!_slang_assemble_operation(A, &op->children[0], slang_ref_force))
+ return GL_FALSE;
+ for (i = 1; i < op->num_children; i++)
+ if (!_slang_assemble_operation
+ (A, &op->children[i], slang_ref_forbid))
+ return GL_FALSE;
+ if (!call_asm_instruction(A, op->a_id))
+ return GL_FALSE;
+ }
+ break;
+ case slang_oper_break:
+ if (!PLAB(A->file, slang_asm_jump, A->flow.loop_end))
+ return GL_FALSE;
+ break;
+ case slang_oper_continue:
+ if (!PLAB(A->file, slang_asm_jump, A->flow.loop_start))
+ return GL_FALSE;
+ break;
+ case slang_oper_discard:
+ if (!PUSH(A->file, slang_asm_discard))
+ return GL_FALSE;
+ if (!PUSH(A->file, slang_asm_exit))
+ return GL_FALSE;
+ break;
+ case slang_oper_return:
+ if (A->local.ret_size != 0) {
+ /* push the result's address */
+ if (!PLAB2(A->file, slang_asm_local_addr, 0, A->local.ret_size))
+ return GL_FALSE;
+ if (!_slang_assemble_operation
+ (A, &op->children[0], slang_ref_forbid))
+ return GL_FALSE;
+
+ A->swz.num_components = 0;
+ /* assign the operation to the function result (it was reserved on the stack) */
+ if (!_slang_assemble_assignment(A, op->children))
+ return GL_FALSE;
+
+ if (!PLAB(A->file, slang_asm_local_free, 4))
+ return GL_FALSE;
+ }
+ if (!PLAB(A->file, slang_asm_jump, A->flow.function_end))
+ return GL_FALSE;
+ break;
+ case slang_oper_expression:
+ if (ref == slang_ref_force)
+ return GL_FALSE;
+ if (!_slang_assemble_operation(A, &op->children[0], ref))
+ return GL_FALSE;
+ break;
+ case slang_oper_if:
+ if (!_slang_assemble_if(A, op))
+ return GL_FALSE;
+ break;
+ case slang_oper_while:
+ if (!_slang_assemble_while(A, op))
+ return GL_FALSE;
+ break;
+ case slang_oper_do:
+ if (!_slang_assemble_do(A, op))
+ return GL_FALSE;
+ break;
+ case slang_oper_for:
+ if (!_slang_assemble_for(A, op))
+ return GL_FALSE;
+ break;
+ case slang_oper_void:
+ break;
+ case slang_oper_literal_bool:
+ if (ref == slang_ref_force)
+ return GL_FALSE;
+ if (!PLIT(A->file, slang_asm_bool_push, op->literal))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_literal_int:
+ if (ref == slang_ref_force)
+ return GL_FALSE;
+ if (!PLIT(A->file, slang_asm_int_push, op->literal))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_literal_float:
+ if (ref == slang_ref_force)
+ return GL_FALSE;
+ if (!PLIT(A->file, slang_asm_float_push, op->literal))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_identifier:
+ {
+ slang_variable *var;
+ GLuint size;
+
+ /* find the variable and calculate its size */
+ var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE);
+ if (var == NULL)
+ return GL_FALSE;
+ size = 0;
+ if (!sizeof_variable
+ (A, &var->type.specifier, slang_qual_none, var->array_len,
+ &size))
+ return GL_FALSE;
+
+ /* prepare stack for dereferencing */
+ if (ref == slang_ref_forbid)
+ if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
+ return GL_FALSE;
+
+ /* push the variable's address */
+ if (var->global) {
+ if (!PLAB(A->file, slang_asm_global_addr, var->address))
+ return GL_FALSE;
+ }
+ else {
+ if (!PLAB2(A->file, slang_asm_local_addr, var->address, size))
+ return GL_FALSE;
+ }
+
+ /* perform the dereference */
+ if (ref == slang_ref_forbid) {
+ if (!PUSH(A->file, slang_asm_addr_copy))
+ return GL_FALSE;
+ if (!PLAB(A->file, slang_asm_local_free, 4))
+ return GL_FALSE;
+ if (!_slang_dereference(A, op))
+ return GL_FALSE;
+ }
+ }
+ break;
+ case slang_oper_sequence:
+ if (ref == slang_ref_force)
+ return GL_FALSE;
+ if (!_slang_assemble_operation(A, &op->children[0],
+ slang_ref_forbid /*slang_ref_freelance */ ))
+ return GL_FALSE;
+ if (!_slang_cleanup_stack(A, &op->children[0]))
+ return GL_FALSE;
+ if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_assign:
+ if (!_slang_assemble_assign(A, op, "=", ref))
+ return GL_FALSE;
+ break;
+ case slang_oper_addassign:
+ if (!_slang_assemble_assign(A, op, "+=", ref))
+ return GL_FALSE;
+ A->ref = ref;
+ break;
+ case slang_oper_subassign:
+ if (!_slang_assemble_assign(A, op, "-=", ref))
+ return GL_FALSE;
+ A->ref = ref;
+ break;
+ case slang_oper_mulassign:
+ if (!_slang_assemble_assign(A, op, "*=", ref))
+ return GL_FALSE;
+ A->ref = ref;
+ break;
+ /*case slang_oper_modassign: */
+ /*case slang_oper_lshassign: */
+ /*case slang_oper_rshassign: */
+ /*case slang_oper_orassign: */
+ /*case slang_oper_xorassign: */
+ /*case slang_oper_andassign: */
+ case slang_oper_divassign:
+ if (!_slang_assemble_assign(A, op, "/=", ref))
+ return GL_FALSE;
+ A->ref = ref;
+ break;
+ case slang_oper_select:
+ if (!_slang_assemble_select(A, op))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_logicalor:
+ if (!_slang_assemble_logicalor(A, op))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_logicaland:
+ if (!_slang_assemble_logicaland(A, op))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_logicalxor:
+ if (!_slang_assemble_function_call_name(A, "^^", op->children, 2, GL_FALSE))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ /*case slang_oper_bitor: */
+ /*case slang_oper_bitxor: */
+ /*case slang_oper_bitand: */
+ case slang_oper_less:
+ if (!_slang_assemble_function_call_name(A, "<", op->children, 2, GL_FALSE))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_greater:
+ if (!_slang_assemble_function_call_name(A, ">", op->children, 2, GL_FALSE))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_lessequal:
+ if (!_slang_assemble_function_call_name(A, "<=", op->children, 2, GL_FALSE))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_greaterequal:
+ if (!_slang_assemble_function_call_name(A, ">=", op->children, 2, GL_FALSE))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ /*case slang_oper_lshift: */
+ /*case slang_oper_rshift: */
+ case slang_oper_add:
+ if (!_slang_assemble_function_call_name(A, "+", op->children, 2, GL_FALSE))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_subtract:
+ if (!_slang_assemble_function_call_name(A, "-", op->children, 2, GL_FALSE))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_multiply:
+ if (!_slang_assemble_function_call_name(A, "*", op->children, 2, GL_FALSE))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ /*case slang_oper_modulus: */
+ case slang_oper_divide:
+ if (!_slang_assemble_function_call_name(A, "/", op->children, 2, GL_FALSE))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_equal:
+ if (!_slang_assemble_operation(A, &op->children[0], slang_ref_forbid))
+ return GL_FALSE;
+ if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid))
+ return GL_FALSE;
+ if (!equality(A, op->children, GL_TRUE))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_notequal:
+ if (!_slang_assemble_operation(A, &op->children[0], slang_ref_forbid))
+ return GL_FALSE;
+ if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid))
+ return GL_FALSE;
+ if (!equality(A, op->children, GL_FALSE))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_preincrement:
+ if (!_slang_assemble_assign(A, op, "++", ref))
+ return GL_FALSE;
+ A->ref = ref;
+ break;
+ case slang_oper_predecrement:
+ if (!_slang_assemble_assign(A, op, "--", ref))
+ return GL_FALSE;
+ A->ref = ref;
+ break;
+ case slang_oper_plus:
+ if (!_slang_dereference(A, op))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_minus:
+ if (!_slang_assemble_function_call_name
+ (A, "-", op->children, 1, GL_FALSE))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ /*case slang_oper_complement: */
+ case slang_oper_not:
+ if (!_slang_assemble_function_call_name
+ (A, "!", op->children, 1, GL_FALSE))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_subscript:
+ {
+ slang_assembly_typeinfo ti_arr, ti_elem;
+
+ if (!slang_assembly_typeinfo_construct(&ti_arr))
+ return GL_FALSE;
+ if (!slang_assembly_typeinfo_construct(&ti_elem)) {
+ slang_assembly_typeinfo_destruct(&ti_arr);
+ return GL_FALSE;
+ }
+ if (!handle_subscript(A, &ti_elem, &ti_arr, op, ref)) {
+ slang_assembly_typeinfo_destruct(&ti_arr);
+ slang_assembly_typeinfo_destruct(&ti_elem);
+ return GL_FALSE;
+ }
+ slang_assembly_typeinfo_destruct(&ti_arr);
+ slang_assembly_typeinfo_destruct(&ti_elem);
+ }
+ break;
+ case slang_oper_call:
+ {
+ slang_function *fun;
+
+ fun =
+ _slang_locate_function(A->space.funcs, op->a_id, op->children,
+ op->num_children, &A->space, A->atoms);
+ if (fun == NULL) {
+ if (!_slang_assemble_constructor(A, op))
+ return GL_FALSE;
+ }
+ else {
+ if (!_slang_assemble_function_call
+ (A, fun, op->children, op->num_children, GL_FALSE))
+ return GL_FALSE;
+ }
+ A->ref = slang_ref_forbid;
+ }
+ break;
+ case slang_oper_field:
+ {
+ slang_assembly_typeinfo ti_after, ti_before;
+
+ if (!slang_assembly_typeinfo_construct(&ti_after))
+ return GL_FALSE;
+ if (!slang_assembly_typeinfo_construct(&ti_before)) {
+ slang_assembly_typeinfo_destruct(&ti_after);
+ return GL_FALSE;
+ }
+ if (!handle_field(A, &ti_after, &ti_before, op, ref)) {
+ slang_assembly_typeinfo_destruct(&ti_after);
+ slang_assembly_typeinfo_destruct(&ti_before);
+ return GL_FALSE;
+ }
+ slang_assembly_typeinfo_destruct(&ti_after);
+ slang_assembly_typeinfo_destruct(&ti_before);
+ }
+ break;
+ case slang_oper_postincrement:
+ if (!assemble_function_call_name_dummyint(A, "++", op->children))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ case slang_oper_postdecrement:
+ if (!assemble_function_call_name_dummyint(A, "--", op->children))
+ return GL_FALSE;
+ A->ref = slang_ref_forbid;
+ break;
+ default:
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+}
diff --git a/src/mesa/shader/slang/slang_assemble.h b/src/mesa/shader/slang/slang_assemble.h
index 95e4fa263a..d004e66500 100644
--- a/src/mesa/shader/slang/slang_assemble.h
+++ b/src/mesa/shader/slang/slang_assemble.h
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.2
*
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
*
@@ -22,7 +22,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#if !defined SLANG_ASSEMBLE_H
+#ifndef SLANG_ASSEMBLE_H
#define SLANG_ASSEMBLE_H
#include "slang_utility.h"
@@ -31,72 +31,82 @@
extern "C" {
#endif
+
struct slang_operation_;
typedef enum slang_assembly_type_
{
- /* core */
- slang_asm_none,
- slang_asm_float_copy,
- slang_asm_float_move,
- slang_asm_float_push,
- slang_asm_float_deref,
- slang_asm_float_add,
- slang_asm_float_multiply,
- slang_asm_float_divide,
- slang_asm_float_negate,
- slang_asm_float_less,
- slang_asm_float_equal_exp,
- slang_asm_float_equal_int,
- slang_asm_float_to_int,
- slang_asm_float_sine,
- slang_asm_float_arcsine,
- slang_asm_float_arctan,
- slang_asm_float_power,
- slang_asm_float_log2,
- slang_asm_float_floor,
- slang_asm_float_ceil,
- slang_asm_float_noise1,
- slang_asm_float_noise2,
- slang_asm_float_noise3,
- slang_asm_float_noise4,
- slang_asm_int_copy,
- slang_asm_int_move,
- slang_asm_int_push,
- slang_asm_int_deref,
- slang_asm_int_to_float,
- slang_asm_int_to_addr,
- slang_asm_bool_copy,
- slang_asm_bool_move,
- slang_asm_bool_push,
- slang_asm_bool_deref,
- slang_asm_addr_copy,
- slang_asm_addr_push,
- slang_asm_addr_deref,
- slang_asm_addr_add,
- slang_asm_addr_multiply,
- slang_asm_vec4_tex1d,
- slang_asm_vec4_tex2d,
- slang_asm_vec4_tex3d,
- slang_asm_vec4_texcube,
- slang_asm_vec4_shad1d,
- slang_asm_vec4_shad2d,
- slang_asm_jump,
- slang_asm_jump_if_zero,
- slang_asm_enter,
- slang_asm_leave,
- slang_asm_local_alloc,
- slang_asm_local_free,
- slang_asm_local_addr,
- slang_asm_global_addr,
- slang_asm_call,
- slang_asm_return,
- slang_asm_discard,
- slang_asm_exit,
+ /* core */
+ slang_asm_none,
+ slang_asm_float_copy,
+ slang_asm_float_move,
+ slang_asm_float_push,
+ slang_asm_float_deref,
+ slang_asm_float_add, /* a = pop(); b = pop(); push(a + b); */
+ slang_asm_float_multiply,
+ slang_asm_float_divide,
+ slang_asm_float_negate, /* push(-pop()) */
+ slang_asm_float_less, /* a = pop(); b = pop(); push(a < b); */
+ slang_asm_float_equal_exp,
+ slang_asm_float_equal_int,
+ slang_asm_float_to_int, /* push(floatToInt(pop())) */
+ slang_asm_float_sine, /* push(sin(pop()) */
+ slang_asm_float_arcsine,
+ slang_asm_float_arctan,
+ slang_asm_float_power, /* push(pow(pop(), pop())) */
+ slang_asm_float_log2,
+ slang_asm_float_floor,
+ slang_asm_float_ceil,
+ slang_asm_float_noise1, /* push(noise1(pop()) */
+ slang_asm_float_noise2, /* push(noise2(pop(), pop())) */
+ slang_asm_float_noise3,
+ slang_asm_float_noise4,
+
+ slang_asm_int_copy,
+ slang_asm_int_move,
+ slang_asm_int_push,
+ slang_asm_int_deref,
+ slang_asm_int_to_float,
+ slang_asm_int_to_addr,
+
+ slang_asm_bool_copy,
+ slang_asm_bool_move,
+ slang_asm_bool_push,
+ slang_asm_bool_deref,
+
+ slang_asm_addr_copy,
+ slang_asm_addr_push,
+ slang_asm_addr_deref,
+ slang_asm_addr_add,
+ slang_asm_addr_multiply,
+
+ slang_asm_vec4_tex1d,
+ slang_asm_vec4_tex2d,
+ slang_asm_vec4_tex3d,
+ slang_asm_vec4_texcube,
+ slang_asm_vec4_shad1d,
+ slang_asm_vec4_shad2d,
+
+ slang_asm_jump,
+ slang_asm_jump_if_zero,
+
+ slang_asm_enter,
+ slang_asm_leave,
+
+ slang_asm_local_alloc,
+ slang_asm_local_free,
+ slang_asm_local_addr,
+ slang_asm_global_addr,
+
+ slang_asm_call, /* push(ip); jump(inst->param[0]); */
+ slang_asm_return,
+
+ slang_asm_discard,
+ slang_asm_exit,
/* GL_MESA_shader_debug */
- slang_asm_float_print,
- slang_asm_int_print,
- slang_asm_bool_print,
+ slang_asm_float_print,
+ slang_asm_int_print,
+ slang_asm_bool_print,
/* vec4 */
slang_asm_float_to_vec4,
slang_asm_vec4_add,
@@ -109,111 +119,152 @@ typedef enum slang_assembly_type_
slang_asm_vec4_deref,
slang_asm_vec4_equal_int,
/* not a real assembly instruction */
- slang_asm__last
+ slang_asm__last
} slang_assembly_type;
+
+/**
+ * An assembly-level shader instruction.
+ */
typedef struct slang_assembly_
{
- slang_assembly_type type;
- GLfloat literal;
- GLuint param[2];
+ slang_assembly_type type; /**< The instruction opcode */
+ GLfloat literal; /**< float literal */
+ GLuint param[2]; /**< Two integer/address parameters */
} slang_assembly;
+
+/**
+ * A list of slang_assembly instructions
+ */
typedef struct slang_assembly_file_
{
- slang_assembly *code;
- GLuint count;
- GLuint capacity;
+ slang_assembly *code;
+ GLuint count;
+ GLuint capacity;
} slang_assembly_file;
+
+extern GLvoid
+_slang_assembly_file_ctr(slang_assembly_file *);
+
extern GLvoid
-_slang_assembly_file_ctr (slang_assembly_file *);
+slang_assembly_file_destruct(slang_assembly_file *);
+
+extern GLboolean
+slang_assembly_file_push(slang_assembly_file *, slang_assembly_type);
+
+extern GLboolean
+slang_assembly_file_push_label(slang_assembly_file *,
+ slang_assembly_type, GLuint);
+
+extern GLboolean
+slang_assembly_file_push_label2(slang_assembly_file *, slang_assembly_type,
+ GLuint, GLuint);
+
+extern GLboolean
+slang_assembly_file_push_literal(slang_assembly_file *,
+ slang_assembly_type, GLfloat);
-GLvoid slang_assembly_file_destruct (slang_assembly_file *);
-GLboolean slang_assembly_file_push (slang_assembly_file *, slang_assembly_type);
-GLboolean slang_assembly_file_push_label (slang_assembly_file *, slang_assembly_type, GLuint);
-GLboolean slang_assembly_file_push_label2 (slang_assembly_file *, slang_assembly_type, GLuint, GLuint);
-GLboolean slang_assembly_file_push_literal (slang_assembly_file *, slang_assembly_type, GLfloat);
typedef struct slang_assembly_file_restore_point_
{
- GLuint count;
+ GLuint count;
} slang_assembly_file_restore_point;
-GLboolean slang_assembly_file_restore_point_save (slang_assembly_file *,
- slang_assembly_file_restore_point *);
-GLboolean slang_assembly_file_restore_point_load (slang_assembly_file *,
- slang_assembly_file_restore_point *);
+
+extern GLboolean
+slang_assembly_file_restore_point_save(slang_assembly_file *,
+ slang_assembly_file_restore_point *);
+
+extern GLboolean
+slang_assembly_file_restore_point_load(slang_assembly_file *,
+ slang_assembly_file_restore_point *);
+
typedef struct slang_assembly_flow_control_
{
- GLuint loop_start; /* for "continue" statement */
- GLuint loop_end; /* for "break" statement */
- GLuint function_end; /* for "return" statement */
+ GLuint loop_start; /**< for "continue" statement */
+ GLuint loop_end; /**< for "break" statement */
+ GLuint function_end; /**< for "return" statement */
} slang_assembly_flow_control;
typedef struct slang_assembly_local_info_
{
- GLuint ret_size;
- GLuint addr_tmp;
- GLuint swizzle_tmp;
+ GLuint ret_size;
+ GLuint addr_tmp;
+ GLuint swizzle_tmp;
} slang_assembly_local_info;
typedef enum
{
- slang_ref_force,
- slang_ref_forbid/*,
- slang_ref_freelance*/
+ slang_ref_force,
+ slang_ref_forbid /**< slang_ref_freelance */
} slang_ref_type;
-/*
- * Holds a complete information about vector swizzle - the <swizzle> array contains
- * vector component source indices, where 0 is "x", 1 is "y", 2 is "z" and 3 is "w".
+/**
+ * Holds complete information about vector swizzle - the <swizzle>
+ * array contains vector component source indices, where 0 is "x", 1
+ * is "y", 2 is "z" and 3 is "w".
* Example: "xwz" --> { 3, { 0, 3, 2, not used } }.
*/
typedef struct slang_swizzle_
{
- GLuint num_components;
- GLuint swizzle[4];
+ GLuint num_components;
+ GLuint swizzle[4];
} slang_swizzle;
typedef struct slang_assembly_name_space_
{
- struct slang_function_scope_ *funcs;
- struct slang_struct_scope_ *structs;
- struct slang_variable_scope_ *vars;
+ struct slang_function_scope_ *funcs;
+ struct slang_struct_scope_ *structs;
+ struct slang_variable_scope_ *vars;
} slang_assembly_name_space;
typedef struct slang_assemble_ctx_
{
- slang_assembly_file *file;
- struct slang_machine_ *mach;
- slang_atom_pool *atoms;
- slang_assembly_name_space space;
- slang_assembly_flow_control flow;
- slang_assembly_local_info local;
- slang_ref_type ref;
- slang_swizzle swz;
+ slang_assembly_file *file;
+ struct slang_machine_ *mach;
+ slang_atom_pool *atoms;
+ slang_assembly_name_space space;
+ slang_assembly_flow_control flow;
+ slang_assembly_local_info local;
+ slang_ref_type ref;
+ slang_swizzle swz;
} slang_assemble_ctx;
-struct slang_function_ *_slang_locate_function (struct slang_function_scope_ *funcs, slang_atom name,
- struct slang_operation_ *params, GLuint num_params, slang_assembly_name_space *space,
- slang_atom_pool *);
+extern struct slang_function_ *
+_slang_locate_function(const struct slang_function_scope_ *funcs,
+ slang_atom name, const struct slang_operation_ *params,
+ GLuint num_params,
+ const slang_assembly_name_space *space,
+ slang_atom_pool *);
-GLboolean _slang_assemble_function (slang_assemble_ctx *, struct slang_function_ *);
+extern GLboolean
+_slang_assemble_function(slang_assemble_ctx *, struct slang_function_ *);
-GLboolean _slang_cleanup_stack (slang_assemble_ctx *, struct slang_operation_ *);
+extern GLboolean
+_slang_assemble_function2(slang_assemble_ctx * , struct slang_function_ *);
-GLboolean _slang_dereference (slang_assemble_ctx *, struct slang_operation_ *);
+extern GLboolean
+_slang_cleanup_stack(slang_assemble_ctx *, struct slang_operation_ *);
-GLboolean _slang_assemble_function_call (slang_assemble_ctx *, struct slang_function_ *,
- struct slang_operation_ *, GLuint, GLboolean);
+extern GLboolean
+_slang_dereference(slang_assemble_ctx *, struct slang_operation_ *);
-GLboolean _slang_assemble_function_call_name (slang_assemble_ctx *, const char *,
- struct slang_operation_ *, GLuint, GLboolean);
+extern GLboolean
+_slang_assemble_function_call(slang_assemble_ctx *, struct slang_function_ *,
+ struct slang_operation_ *, GLuint, GLboolean);
+
+extern GLboolean
+_slang_assemble_function_call_name(slang_assemble_ctx *, const char *,
+ struct slang_operation_ *, GLuint,
+ GLboolean);
+
+extern GLboolean
+_slang_assemble_operation(slang_assemble_ctx *, struct slang_operation_ *,
+ slang_ref_type);
-GLboolean _slang_assemble_operation (slang_assemble_ctx *, struct slang_operation_ *,
- slang_ref_type);
#ifdef __cplusplus
}
@@ -225,4 +276,3 @@ GLboolean _slang_assemble_operation (slang_assemble_ctx *, struct slang_operatio
#include "slang_assemble_conditional.h"
#endif
-
diff --git a/src/mesa/shader/slang/slang_assemble_assignment.c b/src/mesa/shader/slang/slang_assemble_assignment.c
index d894a8db18..a1038671c4 100644
--- a/src/mesa/shader/slang/slang_assemble_assignment.c
+++ b/src/mesa/shader/slang/slang_assemble_assignment.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.2
*
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
*
@@ -53,8 +53,11 @@
* +------------------+
*/
+
+
static GLboolean
-assign_basic (slang_assemble_ctx *A, slang_storage_type type, GLuint *index, GLuint size)
+assign_basic(slang_assemble_ctx * A, slang_storage_type type, GLuint * index,
+ GLuint size)
{
GLuint dst_offset, dst_addr_loc;
slang_assembly_type ty;
@@ -85,22 +88,25 @@ assign_basic (slang_assemble_ctx *A, slang_storage_type type, GLuint *index, GLu
ty = slang_asm_none;
}
- /* Calculate the distance from top of the stack to the destination address. As the
- * copy operation progresses, components of the source are being successively popped
- * off the stack by the amount of *index increase step.
- */
+ /* Calculate the distance from top of the stack to the destination
+ * address. As the copy operation progresses, components of the
+ * source are being successively popped off the stack by the amount
+ * of *index increase step.
+ */
dst_addr_loc = size - *index;
- if (!slang_assembly_file_push_label2 (A->file, ty, dst_addr_loc, dst_offset))
+ if (!slang_assembly_file_push_label2
+ (A->file, ty, dst_addr_loc, dst_offset))
return GL_FALSE;
- *index += _slang_sizeof_type (type);
+ *index += _slang_sizeof_type(type);
return GL_TRUE;
}
+
static GLboolean
-assign_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLuint *index,
- GLuint size)
+assign_aggregate(slang_assemble_ctx * A, const slang_storage_aggregate * agg,
+ GLuint * index, GLuint size)
{
GLuint i;
@@ -110,25 +116,26 @@ assign_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLu
for (j = 0; j < arr->length; j++) {
if (arr->type == slang_stor_aggregate) {
- if (!assign_aggregate (A, arr->aggregate, index, size))
+ if (!assign_aggregate(A, arr->aggregate, index, size))
return GL_FALSE;
}
else {
- /* When the destination is swizzled, we are forced to do float_copy, even if
- * vec4 extension is enabled with vec4_copy operation.
+ /* When the destination is swizzled, we are forced to do
+ * float_copy, even if vec4 extension is enabled with
+ * vec4_copy operation.
*/
if (A->swz.num_components != 0 && arr->type == slang_stor_vec4) {
- if (!assign_basic (A, slang_stor_float, index, size))
+ if (!assign_basic(A, slang_stor_float, index, size))
return GL_FALSE;
- if (!assign_basic (A, slang_stor_float, index, size))
+ if (!assign_basic(A, slang_stor_float, index, size))
return GL_FALSE;
- if (!assign_basic (A, slang_stor_float, index, size))
+ if (!assign_basic(A, slang_stor_float, index, size))
return GL_FALSE;
- if (!assign_basic (A, slang_stor_float, index, size))
+ if (!assign_basic(A, slang_stor_float, index, size))
return GL_FALSE;
}
else {
- if (!assign_basic (A, arr->type, index, size))
+ if (!assign_basic(A, arr->type, index, size))
return GL_FALSE;
}
}
@@ -138,80 +145,79 @@ assign_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLu
return GL_TRUE;
}
-GLboolean _slang_assemble_assignment (slang_assemble_ctx *A, slang_operation *op)
+
+GLboolean
+_slang_assemble_assignment(slang_assemble_ctx * A, const slang_operation * op)
{
- slang_assembly_typeinfo ti;
- GLboolean result = GL_FALSE;
- slang_storage_aggregate agg;
- GLuint index, size;
-
- if (!slang_assembly_typeinfo_construct (&ti))
- return GL_FALSE;
- if (!_slang_typeof_operation (A, op, &ti))
- goto end1;
-
- if (!slang_storage_aggregate_construct (&agg))
- goto end1;
- if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs,
- A->space.vars, A->mach, A->file, A->atoms))
- goto end;
-
- index = 0;
- size = _slang_sizeof_aggregate (&agg);
- result = assign_aggregate (A, &agg, &index, size);
-
-end1:
- slang_storage_aggregate_destruct (&agg);
-end:
- slang_assembly_typeinfo_destruct (&ti);
- return result;
+ slang_assembly_typeinfo ti;
+ GLboolean result = GL_FALSE;
+ slang_storage_aggregate agg;
+ GLuint index, size;
+
+ if (!slang_assembly_typeinfo_construct(&ti))
+ return GL_FALSE;
+ if (!_slang_typeof_operation(A, op, &ti))
+ goto end1;
+
+ if (!slang_storage_aggregate_construct(&agg))
+ goto end1;
+ if (!_slang_aggregate_variable(&agg, &ti.spec, 0, A->space.funcs,
+ A->space.structs, A->space.vars,
+ A->mach, A->file, A->atoms))
+ goto end;
+
+ index = 0;
+ size = _slang_sizeof_aggregate(&agg);
+ result = assign_aggregate(A, &agg, &index, size);
+
+ end1:
+ slang_storage_aggregate_destruct(&agg);
+ end:
+ slang_assembly_typeinfo_destruct(&ti);
+ return result;
}
-/*
- * _slang_assemble_assign()
- *
- * Performs unary (pre ++ and --) or binary (=, +=, -=, *=, /=) assignment on the operation's
- * children.
- */
-GLboolean _slang_assemble_assign (slang_assemble_ctx *A, slang_operation *op, const char *oper,
- slang_ref_type ref)
+/**
+ * Performs unary (pre ++ and --) or binary (=, +=, -=, *=, /=)
+ * assignment on the operation's children.
+ */
+GLboolean
+_slang_assemble_assign(slang_assemble_ctx * A, slang_operation * op,
+ const char *oper, slang_ref_type ref)
{
- slang_swizzle swz;
-
- if (ref == slang_ref_forbid)
- {
- if (!slang_assembly_file_push_label2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
- return GL_FALSE;
- }
-
- if (slang_string_compare ("=", oper) == 0)
- {
- if (!_slang_assemble_operation (A, &op->children[0], slang_ref_force))
- return GL_FALSE;
- swz = A->swz;
- if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
- return GL_FALSE;
- A->swz = swz;
- if (!_slang_assemble_assignment (A, op->children))
- return GL_FALSE;
- }
- else
- {
- if (!_slang_assemble_function_call_name (A, oper, op->children, op->num_children, GL_TRUE))
- return GL_FALSE;
- }
-
- if (ref == slang_ref_forbid)
- {
- if (!slang_assembly_file_push (A->file, slang_asm_addr_copy))
- return GL_FALSE;
- if (!slang_assembly_file_push_label (A->file, slang_asm_local_free, 4))
- return GL_FALSE;
- if (!_slang_dereference (A, op->children))
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
+ slang_swizzle swz;
+
+ if (ref == slang_ref_forbid) {
+ if (!slang_assembly_file_push_label2
+ (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
+ return GL_FALSE;
+ }
+
+ if (slang_string_compare("=", oper) == 0) {
+ if (!_slang_assemble_operation(A, &op->children[0], slang_ref_force))
+ return GL_FALSE;
+ swz = A->swz;
+ if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid))
+ return GL_FALSE;
+ A->swz = swz;
+ if (!_slang_assemble_assignment(A, op->children))
+ return GL_FALSE;
+ }
+ else {
+ if (!_slang_assemble_function_call_name
+ (A, oper, op->children, op->num_children, GL_TRUE))
+ return GL_FALSE;
+ }
+
+ if (ref == slang_ref_forbid) {
+ if (!slang_assembly_file_push(A->file, slang_asm_addr_copy))
+ return GL_FALSE;
+ if (!slang_assembly_file_push_label(A->file, slang_asm_local_free, 4))
+ return GL_FALSE;
+ if (!_slang_dereference(A, op->children))
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+}
diff --git a/src/mesa/shader/slang/slang_assemble_assignment.h b/src/mesa/shader/slang/slang_assemble_assignment.h
index 7b993b543b..3c1ecdedab 100644
--- a/src/mesa/shader/slang/slang_assemble_assignment.h
+++ b/src/mesa/shader/slang/slang_assemble_assignment.h
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.2
*
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
*
@@ -22,21 +22,24 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#if !defined SLANG_ASSEMBLE_ASSIGNMENT_H
+#ifndef SLANG_ASSEMBLE_ASSIGNMENT_H
#define SLANG_ASSEMBLE_ASSIGNMENT_H
#if defined __cplusplus
extern "C" {
#endif
-GLboolean _slang_assemble_assignment (slang_assemble_ctx *, struct slang_operation_ *);
-GLboolean _slang_assemble_assign (slang_assemble_ctx *, struct slang_operation_ *, const char *,
- slang_ref_type);
+extern GLboolean
+_slang_assemble_assignment(slang_assemble_ctx *, const struct slang_operation_ *);
+
+extern GLboolean
+_slang_assemble_assign(slang_assemble_ctx *, struct slang_operation_ *,
+ const char *, slang_ref_type);
+
#ifdef __cplusplus
}
#endif
-#endif
-
+#endif /* SLANG_ASSEMBLE_ASSIGNMENT_H */
diff --git a/src/mesa/shader/slang/slang_assemble_constructor.c b/src/mesa/shader/slang/slang_assemble_constructor.c
index 9d1aa70718..6cd320d446 100644
--- a/src/mesa/shader/slang/slang_assemble_constructor.c
+++ b/src/mesa/shader/slang/slang_assemble_constructor.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.2
*
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
*
@@ -32,348 +32,370 @@
#include "slang_assemble.h"
#include "slang_storage.h"
-/* _slang_is_swizzle() */
-GLboolean _slang_is_swizzle (const char *field, GLuint rows, slang_swizzle *swz)
+
+/**
+ * Checks if a field selector is a general swizzle (an r-value swizzle
+ * with replicated components or an l-value swizzle mask) for a
+ * vector. Returns GL_TRUE if this is the case, <swz> is filled with
+ * swizzle information. Returns GL_FALSE otherwise.
+ */
+GLboolean
+_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle * swz)
{
- GLuint i;
- GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE;
-
- /* the swizzle can be at most 4-component long */
- swz->num_components = slang_string_length (field);
- if (swz->num_components > 4)
- return GL_FALSE;
-
- for (i = 0; i < swz->num_components; i++)
- {
- /* mark which swizzle group is used */
- switch (field[i])
- {
- case 'x':
- case 'y':
- case 'z':
- case 'w':
- xyzw = GL_TRUE;
- break;
- case 'r':
- case 'g':
- case 'b':
- case 'a':
- rgba = GL_TRUE;
- break;
- case 's':
- case 't':
- case 'p':
- case 'q':
- stpq = GL_TRUE;
- break;
- default:
- return GL_FALSE;
- }
-
- /* collect swizzle component */
- switch (field[i])
- {
- case 'x':
- case 'r':
- case 's':
- swz->swizzle[i] = 0;
- break;
- case 'y':
- case 'g':
- case 't':
- swz->swizzle[i] = 1;
- break;
- case 'z':
- case 'b':
- case 'p':
- swz->swizzle[i] = 2;
- break;
- case 'w':
- case 'a':
- case 'q':
- swz->swizzle[i] = 3;
- break;
- }
-
- /* check if the component is valid for given vector's row count */
- if (rows <= swz->swizzle[i])
- return GL_FALSE;
- }
-
- /* only one swizzle group can be used */
- if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq))
- return GL_FALSE;
-
- return GL_TRUE;
+ GLuint i;
+ GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE;
+
+ /* the swizzle can be at most 4-component long */
+ swz->num_components = slang_string_length(field);
+ if (swz->num_components > 4)
+ return GL_FALSE;
+
+ for (i = 0; i < swz->num_components; i++) {
+ /* mark which swizzle group is used */
+ switch (field[i]) {
+ case 'x':
+ case 'y':
+ case 'z':
+ case 'w':
+ xyzw = GL_TRUE;
+ break;
+ case 'r':
+ case 'g':
+ case 'b':
+ case 'a':
+ rgba = GL_TRUE;
+ break;
+ case 's':
+ case 't':
+ case 'p':
+ case 'q':
+ stpq = GL_TRUE;
+ break;
+ default:
+ return GL_FALSE;
+ }
+
+ /* collect swizzle component */
+ switch (field[i]) {
+ case 'x':
+ case 'r':
+ case 's':
+ swz->swizzle[i] = 0;
+ break;
+ case 'y':
+ case 'g':
+ case 't':
+ swz->swizzle[i] = 1;
+ break;
+ case 'z':
+ case 'b':
+ case 'p':
+ swz->swizzle[i] = 2;
+ break;
+ case 'w':
+ case 'a':
+ case 'q':
+ swz->swizzle[i] = 3;
+ break;
+ }
+
+ /* check if the component is valid for given vector's row count */
+ if (rows <= swz->swizzle[i])
+ return GL_FALSE;
+ }
+
+ /* only one swizzle group can be used */
+ if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq))
+ return GL_FALSE;
+
+ return GL_TRUE;
}
-/* _slang_is_swizzle_mask() */
-GLboolean _slang_is_swizzle_mask (const slang_swizzle *swz, GLuint rows)
+
+/**
+ * Checks if a general swizzle is an l-value swizzle - these swizzles
+ * do not have duplicated fields. Returns GL_TRUE if this is a
+ * swizzle mask. Returns GL_FALSE otherwise
+ */
+GLboolean
+_slang_is_swizzle_mask(const slang_swizzle * swz, GLuint rows)
{
- GLuint i, c = 0;
+ GLuint i, c = 0;
- /* the swizzle may not be longer than the vector dim */
- if (swz->num_components > rows)
- return GL_FALSE;
+ /* the swizzle may not be longer than the vector dim */
+ if (swz->num_components > rows)
+ return GL_FALSE;
- /* the swizzle components cannot be duplicated */
- for (i = 0; i < swz->num_components; i++)
- {
- if ((c & (1 << swz->swizzle[i])) != 0)
- return GL_FALSE;
- c |= 1 << swz->swizzle[i];
- }
+ /* the swizzle components cannot be duplicated */
+ for (i = 0; i < swz->num_components; i++) {
+ if ((c & (1 << swz->swizzle[i])) != 0)
+ return GL_FALSE;
+ c |= 1 << swz->swizzle[i];
+ }
- return GL_TRUE;
+ return GL_TRUE;
}
-/* _slang_multiply_swizzles() */
-GLvoid _slang_multiply_swizzles (slang_swizzle *dst, const slang_swizzle *left,
- const slang_swizzle *right)
+
+/**
+ * Combines (multiplies) two swizzles to form single swizzle.
+ * Example: "vec.wzyx.yx" --> "vec.zw".
+ */
+GLvoid
+_slang_multiply_swizzles(slang_swizzle * dst, const slang_swizzle * left,
+ const slang_swizzle * right)
{
- GLuint i;
+ GLuint i;
- dst->num_components = right->num_components;
- for (i = 0; i < right->num_components; i++)
- dst->swizzle[i] = left->swizzle[right->swizzle[i]];
+ dst->num_components = right->num_components;
+ for (i = 0; i < right->num_components; i++)
+ dst->swizzle[i] = left->swizzle[right->swizzle[i]];
}
-/* _slang_assemble_constructor() */
+
static GLboolean
-sizeof_argument (slang_assemble_ctx *A, GLuint *size, slang_operation *op)
+sizeof_argument(slang_assemble_ctx * A, GLuint * size, slang_operation * op)
{
slang_assembly_typeinfo ti;
GLboolean result = GL_FALSE;
slang_storage_aggregate agg;
- if (!slang_assembly_typeinfo_construct (&ti))
+ if (!slang_assembly_typeinfo_construct(&ti))
return GL_FALSE;
- if (!_slang_typeof_operation (A, op, &ti))
+ if (!_slang_typeof_operation(A, op, &ti))
goto end1;
- if (!slang_storage_aggregate_construct (&agg))
+ if (!slang_storage_aggregate_construct(&agg))
goto end1;
- if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs,
- A->space.vars, A->mach, A->file, A->atoms))
+ if (!_slang_aggregate_variable(&agg, &ti.spec, 0, A->space.funcs,
+ A->space.structs, A->space.vars,
+ A->mach, A->file, A->atoms))
goto end;
- *size = _slang_sizeof_aggregate (&agg);
+ *size = _slang_sizeof_aggregate(&agg);
result = GL_TRUE;
-end:
- slang_storage_aggregate_destruct (&agg);
-end1:
- slang_assembly_typeinfo_destruct (&ti);
+ end:
+ slang_storage_aggregate_destruct(&agg);
+ end1:
+ slang_assembly_typeinfo_destruct(&ti);
return result;
}
-static GLboolean constructor_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *flat,
- slang_operation *op, GLuint garbage_size)
+
+static GLboolean
+constructor_aggregate(slang_assemble_ctx * A,
+ const slang_storage_aggregate * flat,
+ slang_operation * op, GLuint garbage_size)
{
- slang_assembly_typeinfo ti;
- GLboolean result = GL_FALSE;
- slang_storage_aggregate agg, flat_agg;
-
- if (!slang_assembly_typeinfo_construct (&ti))
- return GL_FALSE;
- if (!_slang_typeof_operation (A, op, &ti))
- goto end1;
-
- if (!slang_storage_aggregate_construct (&agg))
- goto end1;
- if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs,
- A->space.vars, A->mach, A->file, A->atoms))
- goto end2;
-
- if (!slang_storage_aggregate_construct (&flat_agg))
- goto end2;
- if (!_slang_flatten_aggregate (&flat_agg, &agg))
- goto end;
-
- if (!_slang_assemble_operation (A, op, slang_ref_forbid))
- goto end;
-
- /* TODO: convert (generic) elements */
-
- /* free the garbage */
- if (garbage_size != 0)
- {
- GLuint i;
-
- /* move the non-garbage part to the end of the argument */
- if (!slang_assembly_file_push_label (A->file, slang_asm_addr_push, 0))
- goto end;
- for (i = flat_agg.count * 4 - garbage_size; i > 0; i -= 4)
- {
- if (!slang_assembly_file_push_label2 (A->file, slang_asm_float_move,
- garbage_size + i, i))
- {
- goto end;
- }
- }
- if (!slang_assembly_file_push_label (A->file, slang_asm_local_free, garbage_size + 4))
- goto end;
- }
-
- result = GL_TRUE;
-end:
- slang_storage_aggregate_destruct (&flat_agg);
-end2:
- slang_storage_aggregate_destruct (&agg);
-end1:
- slang_assembly_typeinfo_destruct (&ti);
- return result;
+ slang_assembly_typeinfo ti;
+ GLboolean result = GL_FALSE;
+ slang_storage_aggregate agg, flat_agg;
+
+ if (!slang_assembly_typeinfo_construct(&ti))
+ return GL_FALSE;
+ if (!_slang_typeof_operation(A, op, &ti))
+ goto end1;
+
+ if (!slang_storage_aggregate_construct(&agg))
+ goto end1;
+ if (!_slang_aggregate_variable(&agg, &ti.spec, 0, A->space.funcs,
+ A->space.structs, A->space.vars,
+ A->mach, A->file, A->atoms))
+ goto end2;
+
+ if (!slang_storage_aggregate_construct(&flat_agg))
+ goto end2;
+ if (!_slang_flatten_aggregate(&flat_agg, &agg))
+ goto end;
+
+ if (!_slang_assemble_operation(A, op, slang_ref_forbid))
+ goto end;
+
+ /* TODO: convert (generic) elements */
+
+ /* free the garbage */
+ if (garbage_size != 0) {
+ GLuint i;
+
+ /* move the non-garbage part to the end of the argument */
+ if (!slang_assembly_file_push_label(A->file, slang_asm_addr_push, 0))
+ goto end;
+ for (i = flat_agg.count * 4 - garbage_size; i > 0; i -= 4) {
+ if (!slang_assembly_file_push_label2(A->file, slang_asm_float_move,
+ garbage_size + i, i)) {
+ goto end;
+ }
+ }
+ if (!slang_assembly_file_push_label
+ (A->file, slang_asm_local_free, garbage_size + 4))
+ goto end;
+ }
+
+ result = GL_TRUE;
+ end:
+ slang_storage_aggregate_destruct(&flat_agg);
+ end2:
+ slang_storage_aggregate_destruct(&agg);
+ end1:
+ slang_assembly_typeinfo_destruct(&ti);
+ return result;
}
-GLboolean _slang_assemble_constructor (slang_assemble_ctx *A, slang_operation *op)
+
+GLboolean
+_slang_assemble_constructor(slang_assemble_ctx * A, const slang_operation * op)
{
- slang_assembly_typeinfo ti;
- GLboolean result = GL_FALSE;
- slang_storage_aggregate agg, flat;
- GLuint size, i;
- GLuint arg_sums[2];
-
- /* get typeinfo of the constructor (the result of constructor expression) */
- if (!slang_assembly_typeinfo_construct (&ti))
- return GL_FALSE;
- if (!_slang_typeof_operation (A, op, &ti))
- goto end1;
-
- /* create an aggregate of the constructor */
- if (!slang_storage_aggregate_construct (&agg))
- goto end1;
- if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs,
- A->space.vars, A->mach, A->file, A->atoms))
- goto end2;
-
- /* calculate size of the constructor */
- size = _slang_sizeof_aggregate (&agg);
-
- /* flatten the constructor */
- if (!slang_storage_aggregate_construct (&flat))
- goto end2;
- if (!_slang_flatten_aggregate (&flat, &agg))
- goto end;
-
- /* collect the last two constructor's argument size sums */
- arg_sums[0] = 0; /* will hold all but the last argument's size sum */
- arg_sums[1] = 0; /* will hold all argument's size sum */
- for (i = 0; i < op->num_children; i++)
- {
- GLuint arg_size = 0;
-
- if (!sizeof_argument (A, &arg_size, &op->children[i]))
- goto end;
- if (i > 0)
- arg_sums[0] = arg_sums[1];
- arg_sums[1] += arg_size;
- }
-
- /* check if there are too many arguments */
- if (arg_sums[0] >= size)
- {
- /* TODO: info log: too many arguments in constructor list */
- goto end;
- }
-
- /* check if there are too few arguments */
- if (arg_sums[1] < size)
- {
- /* TODO: info log: too few arguments in constructor list */
- goto end;
- }
-
- /* traverse the children that form the constructor expression */
- for (i = op->num_children; i > 0; i--)
- {
- GLuint garbage_size;
-
- /* the last argument may be too big - calculate the unnecessary data size */
- if (i == op->num_children)
- garbage_size = arg_sums[1] - size;
- else
- garbage_size = 0;
-
- if (!constructor_aggregate (A, &flat, &op->children[i - 1], garbage_size))
- goto end;
- }
-
- result = GL_TRUE;
-end:
- slang_storage_aggregate_destruct (&flat);
-end2:
- slang_storage_aggregate_destruct (&agg);
-end1:
- slang_assembly_typeinfo_destruct (&ti);
- return result;
+ slang_assembly_typeinfo ti;
+ GLboolean result = GL_FALSE;
+ slang_storage_aggregate agg, flat;
+ GLuint size, i;
+ GLuint arg_sums[2];
+
+ /* get typeinfo of the constructor (the result of constructor expression) */
+ if (!slang_assembly_typeinfo_construct(&ti))
+ return GL_FALSE;
+ if (!_slang_typeof_operation(A, op, &ti))
+ goto end1;
+
+ /* create an aggregate of the constructor */
+ if (!slang_storage_aggregate_construct(&agg))
+ goto end1;
+ if (!_slang_aggregate_variable(&agg, &ti.spec, 0, A->space.funcs,
+ A->space.structs, A->space.vars,
+ A->mach, A->file, A->atoms))
+ goto end2;
+
+ /* calculate size of the constructor */
+ size = _slang_sizeof_aggregate(&agg);
+
+ /* flatten the constructor */
+ if (!slang_storage_aggregate_construct(&flat))
+ goto end2;
+ if (!_slang_flatten_aggregate(&flat, &agg))
+ goto end;
+
+ /* collect the last two constructor's argument size sums */
+ arg_sums[0] = 0; /* will hold all but the last argument's size sum */
+ arg_sums[1] = 0; /* will hold all argument's size sum */
+ for (i = 0; i < op->num_children; i++) {
+ GLuint arg_size = 0;
+
+ if (!sizeof_argument(A, &arg_size, &op->children[i]))
+ goto end;
+ if (i > 0)
+ arg_sums[0] = arg_sums[1];
+ arg_sums[1] += arg_size;
+ }
+
+ /* check if there are too many arguments */
+ if (arg_sums[0] >= size) {
+ /* TODO: info log: too many arguments in constructor list */
+ goto end;
+ }
+
+ /* check if there are too few arguments */
+ if (arg_sums[1] < size) {
+ /* TODO: info log: too few arguments in constructor list */
+ goto end;
+ }
+
+ /* traverse the children that form the constructor expression */
+ for (i = op->num_children; i > 0; i--) {
+ GLuint garbage_size;
+
+ /* the last argument may be too big - calculate the unnecessary
+ * data size
+ */
+ if (i == op->num_children)
+ garbage_size = arg_sums[1] - size;
+ else
+ garbage_size = 0;
+
+ if (!constructor_aggregate
+ (A, &flat, &op->children[i - 1], garbage_size))
+ goto end;
+ }
+
+ result = GL_TRUE;
+ end:
+ slang_storage_aggregate_destruct(&flat);
+ end2:
+ slang_storage_aggregate_destruct(&agg);
+ end1:
+ slang_assembly_typeinfo_destruct(&ti);
+ return result;
}
-/* _slang_assemble_constructor_from_swizzle() */
-GLboolean _slang_assemble_constructor_from_swizzle (slang_assemble_ctx *A, const slang_swizzle *swz,
- slang_type_specifier *spec, slang_type_specifier *master_spec)
+
+GLboolean
+_slang_assemble_constructor_from_swizzle(slang_assemble_ctx * A,
+ const slang_swizzle * swz,
+ const slang_type_specifier * spec,
+ const slang_type_specifier * master_spec)
{
- GLuint master_rows, i;
-
- master_rows = _slang_type_dim (master_spec->type);
- for (i = 0; i < master_rows; i++)
- {
- switch (_slang_type_base (master_spec->type))
- {
- case slang_spec_bool:
- if (!slang_assembly_file_push_label2 (A->file, slang_asm_bool_copy,
- (master_rows - i) * 4, i * 4))
- return GL_FALSE;
- break;
- case slang_spec_int:
- if (!slang_assembly_file_push_label2 (A->file, slang_asm_int_copy,
- (master_rows - i) * 4, i * 4))
- return GL_FALSE;
- break;
- case slang_spec_float:
- if (!slang_assembly_file_push_label2 (A->file, slang_asm_float_copy,
- (master_rows - i) * 4, i * 4))
- return GL_FALSE;
- break;
- default:
- break;
- }
- }
- if (!slang_assembly_file_push_label (A->file, slang_asm_local_free, 4))
- return GL_FALSE;
- for (i = swz->num_components; i > 0; i--)
- {
- GLuint n = i - 1;
-
- if (!slang_assembly_file_push_label2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
- return GL_FALSE;
- if (!slang_assembly_file_push_label (A->file, slang_asm_addr_push, swz->swizzle[n] * 4))
- return GL_FALSE;
- if (!slang_assembly_file_push (A->file, slang_asm_addr_add))
- return GL_FALSE;
- switch (_slang_type_base (master_spec->type))
- {
- case slang_spec_bool:
- if (!slang_assembly_file_push (A->file, slang_asm_bool_deref))
- return GL_FALSE;
- break;
- case slang_spec_int:
- if (!slang_assembly_file_push (A->file, slang_asm_int_deref))
- return GL_FALSE;
- break;
- case slang_spec_float:
- if (!slang_assembly_file_push (A->file, slang_asm_float_deref))
- return GL_FALSE;
- break;
- default:
- break;
- }
- }
-
- return GL_TRUE;
-}
+ const GLuint master_rows = _slang_type_dim(master_spec->type);
+ GLuint i;
+
+ for (i = 0; i < master_rows; i++) {
+ switch (_slang_type_base(master_spec->type)) {
+ case slang_spec_bool:
+ if (!slang_assembly_file_push_label2(A->file, slang_asm_bool_copy,
+ (master_rows - i) * 4, i * 4))
+ return GL_FALSE;
+ break;
+ case slang_spec_int:
+ if (!slang_assembly_file_push_label2(A->file, slang_asm_int_copy,
+ (master_rows - i) * 4, i * 4))
+ return GL_FALSE;
+ break;
+ case slang_spec_float:
+ if (!slang_assembly_file_push_label2(A->file, slang_asm_float_copy,
+ (master_rows - i) * 4, i * 4))
+ return GL_FALSE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!slang_assembly_file_push_label(A->file, slang_asm_local_free, 4))
+ return GL_FALSE;
+ for (i = swz->num_components; i > 0; i--) {
+ const GLuint n = i - 1;
+
+ if (!slang_assembly_file_push_label2(A->file, slang_asm_local_addr,
+ A->local.swizzle_tmp, 16))
+ return GL_FALSE;
+ if (!slang_assembly_file_push_label(A->file, slang_asm_addr_push,
+ swz->swizzle[n] * 4))
+ return GL_FALSE;
+ if (!slang_assembly_file_push(A->file, slang_asm_addr_add))
+ return GL_FALSE;
+
+ switch (_slang_type_base(master_spec->type)) {
+ case slang_spec_bool:
+ if (!slang_assembly_file_push(A->file, slang_asm_bool_deref))
+ return GL_FALSE;
+ break;
+ case slang_spec_int:
+ if (!slang_assembly_file_push(A->file, slang_asm_int_deref))
+ return GL_FALSE;
+ break;
+ case slang_spec_float:
+ if (!slang_assembly_file_push(A->file, slang_asm_float_deref))
+ return GL_FALSE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return GL_TRUE;
+}
diff --git a/src/mesa/shader/slang/slang_assemble_constructor.h b/src/mesa/shader/slang/slang_assemble_constructor.h
index 41a03943cf..c0deb91344 100644
--- a/src/mesa/shader/slang/slang_assemble_constructor.h
+++ b/src/mesa/shader/slang/slang_assemble_constructor.h
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.2
*
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
*
@@ -22,43 +22,36 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#if !defined SLANG_ASSEMBLE_CONSTRUCTOR_H
+#ifndef SLANG_ASSEMBLE_CONSTRUCTOR_H
#define SLANG_ASSEMBLE_CONSTRUCTOR_H
#if defined __cplusplus
extern "C" {
#endif
-/*
- * Checks if a field selector is a general swizzle (an r-value swizzle with replicated
- * components or an l-value swizzle mask) for a vector.
- * Returns GL_TRUE if this is the case, <swz> is filled with swizzle information.
- * Returns GL_FALSE otherwise.
- */
-GLboolean _slang_is_swizzle (const char *field, GLuint rows, slang_swizzle *swz);
-/*
- * Checks if a general swizzle is an l-value swizzle - these swizzles do not have
- * duplicated fields.
- * Returns GL_TRUE if this is a swizzle mask.
- * Returns GL_FALSE otherwise
- */
-GLboolean _slang_is_swizzle_mask (const slang_swizzle *swz, GLuint rows);
+extern GLboolean
+_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle *swz);
-/*
- * Combines (multiplies) two swizzles to form single swizzle.
- * Example: "vec.wzyx.yx" --> "vec.zw".
- */
-GLvoid _slang_multiply_swizzles (slang_swizzle *, const slang_swizzle *, const slang_swizzle *);
+extern GLboolean
+_slang_is_swizzle_mask(const slang_swizzle *swz, GLuint rows);
+
+extern GLvoid
+_slang_multiply_swizzles(slang_swizzle *, const slang_swizzle *,
+ const slang_swizzle *);
-GLboolean _slang_assemble_constructor (slang_assemble_ctx *, struct slang_operation_ *);
+extern GLboolean
+_slang_assemble_constructor(slang_assemble_ctx *,
+ const struct slang_operation_ *);
-GLboolean _slang_assemble_constructor_from_swizzle (slang_assemble_ctx *, const slang_swizzle *,
- slang_type_specifier *, slang_type_specifier *);
+extern GLboolean
+_slang_assemble_constructor_from_swizzle(slang_assemble_ctx *,
+ const slang_swizzle *,
+ const slang_type_specifier *,
+ const slang_type_specifier *);
#ifdef __cplusplus
}
#endif
-#endif
-
+#endif /* SLANG_ASSEMBLE_CONSTRUCTOR_H */
diff --git a/src/mesa/shader/slang/slang_assemble_typeinfo.c b/src/mesa/shader/slang/slang_assemble_typeinfo.c
index 58f4e24f25..265e417dad 100644
--- a/src/mesa/shader/slang/slang_assemble_typeinfo.c
+++ b/src/mesa/shader/slang/slang_assemble_typeinfo.c
@@ -36,552 +36,590 @@
* slang_type_specifier
*/
-GLvoid slang_type_specifier_ctr (slang_type_specifier *self)
+GLvoid
+slang_type_specifier_ctr(slang_type_specifier * self)
{
- self->type = slang_spec_void;
- self->_struct = NULL;
- self->_array = NULL;
+ self->type = slang_spec_void;
+ self->_struct = NULL;
+ self->_array = NULL;
}
-GLvoid slang_type_specifier_dtr (slang_type_specifier *self)
+GLvoid
+slang_type_specifier_dtr(slang_type_specifier * self)
{
- if (self->_struct != NULL)
- {
- slang_struct_destruct (self->_struct);
- slang_alloc_free (self->_struct);
- }
- if (self->_array != NULL)
- {
- slang_type_specifier_dtr (self->_array);
- slang_alloc_free (self->_array);
- }
+ if (self->_struct != NULL) {
+ slang_struct_destruct(self->_struct);
+ slang_alloc_free(self->_struct);
+ }
+ if (self->_array != NULL) {
+ slang_type_specifier_dtr(self->_array);
+ slang_alloc_free(self->_array);
+ }
}
-GLboolean slang_type_specifier_copy (slang_type_specifier *x, const slang_type_specifier *y)
+GLboolean
+slang_type_specifier_copy(slang_type_specifier * x,
+ const slang_type_specifier * y)
{
- slang_type_specifier z;
-
- slang_type_specifier_ctr (&z);
- z.type = y->type;
- if (z.type == slang_spec_struct)
- {
- z._struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
- if (z._struct == NULL)
- {
- slang_type_specifier_dtr (&z);
- return GL_FALSE;
- }
- if (!slang_struct_construct (z._struct))
- {
- slang_alloc_free (z._struct);
- slang_type_specifier_dtr (&z);
- return GL_FALSE;
- }
- if (!slang_struct_copy (z._struct, y->_struct))
- {
- slang_type_specifier_dtr (&z);
- return GL_FALSE;
- }
- }
- else if (z.type == slang_spec_array)
- {
- z._array = (slang_type_specifier *) slang_alloc_malloc (sizeof (slang_type_specifier));
- if (z._array == NULL)
- {
- slang_type_specifier_dtr (&z);
- return GL_FALSE;
- }
- slang_type_specifier_ctr (z._array);
- if (!slang_type_specifier_copy (z._array, y->_array))
- {
- slang_type_specifier_dtr (&z);
- return GL_FALSE;
- }
- }
- slang_type_specifier_dtr (x);
- *x = z;
- return GL_TRUE;
+ slang_type_specifier z;
+
+ slang_type_specifier_ctr(&z);
+ z.type = y->type;
+ if (z.type == slang_spec_struct) {
+ z._struct = (slang_struct *) slang_alloc_malloc(sizeof(slang_struct));
+ if (z._struct == NULL) {
+ slang_type_specifier_dtr(&z);
+ return GL_FALSE;
+ }
+ if (!slang_struct_construct(z._struct)) {
+ slang_alloc_free(z._struct);
+ slang_type_specifier_dtr(&z);
+ return GL_FALSE;
+ }
+ if (!slang_struct_copy(z._struct, y->_struct)) {
+ slang_type_specifier_dtr(&z);
+ return GL_FALSE;
+ }
+ }
+ else if (z.type == slang_spec_array) {
+ z._array =
+ (slang_type_specifier *)
+ slang_alloc_malloc(sizeof(slang_type_specifier));
+ if (z._array == NULL) {
+ slang_type_specifier_dtr(&z);
+ return GL_FALSE;
+ }
+ slang_type_specifier_ctr(z._array);
+ if (!slang_type_specifier_copy(z._array, y->_array)) {
+ slang_type_specifier_dtr(&z);
+ return GL_FALSE;
+ }
+ }
+ slang_type_specifier_dtr(x);
+ *x = z;
+ return GL_TRUE;
}
-GLboolean slang_type_specifier_equal (const slang_type_specifier *x, const slang_type_specifier *y)
+GLboolean
+slang_type_specifier_equal(const slang_type_specifier * x,
+ const slang_type_specifier * y)
{
- if (x->type != y->type)
- return 0;
- if (x->type == slang_spec_struct)
- return slang_struct_equal (x->_struct, y->_struct);
- if (x->type == slang_spec_array)
- return slang_type_specifier_equal (x->_array, y->_array);
- return 1;
+ if (x->type != y->type)
+ return 0;
+ if (x->type == slang_spec_struct)
+ return slang_struct_equal(x->_struct, y->_struct);
+ if (x->type == slang_spec_array)
+ return slang_type_specifier_equal(x->_array, y->_array);
+ return 1;
}
/* slang_assembly_typeinfo */
-GLboolean slang_assembly_typeinfo_construct (slang_assembly_typeinfo *ti)
+GLboolean
+slang_assembly_typeinfo_construct(slang_assembly_typeinfo * ti)
{
- slang_type_specifier_ctr (&ti->spec);
- ti->array_len = 0;
- return GL_TRUE;
+ slang_type_specifier_ctr(&ti->spec);
+ ti->array_len = 0;
+ return GL_TRUE;
}
-GLvoid slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *ti)
+GLvoid
+slang_assembly_typeinfo_destruct(slang_assembly_typeinfo * ti)
{
- slang_type_specifier_dtr (&ti->spec);
+ slang_type_specifier_dtr(&ti->spec);
}
/* _slang_typeof_operation() */
-static GLboolean typeof_existing_function (const char *name, slang_operation *params,
- GLuint num_params, slang_assembly_name_space *space, slang_type_specifier *spec,
- slang_atom_pool *atoms)
+/**
+ * Determine the return type of a function.
+ * \param name name of the function
+ * \param params array of function parameters
+ * \param num_params number of parameters
+ * \param space namespace to use
+ * \param spec returns the function's type
+ * \param atoms atom pool
+ * \return GL_TRUE for success, GL_FALSE if failure
+ */
+static GLboolean
+typeof_existing_function(const char *name, const slang_operation * params,
+ GLuint num_params,
+ const slang_assembly_name_space * space,
+ slang_type_specifier * spec,
+ slang_atom_pool * atoms)
{
- slang_atom atom;
- GLboolean exists;
-
- atom = slang_atom_pool_atom (atoms, name);
- if (!_slang_typeof_function (atom, params, num_params, space, spec, &exists, atoms))
- return GL_FALSE;
- return exists;
+ slang_atom atom;
+ GLboolean exists;
+
+ atom = slang_atom_pool_atom(atoms, name);
+ if (!_slang_typeof_function(atom, params, num_params, space, spec,
+ &exists, atoms))
+ return GL_FALSE;
+ return exists;
}
-GLboolean _slang_typeof_operation (slang_assemble_ctx *A, slang_operation *op,
- slang_assembly_typeinfo *ti)
+GLboolean
+_slang_typeof_operation(const slang_assemble_ctx * A,
+ const slang_operation * op,
+ slang_assembly_typeinfo * ti)
{
- return _slang_typeof_operation_ (op, &A->space, ti, A->atoms);
+ return _slang_typeof_operation_(op, &A->space, ti, A->atoms);
}
-GLboolean _slang_typeof_operation_ (slang_operation *op, slang_assembly_name_space *space,
- slang_assembly_typeinfo *ti, slang_atom_pool *atoms)
+
+/**
+ * Determine the return type of an operation.
+ * \param op the operation node
+ * \param space the namespace to use
+ * \param ti the returned type
+ * \param atoms atom pool
+ * \return GL_TRUE for success, GL_FALSE if failure
+ */
+GLboolean
+_slang_typeof_operation_(const slang_operation * op,
+ const slang_assembly_name_space * space,
+ slang_assembly_typeinfo * ti,
+ slang_atom_pool * atoms)
{
- ti->can_be_referenced = GL_FALSE;
- ti->is_swizzled = GL_FALSE;
-
- switch (op->type)
- {
- case slang_oper_block_no_new_scope:
- case slang_oper_block_new_scope:
- case slang_oper_variable_decl:
- case slang_oper_asm:
- case slang_oper_break:
- case slang_oper_continue:
- case slang_oper_discard:
- case slang_oper_return:
- case slang_oper_if:
- case slang_oper_while:
- case slang_oper_do:
- case slang_oper_for:
- case slang_oper_void:
- ti->spec.type = slang_spec_void;
- break;
- case slang_oper_expression:
- case slang_oper_assign:
- case slang_oper_addassign:
- case slang_oper_subassign:
- case slang_oper_mulassign:
- case slang_oper_divassign:
- case slang_oper_preincrement:
- case slang_oper_predecrement:
- if (!_slang_typeof_operation_ (op->children, space, ti, atoms))
- return 0;
- break;
- case slang_oper_literal_bool:
- case slang_oper_logicalor:
- case slang_oper_logicalxor:
- case slang_oper_logicaland:
- case slang_oper_equal:
- case slang_oper_notequal:
- case slang_oper_less:
- case slang_oper_greater:
- case slang_oper_lessequal:
- case slang_oper_greaterequal:
- case slang_oper_not:
- ti->spec.type = slang_spec_bool;
- break;
- case slang_oper_literal_int:
- ti->spec.type = slang_spec_int;
- break;
- case slang_oper_literal_float:
- ti->spec.type = slang_spec_float;
- break;
- case slang_oper_identifier:
- {
- slang_variable *var;
-
- var = _slang_locate_variable (op->locals, op->a_id, GL_TRUE);
- if (var == NULL)
- return GL_FALSE;
- if (!slang_type_specifier_copy (&ti->spec, &var->type.specifier))
- return GL_FALSE;
- ti->can_be_referenced = GL_TRUE;
- ti->array_len = var->array_len;
- }
- break;
- case slang_oper_sequence:
- /* TODO: check [0] and [1] if they match */
- if (!_slang_typeof_operation_ (&op->children[1], space, ti, atoms))
- return GL_FALSE;
- ti->can_be_referenced = GL_FALSE;
- ti->is_swizzled = GL_FALSE;
- break;
- /*case slang_oper_modassign:*/
- /*case slang_oper_lshassign:*/
- /*case slang_oper_rshassign:*/
- /*case slang_oper_orassign:*/
- /*case slang_oper_xorassign:*/
- /*case slang_oper_andassign:*/
- case slang_oper_select:
- /* TODO: check [1] and [2] if they match */
- if (!_slang_typeof_operation_ (&op->children[1], space, ti, atoms))
- return GL_FALSE;
- ti->can_be_referenced = GL_FALSE;
- ti->is_swizzled = GL_FALSE;
- break;
- /*case slang_oper_bitor:*/
- /*case slang_oper_bitxor:*/
- /*case slang_oper_bitand:*/
- /*case slang_oper_lshift:*/
- /*case slang_oper_rshift:*/
- case slang_oper_add:
- if (!typeof_existing_function ("+", op->children, 2, space, &ti->spec, atoms))
- return GL_FALSE;
- break;
- case slang_oper_subtract:
- if (!typeof_existing_function ("-", op->children, 2, space, &ti->spec, atoms))
- return GL_FALSE;
- break;
- case slang_oper_multiply:
- if (!typeof_existing_function ("*", op->children, 2, space, &ti->spec, atoms))
- return GL_FALSE;
- break;
- case slang_oper_divide:
- if (!typeof_existing_function ("/", op->children, 2, space, &ti->spec, atoms))
- return GL_FALSE;
- break;
- /*case slang_oper_modulus:*/
- case slang_oper_plus:
- if (!_slang_typeof_operation_ (op->children, space, ti, atoms))
- return GL_FALSE;
- ti->can_be_referenced = GL_FALSE;
- ti->is_swizzled = GL_FALSE;
- break;
- case slang_oper_minus:
- if (!typeof_existing_function ("-", op->children, 1, space, &ti->spec, atoms))
- return GL_FALSE;
- break;
- /*case slang_oper_complement:*/
- case slang_oper_subscript:
- {
- slang_assembly_typeinfo _ti;
-
- if (!slang_assembly_typeinfo_construct (&_ti))
- return GL_FALSE;
- if (!_slang_typeof_operation_ (op->children, space, &_ti, atoms))
- {
- slang_assembly_typeinfo_destruct (&_ti);
- return GL_FALSE;
- }
- ti->can_be_referenced = _ti.can_be_referenced;
- if (_ti.spec.type == slang_spec_array)
- {
- if (!slang_type_specifier_copy (&ti->spec, _ti.spec._array))
- {
- slang_assembly_typeinfo_destruct (&_ti);
- return GL_FALSE;
- }
- }
- else
- {
- if (!_slang_type_is_vector (_ti.spec.type) && !_slang_type_is_matrix (_ti.spec.type))
- {
- slang_assembly_typeinfo_destruct (&_ti);
- return GL_FALSE;
- }
- ti->spec.type = _slang_type_base (_ti.spec.type);
- }
- slang_assembly_typeinfo_destruct (&_ti);
- }
- break;
- case slang_oper_call:
- {
- GLboolean exists;
-
- if (!_slang_typeof_function (op->a_id, op->children, op->num_children, space, &ti->spec,
- &exists, atoms))
- return GL_FALSE;
- if (!exists)
- {
- slang_struct *s = slang_struct_scope_find (space->structs, op->a_id, GL_TRUE);
- if (s != NULL)
- {
- ti->spec.type = slang_spec_struct;
- ti->spec._struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
- if (ti->spec._struct == NULL)
- return GL_FALSE;
- if (!slang_struct_construct (ti->spec._struct))
- {
- slang_alloc_free (ti->spec._struct);
- ti->spec._struct = NULL;
- return GL_FALSE;
- }
- if (!slang_struct_copy (ti->spec._struct, s))
- return GL_FALSE;
- }
- else
- {
- const char *name;
- slang_type_specifier_type type;
-
- name = slang_atom_pool_id (atoms, op->a_id);
- type = slang_type_specifier_type_from_string (name);
- if (type == slang_spec_void)
- return GL_FALSE;
- ti->spec.type = type;
- }
- }
- }
- break;
- case slang_oper_field:
- {
- slang_assembly_typeinfo _ti;
-
- if (!slang_assembly_typeinfo_construct (&_ti))
- return GL_FALSE;
- if (!_slang_typeof_operation_ (op->children, space, &_ti, atoms))
- {
- slang_assembly_typeinfo_destruct (&_ti);
- return GL_FALSE;
- }
- if (_ti.spec.type == slang_spec_struct)
- {
- slang_variable *field;
-
- field = _slang_locate_variable (_ti.spec._struct->fields, op->a_id, GL_FALSE);
- if (field == NULL)
- {
- slang_assembly_typeinfo_destruct (&_ti);
- return GL_FALSE;
- }
- if (!slang_type_specifier_copy (&ti->spec, &field->type.specifier))
- {
- slang_assembly_typeinfo_destruct (&_ti);
- return GL_FALSE;
- }
- ti->can_be_referenced = _ti.can_be_referenced;
- }
- else
- {
- GLuint rows;
- const char *swizzle;
- slang_type_specifier_type base;
-
- /* determine the swizzle of the field expression */
- if (!_slang_type_is_vector (_ti.spec.type))
- {
- slang_assembly_typeinfo_destruct (&_ti);
- return GL_FALSE;
- }
- rows = _slang_type_dim (_ti.spec.type);
- swizzle = slang_atom_pool_id (atoms, op->a_id);
- if (!_slang_is_swizzle (swizzle, rows, &ti->swz))
- {
- slang_assembly_typeinfo_destruct (&_ti);
- return GL_FALSE;
- }
- ti->is_swizzled = GL_TRUE;
- ti->can_be_referenced = _ti.can_be_referenced && _slang_is_swizzle_mask (&ti->swz,
- rows);
- if (_ti.is_swizzled)
- {
- slang_swizzle swz;
-
- /* swizzle the swizzle */
- _slang_multiply_swizzles (&swz, &_ti.swz, &ti->swz);
- ti->swz = swz;
- }
- base = _slang_type_base (_ti.spec.type);
- switch (ti->swz.num_components)
- {
- case 1:
- ti->spec.type = base;
- break;
- case 2:
- switch (base)
- {
- case slang_spec_float:
- ti->spec.type = slang_spec_vec2;
- break;
- case slang_spec_int:
- ti->spec.type = slang_spec_ivec2;
- break;
- case slang_spec_bool:
- ti->spec.type = slang_spec_bvec2;
- break;
- default:
- break;
- }
- break;
- case 3:
- switch (base)
- {
- case slang_spec_float:
- ti->spec.type = slang_spec_vec3;
- break;
- case slang_spec_int:
- ti->spec.type = slang_spec_ivec3;
- break;
- case slang_spec_bool:
- ti->spec.type = slang_spec_bvec3;
- break;
- default:
- break;
- }
- break;
- case 4:
- switch (base)
- {
- case slang_spec_float:
- ti->spec.type = slang_spec_vec4;
- break;
- case slang_spec_int:
- ti->spec.type = slang_spec_ivec4;
- break;
- case slang_spec_bool:
- ti->spec.type = slang_spec_bvec4;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
- slang_assembly_typeinfo_destruct (&_ti);
- }
- break;
- case slang_oper_postincrement:
- case slang_oper_postdecrement:
- if (!_slang_typeof_operation_ (op->children, space, ti, atoms))
- return GL_FALSE;
- ti->can_be_referenced = GL_FALSE;
- ti->is_swizzled = GL_FALSE;
- break;
- default:
- return GL_FALSE;
- }
-
- return GL_TRUE;
+ ti->can_be_referenced = GL_FALSE;
+ ti->is_swizzled = GL_FALSE;
+
+ switch (op->type) {
+ case slang_oper_block_no_new_scope:
+ case slang_oper_block_new_scope:
+ case slang_oper_variable_decl:
+ case slang_oper_asm:
+ case slang_oper_break:
+ case slang_oper_continue:
+ case slang_oper_discard:
+ case slang_oper_return:
+ case slang_oper_if:
+ case slang_oper_while:
+ case slang_oper_do:
+ case slang_oper_for:
+ case slang_oper_void:
+ ti->spec.type = slang_spec_void;
+ break;
+ case slang_oper_expression:
+ case slang_oper_assign:
+ case slang_oper_addassign:
+ case slang_oper_subassign:
+ case slang_oper_mulassign:
+ case slang_oper_divassign:
+ case slang_oper_preincrement:
+ case slang_oper_predecrement:
+ if (!_slang_typeof_operation_(op->children, space, ti, atoms))
+ return 0;
+ break;
+ case slang_oper_literal_bool:
+ case slang_oper_logicalor:
+ case slang_oper_logicalxor:
+ case slang_oper_logicaland:
+ case slang_oper_equal:
+ case slang_oper_notequal:
+ case slang_oper_less:
+ case slang_oper_greater:
+ case slang_oper_lessequal:
+ case slang_oper_greaterequal:
+ case slang_oper_not:
+ ti->spec.type = slang_spec_bool;
+ break;
+ case slang_oper_literal_int:
+ ti->spec.type = slang_spec_int;
+ break;
+ case slang_oper_literal_float:
+ ti->spec.type = slang_spec_float;
+ break;
+ case slang_oper_identifier:
+ {
+ slang_variable *var;
+
+ var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE);
+ if (var == NULL)
+ return GL_FALSE;
+ if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier))
+ return GL_FALSE;
+ ti->can_be_referenced = GL_TRUE;
+ ti->array_len = var->array_len;
+ }
+ break;
+ case slang_oper_sequence:
+ /* TODO: check [0] and [1] if they match */
+ if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms))
+ return GL_FALSE;
+ ti->can_be_referenced = GL_FALSE;
+ ti->is_swizzled = GL_FALSE;
+ break;
+ /*case slang_oper_modassign: */
+ /*case slang_oper_lshassign: */
+ /*case slang_oper_rshassign: */
+ /*case slang_oper_orassign: */
+ /*case slang_oper_xorassign: */
+ /*case slang_oper_andassign: */
+ case slang_oper_select:
+ /* TODO: check [1] and [2] if they match */
+ if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms))
+ return GL_FALSE;
+ ti->can_be_referenced = GL_FALSE;
+ ti->is_swizzled = GL_FALSE;
+ break;
+ /*case slang_oper_bitor: */
+ /*case slang_oper_bitxor: */
+ /*case slang_oper_bitand: */
+ /*case slang_oper_lshift: */
+ /*case slang_oper_rshift: */
+ case slang_oper_add:
+ if (!typeof_existing_function("+", op->children, 2, space,
+ &ti->spec, atoms))
+ return GL_FALSE;
+ break;
+ case slang_oper_subtract:
+ if (!typeof_existing_function("-", op->children, 2, space,
+ &ti->spec, atoms))
+ return GL_FALSE;
+ break;
+ case slang_oper_multiply:
+ if (!typeof_existing_function("*", op->children, 2, space,
+ &ti->spec, atoms))
+ return GL_FALSE;
+ break;
+ case slang_oper_divide:
+ if (!typeof_existing_function("/", op->children, 2, space,
+ &ti->spec, atoms))
+ return GL_FALSE;
+ break;
+ /*case slang_oper_modulus: */
+ case slang_oper_plus:
+ if (!_slang_typeof_operation_(op->children, space, ti, atoms))
+ return GL_FALSE;
+ ti->can_be_referenced = GL_FALSE;
+ ti->is_swizzled = GL_FALSE;
+ break;
+ case slang_oper_minus:
+ if (!typeof_existing_function
+ ("-", op->children, 1, space, &ti->spec, atoms))
+ return GL_FALSE;
+ break;
+ /*case slang_oper_complement: */
+ case slang_oper_subscript:
+ {
+ slang_assembly_typeinfo _ti;
+
+ if (!slang_assembly_typeinfo_construct(&_ti))
+ return GL_FALSE;
+ if (!_slang_typeof_operation_(op->children, space, &_ti, atoms)) {
+ slang_assembly_typeinfo_destruct(&_ti);
+ return GL_FALSE;
+ }
+ ti->can_be_referenced = _ti.can_be_referenced;
+ if (_ti.spec.type == slang_spec_array) {
+ if (!slang_type_specifier_copy(&ti->spec, _ti.spec._array)) {
+ slang_assembly_typeinfo_destruct(&_ti);
+ return GL_FALSE;
+ }
+ }
+ else {
+ if (!_slang_type_is_vector(_ti.spec.type)
+ && !_slang_type_is_matrix(_ti.spec.type)) {
+ slang_assembly_typeinfo_destruct(&_ti);
+ return GL_FALSE;
+ }
+ ti->spec.type = _slang_type_base(_ti.spec.type);
+ }
+ slang_assembly_typeinfo_destruct(&_ti);
+ }
+ break;
+ case slang_oper_call:
+ {
+ GLboolean exists;
+
+ if (!_slang_typeof_function(op->a_id, op->children, op->num_children,
+ space, &ti->spec, &exists, atoms))
+ return GL_FALSE;
+ if (!exists) {
+ slang_struct *s =
+ slang_struct_scope_find(space->structs, op->a_id, GL_TRUE);
+ if (s != NULL) {
+ ti->spec.type = slang_spec_struct;
+ ti->spec._struct =
+ (slang_struct *) slang_alloc_malloc(sizeof(slang_struct));
+ if (ti->spec._struct == NULL)
+ return GL_FALSE;
+ if (!slang_struct_construct(ti->spec._struct)) {
+ slang_alloc_free(ti->spec._struct);
+ ti->spec._struct = NULL;
+ return GL_FALSE;
+ }
+ if (!slang_struct_copy(ti->spec._struct, s))
+ return GL_FALSE;
+ }
+ else {
+ const char *name;
+ slang_type_specifier_type type;
+
+ name = slang_atom_pool_id(atoms, op->a_id);
+ type = slang_type_specifier_type_from_string(name);
+ if (type == slang_spec_void)
+ return GL_FALSE;
+ ti->spec.type = type;
+ }
+ }
+ }
+ break;
+ case slang_oper_field:
+ {
+ slang_assembly_typeinfo _ti;
+
+ if (!slang_assembly_typeinfo_construct(&_ti))
+ return GL_FALSE;
+ if (!_slang_typeof_operation_(op->children, space, &_ti, atoms)) {
+ slang_assembly_typeinfo_destruct(&_ti);
+ return GL_FALSE;
+ }
+ if (_ti.spec.type == slang_spec_struct) {
+ slang_variable *field;
+
+ field =
+ _slang_locate_variable(_ti.spec._struct->fields, op->a_id,
+ GL_FALSE);
+ if (field == NULL) {
+ slang_assembly_typeinfo_destruct(&_ti);
+ return GL_FALSE;
+ }
+ if (!slang_type_specifier_copy(&ti->spec, &field->type.specifier)) {
+ slang_assembly_typeinfo_destruct(&_ti);
+ return GL_FALSE;
+ }
+ ti->can_be_referenced = _ti.can_be_referenced;
+ }
+ else {
+ GLuint rows;
+ const char *swizzle;
+ slang_type_specifier_type base;
+
+ /* determine the swizzle of the field expression */
+ if (!_slang_type_is_vector(_ti.spec.type)) {
+ slang_assembly_typeinfo_destruct(&_ti);
+ return GL_FALSE;
+ }
+ rows = _slang_type_dim(_ti.spec.type);
+ swizzle = slang_atom_pool_id(atoms, op->a_id);
+ if (!_slang_is_swizzle(swizzle, rows, &ti->swz)) {
+ slang_assembly_typeinfo_destruct(&_ti);
+ return GL_FALSE;
+ }
+ ti->is_swizzled = GL_TRUE;
+ ti->can_be_referenced = _ti.can_be_referenced
+ && _slang_is_swizzle_mask(&ti->swz, rows);
+ if (_ti.is_swizzled) {
+ slang_swizzle swz;
+
+ /* swizzle the swizzle */
+ _slang_multiply_swizzles(&swz, &_ti.swz, &ti->swz);
+ ti->swz = swz;
+ }
+ base = _slang_type_base(_ti.spec.type);
+ switch (ti->swz.num_components) {
+ case 1:
+ ti->spec.type = base;
+ break;
+ case 2:
+ switch (base) {
+ case slang_spec_float:
+ ti->spec.type = slang_spec_vec2;
+ break;
+ case slang_spec_int:
+ ti->spec.type = slang_spec_ivec2;
+ break;
+ case slang_spec_bool:
+ ti->spec.type = slang_spec_bvec2;
+ break;
+ default:
+ break;
+ }
+ break;
+ case 3:
+ switch (base) {
+ case slang_spec_float:
+ ti->spec.type = slang_spec_vec3;
+ break;
+ case slang_spec_int:
+ ti->spec.type = slang_spec_ivec3;
+ break;
+ case slang_spec_bool:
+ ti->spec.type = slang_spec_bvec3;
+ break;
+ default:
+ break;
+ }
+ break;
+ case 4:
+ switch (base) {
+ case slang_spec_float:
+ ti->spec.type = slang_spec_vec4;
+ break;
+ case slang_spec_int:
+ ti->spec.type = slang_spec_ivec4;
+ break;
+ case slang_spec_bool:
+ ti->spec.type = slang_spec_bvec4;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ slang_assembly_typeinfo_destruct(&_ti);
+ }
+ break;
+ case slang_oper_postincrement:
+ case slang_oper_postdecrement:
+ if (!_slang_typeof_operation_(op->children, space, ti, atoms))
+ return GL_FALSE;
+ ti->can_be_referenced = GL_FALSE;
+ ti->is_swizzled = GL_FALSE;
+ break;
+ default:
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
}
-/* _slang_typeof_function() */
-GLboolean _slang_typeof_function (slang_atom a_name, slang_operation *params, GLuint num_params,
- slang_assembly_name_space *space, slang_type_specifier *spec, GLboolean *exists,
- slang_atom_pool *atoms)
+
+/**
+ * Determine the return type of a function.
+ * \param a_name the function name
+ * \param param function parameters (overloading)
+ * \param num_params number of parameters to function
+ * \param space namespace to search
+ * \param exists returns GL_TRUE or GL_FALSE to indicate existance of function
+ * \return GL_TRUE for success, GL_FALSE if failure (bad function name)
+ */
+GLboolean
+_slang_typeof_function(slang_atom a_name, const slang_operation * params,
+ GLuint num_params,
+ const slang_assembly_name_space * space,
+ slang_type_specifier * spec, GLboolean * exists,
+ slang_atom_pool * atoms)
{
- slang_function *fun;
-
- fun = _slang_locate_function (space->funcs, a_name, params, num_params, space, atoms);
- *exists = fun != NULL;
- if (fun == NULL)
- return GL_TRUE;
- return slang_type_specifier_copy (spec, &fun->header.type.specifier);
+ slang_function *fun = _slang_locate_function(space->funcs, a_name, params,
+ num_params, space, atoms);
+ *exists = fun != NULL;
+ if (!fun)
+ return GL_TRUE; /* yes, not false */
+ return slang_type_specifier_copy(spec, &fun->header.type.specifier);
}
-/* _slang_type_is_matrix() */
-GLboolean _slang_type_is_matrix (slang_type_specifier_type ty)
+
+/**
+ * Determine if a type is a matrix.
+ * \return GL_TRUE if is a matrix, GL_FALSE otherwise.
+ */
+GLboolean
+_slang_type_is_matrix(slang_type_specifier_type ty)
{
- switch (ty)
- {
- case slang_spec_mat2:
- case slang_spec_mat3:
- case slang_spec_mat4:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
+ switch (ty) {
+ case slang_spec_mat2:
+ case slang_spec_mat3:
+ case slang_spec_mat4:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
}
-/* _slang_type_is_vector() */
-GLboolean _slang_type_is_vector (slang_type_specifier_type ty)
+/**
+ * Determine if a type is a vector.
+ * \return GL_TRUE if is a vector, GL_FALSE otherwise.
+ */
+GLboolean
+_slang_type_is_vector(slang_type_specifier_type ty)
{
- switch (ty)
- {
- case slang_spec_vec2:
- case slang_spec_vec3:
- case slang_spec_vec4:
- case slang_spec_ivec2:
- case slang_spec_ivec3:
- case slang_spec_ivec4:
- case slang_spec_bvec2:
- case slang_spec_bvec3:
- case slang_spec_bvec4:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
+ switch (ty) {
+ case slang_spec_vec2:
+ case slang_spec_vec3:
+ case slang_spec_vec4:
+ case slang_spec_ivec2:
+ case slang_spec_ivec3:
+ case slang_spec_ivec4:
+ case slang_spec_bvec2:
+ case slang_spec_bvec3:
+ case slang_spec_bvec4:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
}
-/* _slang_type_base_of_vector() */
-slang_type_specifier_type _slang_type_base (slang_type_specifier_type ty)
+/**
+ * Given a vector type, return the type of the vector's elements
+ */
+slang_type_specifier_type
+_slang_type_base(slang_type_specifier_type ty)
{
- switch (ty)
- {
- case slang_spec_float:
- case slang_spec_vec2:
- case slang_spec_vec3:
- case slang_spec_vec4:
- return slang_spec_float;
- case slang_spec_int:
- case slang_spec_ivec2:
- case slang_spec_ivec3:
- case slang_spec_ivec4:
- return slang_spec_int;
- case slang_spec_bool:
- case slang_spec_bvec2:
- case slang_spec_bvec3:
- case slang_spec_bvec4:
- return slang_spec_bool;
- case slang_spec_mat2:
- return slang_spec_vec2;
- case slang_spec_mat3:
- return slang_spec_vec3;
- case slang_spec_mat4:
- return slang_spec_vec4;
- default:
- return slang_spec_void;
- }
+ switch (ty) {
+ case slang_spec_float:
+ case slang_spec_vec2:
+ case slang_spec_vec3:
+ case slang_spec_vec4:
+ return slang_spec_float;
+ case slang_spec_int:
+ case slang_spec_ivec2:
+ case slang_spec_ivec3:
+ case slang_spec_ivec4:
+ return slang_spec_int;
+ case slang_spec_bool:
+ case slang_spec_bvec2:
+ case slang_spec_bvec3:
+ case slang_spec_bvec4:
+ return slang_spec_bool;
+ case slang_spec_mat2:
+ return slang_spec_vec2;
+ case slang_spec_mat3:
+ return slang_spec_vec3;
+ case slang_spec_mat4:
+ return slang_spec_vec4;
+ default:
+ return slang_spec_void;
+ }
}
-/* _slang_type_dim */
-GLuint _slang_type_dim (slang_type_specifier_type ty)
+/**
+ * Return the dimensionality of a vector or matrix type.
+ */
+GLuint
+_slang_type_dim(slang_type_specifier_type ty)
{
- switch (ty)
- {
- case slang_spec_float:
- case slang_spec_int:
- case slang_spec_bool:
- return 1;
- case slang_spec_vec2:
- case slang_spec_ivec2:
- case slang_spec_bvec2:
- case slang_spec_mat2:
- return 2;
- case slang_spec_vec3:
- case slang_spec_ivec3:
- case slang_spec_bvec3:
- case slang_spec_mat3:
- return 3;
- case slang_spec_vec4:
- case slang_spec_ivec4:
- case slang_spec_bvec4:
- case slang_spec_mat4:
- return 4;
- default:
- return 0;
- }
+ switch (ty) {
+ case slang_spec_float:
+ case slang_spec_int:
+ case slang_spec_bool:
+ return 1;
+ case slang_spec_vec2:
+ case slang_spec_ivec2:
+ case slang_spec_bvec2:
+ case slang_spec_mat2:
+ return 2;
+ case slang_spec_vec3:
+ case slang_spec_ivec3:
+ case slang_spec_bvec3:
+ case slang_spec_mat3:
+ return 3;
+ case slang_spec_vec4:
+ case slang_spec_ivec4:
+ case slang_spec_bvec4:
+ case slang_spec_mat4:
+ return 4;
+ default:
+ return 0;
+ }
}
-
diff --git a/src/mesa/shader/slang/slang_assemble_typeinfo.h b/src/mesa/shader/slang/slang_assemble_typeinfo.h
index 7e8af96915..777dc21f3a 100644
--- a/src/mesa/shader/slang/slang_assemble_typeinfo.h
+++ b/src/mesa/shader/slang/slang_assemble_typeinfo.h
@@ -29,84 +29,120 @@
extern "C" {
#endif
+
+/**
+ * The basic shading language types (float, vec4, mat3, etc)
+ */
typedef enum slang_type_specifier_type_
{
- slang_spec_void,
- slang_spec_bool,
- slang_spec_bvec2,
- slang_spec_bvec3,
- slang_spec_bvec4,
- slang_spec_int,
- slang_spec_ivec2,
- slang_spec_ivec3,
- slang_spec_ivec4,
- slang_spec_float,
- slang_spec_vec2,
- slang_spec_vec3,
- slang_spec_vec4,
- slang_spec_mat2,
- slang_spec_mat3,
- slang_spec_mat4,
- slang_spec_sampler1D,
- slang_spec_sampler2D,
- slang_spec_sampler3D,
- slang_spec_samplerCube,
- slang_spec_sampler1DShadow,
- slang_spec_sampler2DShadow,
- slang_spec_struct,
- slang_spec_array
+ slang_spec_void,
+ slang_spec_bool,
+ slang_spec_bvec2,
+ slang_spec_bvec3,
+ slang_spec_bvec4,
+ slang_spec_int,
+ slang_spec_ivec2,
+ slang_spec_ivec3,
+ slang_spec_ivec4,
+ slang_spec_float,
+ slang_spec_vec2,
+ slang_spec_vec3,
+ slang_spec_vec4,
+ slang_spec_mat2,
+ slang_spec_mat3,
+ slang_spec_mat4,
+ slang_spec_sampler1D,
+ slang_spec_sampler2D,
+ slang_spec_sampler3D,
+ slang_spec_samplerCube,
+ slang_spec_sampler1DShadow,
+ slang_spec_sampler2DShadow,
+ slang_spec_struct,
+ slang_spec_array
} slang_type_specifier_type;
+
+/**
+ * Describes more sophisticated types, like structs and arrays.
+ */
typedef struct slang_type_specifier_
{
- slang_type_specifier_type type;
- struct slang_struct_ *_struct; /* type: spec_struct */
- struct slang_type_specifier_ *_array; /* type: spec_array */
+ slang_type_specifier_type type;
+ struct slang_struct_ *_struct; /**< used if type == spec_struct */
+ struct slang_type_specifier_ *_array; /**< used if type == spec_array */
} slang_type_specifier;
-GLvoid slang_type_specifier_ctr (slang_type_specifier *);
-GLvoid slang_type_specifier_dtr (slang_type_specifier *);
-GLboolean slang_type_specifier_copy (slang_type_specifier *, const slang_type_specifier *);
-GLboolean slang_type_specifier_equal (const slang_type_specifier *, const slang_type_specifier *);
+
+extern GLvoid
+slang_type_specifier_ctr(slang_type_specifier *);
+
+extern GLvoid
+slang_type_specifier_dtr(slang_type_specifier *);
+
+extern GLboolean
+slang_type_specifier_copy(slang_type_specifier *, const slang_type_specifier *);
+
+extern GLboolean
+slang_type_specifier_equal(const slang_type_specifier *,
+ const slang_type_specifier *);
+
typedef struct slang_assembly_typeinfo_
{
- GLboolean can_be_referenced;
- GLboolean is_swizzled;
- slang_swizzle swz;
- slang_type_specifier spec;
- GLuint array_len;
+ GLboolean can_be_referenced;
+ GLboolean is_swizzled;
+ slang_swizzle swz;
+ slang_type_specifier spec;
+ GLuint array_len;
} slang_assembly_typeinfo;
-GLboolean slang_assembly_typeinfo_construct (slang_assembly_typeinfo *);
-GLvoid slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *);
+extern GLboolean
+slang_assembly_typeinfo_construct(slang_assembly_typeinfo *);
-/*
+extern GLvoid
+slang_assembly_typeinfo_destruct(slang_assembly_typeinfo *);
+
+
+/**
* Retrieves type information about an operation.
* Returns GL_TRUE on success.
* Returns GL_FALSE otherwise.
*/
-GLboolean _slang_typeof_operation (slang_assemble_ctx *, struct slang_operation_ *,
- slang_assembly_typeinfo *);
-GLboolean _slang_typeof_operation_ (struct slang_operation_ *, slang_assembly_name_space *,
- slang_assembly_typeinfo *, slang_atom_pool *);
+extern GLboolean
+_slang_typeof_operation(const slang_assemble_ctx *,
+ const struct slang_operation_ *,
+ slang_assembly_typeinfo *);
-/*
+extern GLboolean
+_slang_typeof_operation_(const struct slang_operation_ *,
+ const slang_assembly_name_space *,
+ slang_assembly_typeinfo *, slang_atom_pool *);
+
+/**
* Retrieves type of a function prototype, if one exists.
* Returns GL_TRUE on success, even if the function was not found.
* Returns GL_FALSE otherwise.
*/
-GLboolean _slang_typeof_function (slang_atom a_name, struct slang_operation_ *params,
- GLuint num_params, slang_assembly_name_space *, slang_type_specifier *spec, GLboolean *exists,
- slang_atom_pool *);
+extern GLboolean
+_slang_typeof_function(slang_atom a_name,
+ const struct slang_operation_ *params,
+ GLuint num_params, const slang_assembly_name_space *,
+ slang_type_specifier *spec, GLboolean *exists,
+ slang_atom_pool *);
+
+extern GLboolean
+_slang_type_is_matrix(slang_type_specifier_type);
+
+extern GLboolean
+_slang_type_is_vector(slang_type_specifier_type);
-GLboolean _slang_type_is_matrix (slang_type_specifier_type);
+extern slang_type_specifier_type
+_slang_type_base(slang_type_specifier_type);
-GLboolean _slang_type_is_vector (slang_type_specifier_type);
+extern GLuint
+_slang_type_dim(slang_type_specifier_type);
-slang_type_specifier_type _slang_type_base (slang_type_specifier_type);
-GLuint _slang_type_dim (slang_type_specifier_type);
#ifdef __cplusplus
}
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c
index 357d61b246..c49ab4a68d 100644
--- a/src/mesa/shader/slang/slang_compile.c
+++ b/src/mesa/shader/slang/slang_compile.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.6
+ * Version: 6.5.2
*
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
*
@@ -35,21 +35,25 @@
#include "slang_storage.h"
/*
- * This is a straightforward implementation of the slang front-end compiler.
- * Lots of error-checking functionality is missing but every well-formed shader source should
- * compile successfully and execute as expected. However, some semantically ill-formed shaders
+ * This is a straightforward implementation of the slang front-end
+ * compiler. Lots of error-checking functionality is missing but
+ * every well-formed shader source should compile successfully and
+ * execute as expected. However, some semantically ill-formed shaders
* may be accepted resulting in undefined behaviour.
*/
-/* slang_var_pool */
-static GLuint slang_var_pool_alloc (slang_var_pool *pool, unsigned int size)
-{
- GLuint addr;
- addr = pool->next_addr;
- pool->next_addr += size;
- return addr;
+/**
+ * Allocate storage for a variable of 'size' bytes from given pool.
+ * Return the allocated address for the variable.
+ */
+static GLuint
+slang_var_pool_alloc(slang_var_pool * pool, unsigned int size)
+{
+ const GLuint addr = pool->next_addr;
+ pool->next_addr += size;
+ return addr;
}
/*
@@ -57,20 +61,21 @@ static GLuint slang_var_pool_alloc (slang_var_pool *pool, unsigned int size)
*/
GLvoid
-_slang_code_unit_ctr (slang_code_unit *self, struct slang_code_object_ *object)
+_slang_code_unit_ctr(slang_code_unit * self,
+ struct slang_code_object_ * object)
{
- _slang_variable_scope_ctr (&self->vars);
- _slang_function_scope_ctr (&self->funs);
- _slang_struct_scope_ctr (&self->structs);
+ _slang_variable_scope_ctr(&self->vars);
+ _slang_function_scope_ctr(&self->funs);
+ _slang_struct_scope_ctr(&self->structs);
self->object = object;
}
GLvoid
-_slang_code_unit_dtr (slang_code_unit *self)
+_slang_code_unit_dtr(slang_code_unit * self)
{
- slang_variable_scope_destruct (&self->vars);
- slang_function_scope_destruct (&self->funs);
- slang_struct_scope_destruct (&self->structs);
+ slang_variable_scope_destruct(&self->vars);
+ slang_function_scope_destruct(&self->funs);
+ slang_struct_scope_destruct(&self->structs);
}
/*
@@ -78,296 +83,313 @@ _slang_code_unit_dtr (slang_code_unit *self)
*/
GLvoid
-_slang_code_object_ctr (slang_code_object *self)
+_slang_code_object_ctr(slang_code_object * self)
{
GLuint i;
for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
- _slang_code_unit_ctr (&self->builtin[i], self);
- _slang_code_unit_ctr (&self->unit, self);
- _slang_assembly_file_ctr (&self->assembly);
- slang_machine_ctr (&self->machine);
+ _slang_code_unit_ctr(&self->builtin[i], self);
+ _slang_code_unit_ctr(&self->unit, self);
+ _slang_assembly_file_ctr(&self->assembly);
+ slang_machine_ctr(&self->machine);
self->varpool.next_addr = 0;
- slang_atom_pool_construct (&self->atompool);
- slang_export_data_table_ctr (&self->expdata);
+ slang_atom_pool_construct(&self->atompool);
+ slang_export_data_table_ctr(&self->expdata);
self->expdata.atoms = &self->atompool;
- slang_export_code_table_ctr (&self->expcode);
+ slang_export_code_table_ctr(&self->expcode);
self->expcode.atoms = &self->atompool;
}
GLvoid
-_slang_code_object_dtr (slang_code_object *self)
+_slang_code_object_dtr(slang_code_object * self)
{
GLuint i;
for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
- _slang_code_unit_dtr (&self->builtin[i]);
- _slang_code_unit_dtr (&self->unit);
- slang_assembly_file_destruct (&self->assembly);
- slang_machine_dtr (&self->machine);
- slang_atom_pool_destruct (&self->atompool);
- slang_export_data_table_dtr (&self->expdata);
- slang_export_code_table_ctr (&self->expcode);
+ _slang_code_unit_dtr(&self->builtin[i]);
+ _slang_code_unit_dtr(&self->unit);
+ slang_assembly_file_destruct(&self->assembly);
+ slang_machine_dtr(&self->machine);
+ slang_atom_pool_destruct(&self->atompool);
+ slang_export_data_table_dtr(&self->expdata);
+ slang_export_code_table_ctr(&self->expcode);
}
/* slang_info_log */
static char *out_of_memory = "Error: Out of memory.\n";
-void slang_info_log_construct (slang_info_log *log)
+void
+slang_info_log_construct(slang_info_log * log)
{
- log->text = NULL;
- log->dont_free_text = 0;
+ log->text = NULL;
+ log->dont_free_text = 0;
}
-void slang_info_log_destruct (slang_info_log *log)
+void
+slang_info_log_destruct(slang_info_log * log)
{
- if (!log->dont_free_text)
- slang_alloc_free (log->text);
+ if (!log->dont_free_text)
+ slang_alloc_free(log->text);
}
-static int slang_info_log_message (slang_info_log *log, const char *prefix, const char *msg)
+static int
+slang_info_log_message(slang_info_log * log, const char *prefix,
+ const char *msg)
{
GLuint size;
- if (log->dont_free_text)
- return 0;
- size = slang_string_length (msg) + 2;
+ if (log->dont_free_text)
+ return 0;
+ size = slang_string_length(msg) + 2;
if (prefix != NULL)
- size += slang_string_length (prefix) + 2;
+ size += slang_string_length(prefix) + 2;
if (log->text != NULL) {
- GLuint old_len = slang_string_length (log->text);
- log->text = (char *) (slang_alloc_realloc (log->text, old_len + 1, old_len + size));
+ GLuint old_len = slang_string_length(log->text);
+ log->text = (char *)
+ slang_alloc_realloc(log->text, old_len + 1, old_len + size);
}
else {
- log->text = (char *) (slang_alloc_malloc (size));
+ log->text = (char *) (slang_alloc_malloc(size));
if (log->text != NULL)
log->text[0] = '\0';
}
- if (log->text == NULL)
- return 0;
+ if (log->text == NULL)
+ return 0;
if (prefix != NULL) {
- slang_string_concat (log->text, prefix);
- slang_string_concat (log->text, ": ");
+ slang_string_concat(log->text, prefix);
+ slang_string_concat(log->text, ": ");
}
- slang_string_concat (log->text, msg);
- slang_string_concat (log->text, "\n");
- return 1;
+ slang_string_concat(log->text, msg);
+ slang_string_concat(log->text, "\n");
+ return 1;
}
-int slang_info_log_print (slang_info_log *log, const char *msg, ...)
+int
+slang_info_log_print(slang_info_log * log, const char *msg, ...)
{
va_list va;
char buf[1024];
- va_start (va, msg);
- _mesa_vsprintf (buf, msg, va);
- va_end (va);
- return slang_info_log_message (log, NULL, buf);
+ va_start(va, msg);
+ _mesa_vsprintf(buf, msg, va);
+ va_end(va);
+ return slang_info_log_message(log, NULL, buf);
}
-int slang_info_log_error (slang_info_log *log, const char *msg, ...)
+int
+slang_info_log_error(slang_info_log * log, const char *msg, ...)
{
- va_list va;
- char buf[1024];
-
- va_start (va, msg);
- _mesa_vsprintf (buf, msg, va);
- va_end (va);
- if (slang_info_log_message (log, "Error", buf))
- return 1;
- slang_info_log_memory (log);
- return 0;
+ va_list va;
+ char buf[1024];
+
+ va_start(va, msg);
+ _mesa_vsprintf(buf, msg, va);
+ va_end(va);
+ if (slang_info_log_message(log, "Error", buf))
+ return 1;
+ slang_info_log_memory(log);
+ return 0;
}
-int slang_info_log_warning (slang_info_log *log, const char *msg, ...)
+int
+slang_info_log_warning(slang_info_log * log, const char *msg, ...)
{
- va_list va;
- char buf[1024];
-
- va_start (va, msg);
- _mesa_vsprintf (buf, msg, va);
- va_end (va);
- if (slang_info_log_message (log, "Warning", buf))
- return 1;
- slang_info_log_memory (log);
- return 0;
+ va_list va;
+ char buf[1024];
+
+ va_start(va, msg);
+ _mesa_vsprintf(buf, msg, va);
+ va_end(va);
+ if (slang_info_log_message(log, "Warning", buf))
+ return 1;
+ slang_info_log_memory(log);
+ return 0;
}
-void slang_info_log_memory (slang_info_log *log)
+void
+slang_info_log_memory(slang_info_log * log)
{
- if (!slang_info_log_message (log, "Error", "Out of memory."))
- {
- log->dont_free_text = 1;
- log->text = out_of_memory;
- }
+ if (!slang_info_log_message(log, "Error", "Out of memory.")) {
+ log->dont_free_text = 1;
+ log->text = out_of_memory;
+ }
}
/* slang_parse_ctx */
typedef struct slang_parse_ctx_
{
- const byte *I;
- slang_info_log *L;
- int parsing_builtin;
- int global_scope;
- slang_atom_pool *atoms;
+ const byte *I;
+ slang_info_log *L;
+ int parsing_builtin;
+ GLboolean global_scope; /**< Is object being declared a global? */
+ slang_atom_pool *atoms;
} slang_parse_ctx;
/* slang_output_ctx */
typedef struct slang_output_ctx_
{
- slang_variable_scope *vars;
- slang_function_scope *funs;
- slang_struct_scope *structs;
- slang_assembly_file *assembly;
- slang_var_pool *global_pool;
- slang_machine *machine;
+ slang_variable_scope *vars;
+ slang_function_scope *funs;
+ slang_struct_scope *structs;
+ slang_assembly_file *assembly;
+ slang_var_pool *global_pool;
+ slang_machine *machine;
} slang_output_ctx;
/* _slang_compile() */
-static void parse_identifier_str (slang_parse_ctx *C, char **id)
+static void
+parse_identifier_str(slang_parse_ctx * C, char **id)
{
- *id = (char *) C->I;
- C->I += _mesa_strlen (*id) + 1;
+ *id = (char *) C->I;
+ C->I += _mesa_strlen(*id) + 1;
}
-static slang_atom parse_identifier (slang_parse_ctx *C)
+static slang_atom
+parse_identifier(slang_parse_ctx * C)
{
- const char *id;
-
- id = (const char *) C->I;
- C->I += _mesa_strlen (id) + 1;
- return slang_atom_pool_atom (C->atoms, id);
+ const char *id;
+
+ id = (const char *) C->I;
+ C->I += _mesa_strlen(id) + 1;
+ return slang_atom_pool_atom(C->atoms, id);
}
-static int parse_number (slang_parse_ctx *C, int *number)
+static int
+parse_number(slang_parse_ctx * C, int *number)
{
- const int radix = (int) (*C->I++);
- *number = 0;
- while (*C->I != '\0')
- {
- int digit;
- if (*C->I >= '0' && *C->I <= '9')
- digit = (int) (*C->I - '0');
- else if (*C->I >= 'A' && *C->I <= 'Z')
- digit = (int) (*C->I - 'A') + 10;
- else
- digit = (int) (*C->I - 'a') + 10;
- *number = *number * radix + digit;
- C->I++;
- }
- C->I++;
- if (*number > 65535)
- slang_info_log_warning (C->L, "%d: literal integer overflow.", *number);
- return 1;
+ const int radix = (int) (*C->I++);
+ *number = 0;
+ while (*C->I != '\0') {
+ int digit;
+ if (*C->I >= '0' && *C->I <= '9')
+ digit = (int) (*C->I - '0');
+ else if (*C->I >= 'A' && *C->I <= 'Z')
+ digit = (int) (*C->I - 'A') + 10;
+ else
+ digit = (int) (*C->I - 'a') + 10;
+ *number = *number * radix + digit;
+ C->I++;
+ }
+ C->I++;
+ if (*number > 65535)
+ slang_info_log_warning(C->L, "%d: literal integer overflow.", *number);
+ return 1;
}
-static int parse_float (slang_parse_ctx *C, float *number)
+static int
+parse_float(slang_parse_ctx * C, float *number)
{
- char *integral = NULL;
- char *fractional = NULL;
- char *exponent = NULL;
- char *whole = NULL;
-
- parse_identifier_str (C, &integral);
- parse_identifier_str (C, &fractional);
- parse_identifier_str (C, &exponent);
-
- whole = (char *) (slang_alloc_malloc ((_mesa_strlen (integral) + _mesa_strlen (fractional) +
- _mesa_strlen (exponent) + 3) * sizeof (char)));
- if (whole == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
-
- slang_string_copy (whole, integral);
- slang_string_concat (whole, ".");
- slang_string_concat (whole, fractional);
- slang_string_concat (whole, "E");
- slang_string_concat (whole, exponent);
-
- *number = (float) (_mesa_strtod(whole, (char **)NULL));
-
- slang_alloc_free (whole);
- return 1;
+ char *integral = NULL;
+ char *fractional = NULL;
+ char *exponent = NULL;
+ char *whole = NULL;
+
+ parse_identifier_str(C, &integral);
+ parse_identifier_str(C, &fractional);
+ parse_identifier_str(C, &exponent);
+
+ whole = (char *) (slang_alloc_malloc((_mesa_strlen(integral) +
+ _mesa_strlen(fractional) +
+ _mesa_strlen(exponent) + 3) * sizeof(char)));
+ if (whole == NULL) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+
+ slang_string_copy(whole, integral);
+ slang_string_concat(whole, ".");
+ slang_string_concat(whole, fractional);
+ slang_string_concat(whole, "E");
+ slang_string_concat(whole, exponent);
+
+ *number = (float) (_mesa_strtod(whole, (char **) NULL));
+
+ slang_alloc_free(whole);
+ return 1;
}
/* revision number - increment after each change affecting emitted output */
#define REVISION 3
-static int check_revision (slang_parse_ctx *C)
+static int
+check_revision(slang_parse_ctx * C)
{
- if (*C->I != REVISION)
- {
- slang_info_log_error (C->L, "Internal compiler error.");
- return 0;
- }
- C->I++;
- return 1;
+ if (*C->I != REVISION) {
+ slang_info_log_error(C->L, "Internal compiler error.");
+ return 0;
+ }
+ C->I++;
+ return 1;
}
-static int parse_statement (slang_parse_ctx *, slang_output_ctx *, slang_operation *);
-static int parse_expression (slang_parse_ctx *, slang_output_ctx *, slang_operation *);
-static int parse_type_specifier (slang_parse_ctx *, slang_output_ctx *, slang_type_specifier *);
+static int parse_statement(slang_parse_ctx *, slang_output_ctx *,
+ slang_operation *);
+static int parse_expression(slang_parse_ctx *, slang_output_ctx *,
+ slang_operation *);
+static int parse_type_specifier(slang_parse_ctx *, slang_output_ctx *,
+ slang_type_specifier *);
-static GLboolean parse_array_len (slang_parse_ctx *C, slang_output_ctx *O, GLuint *len)
+static GLboolean
+parse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len)
{
- slang_operation array_size;
- slang_assembly_name_space space;
- GLboolean result;
-
- if (!slang_operation_construct (&array_size))
- return GL_FALSE;
- if (!parse_expression (C, O, &array_size))
- {
- slang_operation_destruct (&array_size);
- return GL_FALSE;
- }
-
- space.funcs = O->funs;
- space.structs = O->structs;
- space.vars = O->vars;
- result = _slang_evaluate_int (O->assembly, O->machine, &space, &array_size, len, C->atoms);
- slang_operation_destruct (&array_size);
- return result;
+ slang_operation array_size;
+ slang_assembly_name_space space;
+ GLboolean result;
+
+ if (!slang_operation_construct(&array_size))
+ return GL_FALSE;
+ if (!parse_expression(C, O, &array_size)) {
+ slang_operation_destruct(&array_size);
+ return GL_FALSE;
+ }
+
+ space.funcs = O->funs;
+ space.structs = O->structs;
+ space.vars = O->vars;
+ result = _slang_evaluate_int(O->assembly, O->machine, &space,
+ &array_size, len, C->atoms);
+ slang_operation_destruct(&array_size);
+ return result;
}
-static GLboolean calculate_var_size (slang_parse_ctx *C, slang_output_ctx *O, slang_variable *var)
+static GLboolean
+calculate_var_size(slang_parse_ctx * C, slang_output_ctx * O,
+ slang_variable * var)
{
- slang_storage_aggregate agg;
-
- if (!slang_storage_aggregate_construct (&agg))
- return GL_FALSE;
- if (!_slang_aggregate_variable (&agg, &var->type.specifier, var->array_len, O->funs, O->structs,
- O->vars, O->machine, O->assembly, C->atoms))
- {
- slang_storage_aggregate_destruct (&agg);
- return GL_FALSE;
- }
- var->size = _slang_sizeof_aggregate (&agg);
- slang_storage_aggregate_destruct (&agg);
- return GL_TRUE;
+ slang_storage_aggregate agg;
+
+ if (!slang_storage_aggregate_construct(&agg))
+ return GL_FALSE;
+ if (!_slang_aggregate_variable(&agg, &var->type.specifier, var->array_len,
+ O->funs, O->structs, O->vars, O->machine,
+ O->assembly, C->atoms)) {
+ slang_storage_aggregate_destruct(&agg);
+ return GL_FALSE;
+ }
+ var->size = _slang_sizeof_aggregate(&agg);
+ slang_storage_aggregate_destruct(&agg);
+ return GL_TRUE;
}
-static GLboolean convert_to_array (slang_parse_ctx *C, slang_variable *var,
- const slang_type_specifier *sp)
+static GLboolean
+convert_to_array(slang_parse_ctx * C, slang_variable * var,
+ const slang_type_specifier * sp)
{
- /* sized array - mark it as array, copy the specifier to the array element and
- * parse the expression */
- var->type.specifier.type = slang_spec_array;
- var->type.specifier._array = (slang_type_specifier *) slang_alloc_malloc (sizeof (
- slang_type_specifier));
- if (var->type.specifier._array == NULL)
- {
- slang_info_log_memory (C->L);
- return GL_FALSE;
- }
- slang_type_specifier_ctr (var->type.specifier._array);
- return slang_type_specifier_copy (var->type.specifier._array, sp);
+ /* sized array - mark it as array, copy the specifier to the array element and
+ * parse the expression */
+ var->type.specifier.type = slang_spec_array;
+ var->type.specifier._array = (slang_type_specifier *)
+ slang_alloc_malloc(sizeof(slang_type_specifier));
+ if (var->type.specifier._array == NULL) {
+ slang_info_log_memory(C->L);
+ return GL_FALSE;
+ }
+ slang_type_specifier_ctr(var->type.specifier._array);
+ return slang_type_specifier_copy(var->type.specifier._array, sp);
}
/* structure field */
@@ -375,136 +397,128 @@ static GLboolean convert_to_array (slang_parse_ctx *C, slang_variable *var,
#define FIELD_NEXT 1
#define FIELD_ARRAY 2
-static GLboolean parse_struct_field_var (slang_parse_ctx *C, slang_output_ctx *O, slang_variable *var,
- const slang_type_specifier *sp)
+static GLboolean
+parse_struct_field_var(slang_parse_ctx * C, slang_output_ctx * O,
+ slang_variable * var, const slang_type_specifier * sp)
{
- var->a_name = parse_identifier (C);
- if (var->a_name == SLANG_ATOM_NULL)
- return GL_FALSE;
-
- switch (*C->I++)
- {
- case FIELD_NONE:
- if (!slang_type_specifier_copy (&var->type.specifier, sp))
- return GL_FALSE;
- break;
- case FIELD_ARRAY:
- if (!convert_to_array (C, var, sp))
- return GL_FALSE;
- if (!parse_array_len (C, O, &var->array_len))
- return GL_FALSE;
- break;
- default:
- return GL_FALSE;
- }
-
- return calculate_var_size (C, O, var);
+ var->a_name = parse_identifier(C);
+ if (var->a_name == SLANG_ATOM_NULL)
+ return GL_FALSE;
+
+ switch (*C->I++) {
+ case FIELD_NONE:
+ if (!slang_type_specifier_copy(&var->type.specifier, sp))
+ return GL_FALSE;
+ break;
+ case FIELD_ARRAY:
+ if (!convert_to_array(C, var, sp))
+ return GL_FALSE;
+ if (!parse_array_len(C, O, &var->array_len))
+ return GL_FALSE;
+ break;
+ default:
+ return GL_FALSE;
+ }
+
+ return calculate_var_size(C, O, var);
}
-static int parse_struct_field (slang_parse_ctx *C, slang_output_ctx *O, slang_struct *st,
- slang_type_specifier *sp)
+static int
+parse_struct_field(slang_parse_ctx * C, slang_output_ctx * O,
+ slang_struct * st, slang_type_specifier * sp)
{
- slang_output_ctx o = *O;
-
- o.structs = st->structs;
- if (!parse_type_specifier (C, &o, sp))
- return 0;
- do
- {
- slang_variable *var;
-
- st->fields->variables = (slang_variable *) slang_alloc_realloc (st->fields->variables,
- st->fields->num_variables * sizeof (slang_variable),
- (st->fields->num_variables + 1) * sizeof (slang_variable));
- if (st->fields->variables == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- var = &st->fields->variables[st->fields->num_variables];
- if (!slang_variable_construct (var))
- return 0;
- st->fields->num_variables++;
- if (!parse_struct_field_var (C, &o, var, sp))
- return 0;
- }
- while (*C->I++ != FIELD_NONE);
-
- return 1;
+ slang_output_ctx o = *O;
+
+ o.structs = st->structs;
+ if (!parse_type_specifier(C, &o, sp))
+ return 0;
+
+ do {
+ slang_variable *var = slang_variable_scope_grow(st->fields);
+ if (!var) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ if (!parse_struct_field_var(C, &o, var, sp))
+ return 0;
+ }
+ while (*C->I++ != FIELD_NONE);
+
+ return 1;
}
-static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct **st)
+static int
+parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st)
{
- slang_atom a_name;
- const char *name;
-
- /* parse struct name (if any) and make sure it is unique in current scope */
- a_name = parse_identifier (C);
- if (a_name == SLANG_ATOM_NULL)
- return 0;
- name = slang_atom_pool_id (C->atoms, a_name);
- if (name[0] != '\0' && slang_struct_scope_find (O->structs, a_name, 0) != NULL)
- {
- slang_info_log_error (C->L, "%s: duplicate type name.", name);
- return 0;
- }
-
- /* set-up a new struct */
- *st = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
- if (*st == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- if (!slang_struct_construct (*st))
- {
- slang_alloc_free (*st);
- *st = NULL;
- slang_info_log_memory (C->L);
- return 0;
- }
- (**st).a_name = a_name;
- (**st).structs->outer_scope = O->structs;
-
- /* parse individual struct fields */
- do
- {
- slang_type_specifier sp;
-
- slang_type_specifier_ctr (&sp);
- if (!parse_struct_field (C, O, *st, &sp))
- {
- slang_type_specifier_dtr (&sp);
- return 0;
- }
- slang_type_specifier_dtr (&sp);
- }
- while (*C->I++ != FIELD_NONE);
-
- /* if named struct, copy it to current scope */
- if (name[0] != '\0')
- {
- slang_struct *s;
-
- O->structs->structs = (slang_struct *) slang_alloc_realloc (O->structs->structs,
- O->structs->num_structs * sizeof (slang_struct),
- (O->structs->num_structs + 1) * sizeof (slang_struct));
- if (O->structs->structs == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- s = &O->structs->structs[O->structs->num_structs];
- if (!slang_struct_construct (s))
- return 0;
- O->structs->num_structs++;
- if (!slang_struct_copy (s, *st))
- return 0;
- }
-
- return 1;
+ slang_atom a_name;
+ const char *name;
+
+ /* parse struct name (if any) and make sure it is unique in current scope */
+ a_name = parse_identifier(C);
+ if (a_name == SLANG_ATOM_NULL)
+ return 0;
+
+ name = slang_atom_pool_id(C->atoms, a_name);
+ if (name[0] != '\0'
+ && slang_struct_scope_find(O->structs, a_name, 0) != NULL) {
+ slang_info_log_error(C->L, "%s: duplicate type name.", name);
+ return 0;
+ }
+
+ /* set-up a new struct */
+ *st = (slang_struct *) slang_alloc_malloc(sizeof(slang_struct));
+ if (*st == NULL) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ if (!slang_struct_construct(*st)) {
+ slang_alloc_free(*st);
+ *st = NULL;
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ (**st).a_name = a_name;
+ (**st).structs->outer_scope = O->structs;
+
+ /* parse individual struct fields */
+ do {
+ slang_type_specifier sp;
+
+ slang_type_specifier_ctr(&sp);
+ if (!parse_struct_field(C, O, *st, &sp)) {
+ slang_type_specifier_dtr(&sp);
+ return 0;
+ }
+ slang_type_specifier_dtr(&sp);
+ }
+ while (*C->I++ != FIELD_NONE);
+
+ /* if named struct, copy it to current scope */
+ if (name[0] != '\0') {
+ slang_struct *s;
+
+ O->structs->structs =
+ (slang_struct *) slang_alloc_realloc(O->structs->structs,
+ O->structs->num_structs *
+ sizeof(slang_struct),
+ (O->structs->num_structs +
+ 1) * sizeof(slang_struct));
+ if (O->structs->structs == NULL) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ s = &O->structs->structs[O->structs->num_structs];
+ if (!slang_struct_construct(s))
+ return 0;
+ O->structs->num_structs++;
+ if (!slang_struct_copy(s, *st))
+ return 0;
+ }
+
+ return 1;
}
+
/* type qualifier */
#define TYPE_QUALIFIER_NONE 0
#define TYPE_QUALIFIER_CONST 1
@@ -514,35 +528,35 @@ static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct *
#define TYPE_QUALIFIER_FIXEDOUTPUT 5
#define TYPE_QUALIFIER_FIXEDINPUT 6
-static int parse_type_qualifier (slang_parse_ctx *C, slang_type_qualifier *qual)
+static int
+parse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual)
{
- switch (*C->I++)
- {
- case TYPE_QUALIFIER_NONE:
- *qual = slang_qual_none;
- break;
- case TYPE_QUALIFIER_CONST:
- *qual = slang_qual_const;
- break;
- case TYPE_QUALIFIER_ATTRIBUTE:
- *qual = slang_qual_attribute;
- break;
- case TYPE_QUALIFIER_VARYING:
- *qual = slang_qual_varying;
- break;
- case TYPE_QUALIFIER_UNIFORM:
- *qual = slang_qual_uniform;
- break;
- case TYPE_QUALIFIER_FIXEDOUTPUT:
- *qual = slang_qual_fixedoutput;
- break;
- case TYPE_QUALIFIER_FIXEDINPUT:
- *qual = slang_qual_fixedinput;
- break;
- default:
- return 0;
- }
- return 1;
+ switch (*C->I++) {
+ case TYPE_QUALIFIER_NONE:
+ *qual = slang_qual_none;
+ break;
+ case TYPE_QUALIFIER_CONST:
+ *qual = slang_qual_const;
+ break;
+ case TYPE_QUALIFIER_ATTRIBUTE:
+ *qual = slang_qual_attribute;
+ break;
+ case TYPE_QUALIFIER_VARYING:
+ *qual = slang_qual_varying;
+ break;
+ case TYPE_QUALIFIER_UNIFORM:
+ *qual = slang_qual_uniform;
+ break;
+ case TYPE_QUALIFIER_FIXEDOUTPUT:
+ *qual = slang_qual_fixedoutput;
+ break;
+ case TYPE_QUALIFIER_FIXEDINPUT:
+ *qual = slang_qual_fixedinput;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
}
/* type specifier */
@@ -571,127 +585,127 @@ static int parse_type_qualifier (slang_parse_ctx *C, slang_type_qualifier *qual)
#define TYPE_SPECIFIER_STRUCT 22
#define TYPE_SPECIFIER_TYPENAME 23
-static int parse_type_specifier (slang_parse_ctx *C, slang_output_ctx *O, slang_type_specifier *spec)
+static int
+parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O,
+ slang_type_specifier * spec)
{
- switch (*C->I++)
- {
- case TYPE_SPECIFIER_VOID:
- spec->type = slang_spec_void;
- break;
- case TYPE_SPECIFIER_BOOL:
- spec->type = slang_spec_bool;
- break;
- case TYPE_SPECIFIER_BVEC2:
- spec->type = slang_spec_bvec2;
- break;
- case TYPE_SPECIFIER_BVEC3:
- spec->type = slang_spec_bvec3;
- break;
- case TYPE_SPECIFIER_BVEC4:
- spec->type = slang_spec_bvec4;
- break;
- case TYPE_SPECIFIER_INT:
- spec->type = slang_spec_int;
- break;
- case TYPE_SPECIFIER_IVEC2:
- spec->type = slang_spec_ivec2;
- break;
- case TYPE_SPECIFIER_IVEC3:
- spec->type = slang_spec_ivec3;
- break;
- case TYPE_SPECIFIER_IVEC4:
- spec->type = slang_spec_ivec4;
- break;
- case TYPE_SPECIFIER_FLOAT:
- spec->type = slang_spec_float;
- break;
- case TYPE_SPECIFIER_VEC2:
- spec->type = slang_spec_vec2;
- break;
- case TYPE_SPECIFIER_VEC3:
- spec->type = slang_spec_vec3;
- break;
- case TYPE_SPECIFIER_VEC4:
- spec->type = slang_spec_vec4;
- break;
- case TYPE_SPECIFIER_MAT2:
- spec->type = slang_spec_mat2;
- break;
- case TYPE_SPECIFIER_MAT3:
- spec->type = slang_spec_mat3;
- break;
- case TYPE_SPECIFIER_MAT4:
- spec->type = slang_spec_mat4;
- break;
- case TYPE_SPECIFIER_SAMPLER1D:
- spec->type = slang_spec_sampler1D;
- break;
- case TYPE_SPECIFIER_SAMPLER2D:
- spec->type = slang_spec_sampler2D;
- break;
- case TYPE_SPECIFIER_SAMPLER3D:
- spec->type = slang_spec_sampler3D;
- break;
- case TYPE_SPECIFIER_SAMPLERCUBE:
- spec->type = slang_spec_samplerCube;
- break;
- case TYPE_SPECIFIER_SAMPLER1DSHADOW:
- spec->type = slang_spec_sampler1DShadow;
- break;
- case TYPE_SPECIFIER_SAMPLER2DSHADOW:
- spec->type = slang_spec_sampler2DShadow;
- break;
- case TYPE_SPECIFIER_STRUCT:
- spec->type = slang_spec_struct;
- if (!parse_struct (C, O, &spec->_struct))
- return 0;
- break;
- case TYPE_SPECIFIER_TYPENAME:
- spec->type = slang_spec_struct;
- {
- slang_atom a_name;
- slang_struct *stru;
-
- a_name = parse_identifier (C);
- if (a_name == NULL)
- return 0;
-
- stru = slang_struct_scope_find (O->structs, a_name, 1);
- if (stru == NULL)
- {
- slang_info_log_error (C->L, "%s: undeclared type name.",
- slang_atom_pool_id (C->atoms, a_name));
- return 0;
- }
-
- spec->_struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
- if (spec->_struct == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- if (!slang_struct_construct (spec->_struct))
- {
- slang_alloc_free (spec->_struct);
- spec->_struct = NULL;
- return 0;
- }
- if (!slang_struct_copy (spec->_struct, stru))
- return 0;
- }
- break;
- default:
- return 0;
- }
- return 1;
+ switch (*C->I++) {
+ case TYPE_SPECIFIER_VOID:
+ spec->type = slang_spec_void;
+ break;
+ case TYPE_SPECIFIER_BOOL:
+ spec->type = slang_spec_bool;
+ break;
+ case TYPE_SPECIFIER_BVEC2:
+ spec->type = slang_spec_bvec2;
+ break;
+ case TYPE_SPECIFIER_BVEC3:
+ spec->type = slang_spec_bvec3;
+ break;
+ case TYPE_SPECIFIER_BVEC4:
+ spec->type = slang_spec_bvec4;
+ break;
+ case TYPE_SPECIFIER_INT:
+ spec->type = slang_spec_int;
+ break;
+ case TYPE_SPECIFIER_IVEC2:
+ spec->type = slang_spec_ivec2;
+ break;
+ case TYPE_SPECIFIER_IVEC3:
+ spec->type = slang_spec_ivec3;
+ break;
+ case TYPE_SPECIFIER_IVEC4:
+ spec->type = slang_spec_ivec4;
+ break;
+ case TYPE_SPECIFIER_FLOAT:
+ spec->type = slang_spec_float;
+ break;
+ case TYPE_SPECIFIER_VEC2:
+ spec->type = slang_spec_vec2;
+ break;
+ case TYPE_SPECIFIER_VEC3:
+ spec->type = slang_spec_vec3;
+ break;
+ case TYPE_SPECIFIER_VEC4:
+ spec->type = slang_spec_vec4;
+ break;
+ case TYPE_SPECIFIER_MAT2:
+ spec->type = slang_spec_mat2;
+ break;
+ case TYPE_SPECIFIER_MAT3:
+ spec->type = slang_spec_mat3;
+ break;
+ case TYPE_SPECIFIER_MAT4:
+ spec->type = slang_spec_mat4;
+ break;
+ case TYPE_SPECIFIER_SAMPLER1D:
+ spec->type = slang_spec_sampler1D;
+ break;
+ case TYPE_SPECIFIER_SAMPLER2D:
+ spec->type = slang_spec_sampler2D;
+ break;
+ case TYPE_SPECIFIER_SAMPLER3D:
+ spec->type = slang_spec_sampler3D;
+ break;
+ case TYPE_SPECIFIER_SAMPLERCUBE:
+ spec->type = slang_spec_samplerCube;
+ break;
+ case TYPE_SPECIFIER_SAMPLER1DSHADOW:
+ spec->type = slang_spec_sampler1DShadow;
+ break;
+ case TYPE_SPECIFIER_SAMPLER2DSHADOW:
+ spec->type = slang_spec_sampler2DShadow;
+ break;
+ case TYPE_SPECIFIER_STRUCT:
+ spec->type = slang_spec_struct;
+ if (!parse_struct(C, O, &spec->_struct))
+ return 0;
+ break;
+ case TYPE_SPECIFIER_TYPENAME:
+ spec->type = slang_spec_struct;
+ {
+ slang_atom a_name;
+ slang_struct *stru;
+
+ a_name = parse_identifier(C);
+ if (a_name == NULL)
+ return 0;
+
+ stru = slang_struct_scope_find(O->structs, a_name, 1);
+ if (stru == NULL) {
+ slang_info_log_error(C->L, "%s: undeclared type name.",
+ slang_atom_pool_id(C->atoms, a_name));
+ return 0;
+ }
+
+ spec->_struct =
+ (slang_struct *) slang_alloc_malloc(sizeof(slang_struct));
+ if (spec->_struct == NULL) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ if (!slang_struct_construct(spec->_struct)) {
+ slang_alloc_free(spec->_struct);
+ spec->_struct = NULL;
+ return 0;
+ }
+ if (!slang_struct_copy(spec->_struct, stru))
+ return 0;
+ }
+ break;
+ default:
+ return 0;
+ }
+ return 1;
}
-static int parse_fully_specified_type (slang_parse_ctx *C, slang_output_ctx *O,
- slang_fully_specified_type *type)
+static int
+parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O,
+ slang_fully_specified_type * type)
{
- if (!parse_type_qualifier (C, &type->qualifier))
- return 0;
- return parse_type_specifier (C, O, &type->specifier);
+ if (!parse_type_qualifier(C, &type->qualifier))
+ return 0;
+ return parse_type_specifier(C, O, &type->specifier);
}
/* operation */
@@ -758,459 +772,487 @@ static int parse_fully_specified_type (slang_parse_ctx *C, slang_output_ctx *O,
#define OP_POSTINCREMENT 60
#define OP_POSTDECREMENT 61
-static int parse_child_operation (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper,
- int statement)
+
+/**
+ * When parsing a compound production, this function is used to parse the
+ * children.
+ * For example, a a while-loop compound will have two children, the
+ * while condition expression and the loop body. So, this function will
+ * be called twice to parse those two sub-expressions.
+ * \param C the parsing context
+ * \param O the output context
+ * \param oper the operation we're parsing
+ * \param statment which child of the operation is being parsed
+ * \return 1 if success, 0 if error
+ */
+static int
+parse_child_operation(slang_parse_ctx * C, slang_output_ctx * O,
+ slang_operation * oper, unsigned int statement)
{
- slang_operation *ch;
-
- oper->children = (slang_operation *) slang_alloc_realloc (oper->children,
- oper->num_children * sizeof (slang_operation),
- (oper->num_children + 1) * sizeof (slang_operation));
- if (oper->children == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- ch = &oper->children[oper->num_children];
- if (!slang_operation_construct (ch))
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- oper->num_children++;
- if (statement)
- return parse_statement (C, O, ch);
- return parse_expression (C, O, ch);
+ slang_operation *ch;
+
+ /* grow child array */
+ oper->children = (slang_operation *)
+ slang_alloc_realloc(oper->children,
+ oper->num_children * sizeof(slang_operation),
+ (oper->num_children + 1) * sizeof(slang_operation));
+ if (oper->children == NULL) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+
+ ch = &oper->children[oper->num_children];
+ if (!slang_operation_construct(ch)) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ oper->num_children++;
+ /* XXX I guess the 0th "statement" is not really a statement? */
+ if (statement)
+ return parse_statement(C, O, ch);
+ return parse_expression(C, O, ch);
}
-static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O);
+static int parse_declaration(slang_parse_ctx * C, slang_output_ctx * O);
-static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper)
+static int
+parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
+ slang_operation * oper)
{
- oper->locals->outer_scope = O->vars;
- switch (*C->I++)
- {
- case OP_BLOCK_BEGIN_NO_NEW_SCOPE:
- /* parse child statements, do not create new variable scope */
- oper->type = slang_oper_block_no_new_scope;
- while (*C->I != OP_END)
- if (!parse_child_operation (C, O, oper, 1))
- return 0;
- C->I++;
- break;
- case OP_BLOCK_BEGIN_NEW_SCOPE:
- /* parse child statements, create new variable scope */
- {
- slang_output_ctx o = *O;
-
- oper->type = slang_oper_block_new_scope;
- o.vars = oper->locals;
- while (*C->I != OP_END)
- if (!parse_child_operation (C, &o, oper, 1))
- return 0;
- C->I++;
- }
- break;
- case OP_DECLARE:
- /* local variable declaration, individual declarators are stored as children identifiers */
- oper->type = slang_oper_variable_decl;
- {
- const unsigned int first_var = O->vars->num_variables;
-
- /* parse the declaration, note that there can be zero or more than one declarators */
- if (!parse_declaration (C, O))
- return 0;
- if (first_var < O->vars->num_variables)
- {
- const unsigned int num_vars = O->vars->num_variables - first_var;
- unsigned int i;
-
- oper->children = (slang_operation *) slang_alloc_malloc (num_vars * sizeof (
- slang_operation));
- if (oper->children == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- for (oper->num_children = 0; oper->num_children < num_vars; oper->num_children++)
- if (!slang_operation_construct (&oper->children[oper->num_children]))
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- for (i = first_var; i < O->vars->num_variables; i++)
- {
- slang_operation *o = &oper->children[i - first_var];
-
- o->type = slang_oper_identifier;
- o->locals->outer_scope = O->vars;
- o->a_id = O->vars->variables[i].a_name;
- }
- }
- }
- break;
- case OP_ASM:
- /* the __asm statement, parse the mnemonic and all its arguments as expressions */
- oper->type = slang_oper_asm;
- oper->a_id = parse_identifier (C);
- if (oper->a_id == SLANG_ATOM_NULL)
- return 0;
- while (*C->I != OP_END)
- if (!parse_child_operation (C, O, oper, 0))
- return 0;
- C->I++;
- break;
- case OP_BREAK:
- oper->type = slang_oper_break;
- break;
- case OP_CONTINUE:
- oper->type = slang_oper_continue;
- break;
- case OP_DISCARD:
- oper->type = slang_oper_discard;
- break;
- case OP_RETURN:
- oper->type = slang_oper_return;
- if (!parse_child_operation (C, O, oper, 0))
- return 0;
- break;
- case OP_EXPRESSION:
- oper->type = slang_oper_expression;
- if (!parse_child_operation (C, O, oper, 0))
- return 0;
- break;
- case OP_IF:
- oper->type = slang_oper_if;
- if (!parse_child_operation (C, O, oper, 0))
- return 0;
- if (!parse_child_operation (C, O, oper, 1))
- return 0;
- if (!parse_child_operation (C, O, oper, 1))
- return 0;
- break;
- case OP_WHILE:
- {
- slang_output_ctx o = *O;
-
- oper->type = slang_oper_while;
- o.vars = oper->locals;
- if (!parse_child_operation (C, &o, oper, 1))
- return 0;
- if (!parse_child_operation (C, &o, oper, 1))
- return 0;
- }
- break;
- case OP_DO:
- oper->type = slang_oper_do;
- if (!parse_child_operation (C, O, oper, 1))
- return 0;
- if (!parse_child_operation (C, O, oper, 0))
- return 0;
- break;
- case OP_FOR:
- {
- slang_output_ctx o = *O;
-
- oper->type = slang_oper_for;
- o.vars = oper->locals;
- if (!parse_child_operation (C, &o, oper, 1))
- return 0;
- if (!parse_child_operation (C, &o, oper, 1))
- return 0;
- if (!parse_child_operation (C, &o, oper, 0))
- return 0;
- if (!parse_child_operation (C, &o, oper, 1))
- return 0;
- }
- break;
- default:
- return 0;
- }
- return 1;
+ oper->locals->outer_scope = O->vars;
+ switch (*C->I++) {
+ case OP_BLOCK_BEGIN_NO_NEW_SCOPE:
+ /* parse child statements, do not create new variable scope */
+ oper->type = slang_oper_block_no_new_scope;
+ while (*C->I != OP_END)
+ if (!parse_child_operation(C, O, oper, 1))
+ return 0;
+ C->I++;
+ break;
+ case OP_BLOCK_BEGIN_NEW_SCOPE:
+ /* parse child statements, create new variable scope */
+ {
+ slang_output_ctx o = *O;
+
+ oper->type = slang_oper_block_new_scope;
+ o.vars = oper->locals;
+ while (*C->I != OP_END)
+ if (!parse_child_operation(C, &o, oper, 1))
+ return 0;
+ C->I++;
+ }
+ break;
+ case OP_DECLARE:
+ /* local variable declaration, individual declarators are stored as
+ * children identifiers
+ */
+ oper->type = slang_oper_variable_decl;
+ {
+ const unsigned int first_var = O->vars->num_variables;
+
+ /* parse the declaration, note that there can be zero or more
+ * than one declarators
+ */
+ if (!parse_declaration(C, O))
+ return 0;
+ if (first_var < O->vars->num_variables) {
+ const unsigned int num_vars = O->vars->num_variables - first_var;
+ unsigned int i;
+
+ oper->children = (slang_operation *)
+ slang_alloc_malloc(num_vars * sizeof(slang_operation));
+ if (oper->children == NULL) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ for (oper->num_children = 0; oper->num_children < num_vars;
+ oper->num_children++) {
+ if (!slang_operation_construct
+ (&oper->children[oper->num_children])) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ }
+ for (i = first_var; i < O->vars->num_variables; i++) {
+ slang_operation *o = &oper->children[i - first_var];
+ o->type = slang_oper_identifier;
+ o->locals->outer_scope = O->vars;
+ o->a_id = O->vars->variables[i].a_name;
+ }
+ }
+ }
+ break;
+ case OP_ASM:
+ /* the __asm statement, parse the mnemonic and all its arguments
+ * as expressions
+ */
+ oper->type = slang_oper_asm;
+ oper->a_id = parse_identifier(C);
+ if (oper->a_id == SLANG_ATOM_NULL)
+ return 0;
+ while (*C->I != OP_END) {
+ if (!parse_child_operation(C, O, oper, 0))
+ return 0;
+ }
+ C->I++;
+ break;
+ case OP_BREAK:
+ oper->type = slang_oper_break;
+ break;
+ case OP_CONTINUE:
+ oper->type = slang_oper_continue;
+ break;
+ case OP_DISCARD:
+ oper->type = slang_oper_discard;
+ break;
+ case OP_RETURN:
+ oper->type = slang_oper_return;
+ if (!parse_child_operation(C, O, oper, 0))
+ return 0;
+ break;
+ case OP_EXPRESSION:
+ oper->type = slang_oper_expression;
+ if (!parse_child_operation(C, O, oper, 0))
+ return 0;
+ break;
+ case OP_IF:
+ oper->type = slang_oper_if;
+ if (!parse_child_operation(C, O, oper, 0))
+ return 0;
+ if (!parse_child_operation(C, O, oper, 1))
+ return 0;
+ if (!parse_child_operation(C, O, oper, 1))
+ return 0;
+ break;
+ case OP_WHILE:
+ {
+ slang_output_ctx o = *O;
+
+ oper->type = slang_oper_while;
+ o.vars = oper->locals;
+ if (!parse_child_operation(C, &o, oper, 1))
+ return 0;
+ if (!parse_child_operation(C, &o, oper, 1))
+ return 0;
+ }
+ break;
+ case OP_DO:
+ oper->type = slang_oper_do;
+ if (!parse_child_operation(C, O, oper, 1))
+ return 0;
+ if (!parse_child_operation(C, O, oper, 0))
+ return 0;
+ break;
+ case OP_FOR:
+ {
+ slang_output_ctx o = *O;
+
+ oper->type = slang_oper_for;
+ o.vars = oper->locals;
+ if (!parse_child_operation(C, &o, oper, 1))
+ return 0;
+ if (!parse_child_operation(C, &o, oper, 1))
+ return 0;
+ if (!parse_child_operation(C, &o, oper, 0))
+ return 0;
+ if (!parse_child_operation(C, &o, oper, 1))
+ return 0;
+ }
+ break;
+ default:
+ return 0;
+ }
+ return 1;
}
-static int handle_nary_expression (slang_parse_ctx *C, slang_operation *op, slang_operation **ops,
- unsigned int *total_ops, unsigned int n)
+static int
+handle_nary_expression(slang_parse_ctx * C, slang_operation * op,
+ slang_operation ** ops, unsigned int *total_ops,
+ unsigned int n)
{
- unsigned int i;
-
- op->children = (slang_operation *) slang_alloc_malloc (n * sizeof (slang_operation));
- if (op->children == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- op->num_children = n;
-
- for (i = 0; i < n; i++)
- op->children[i] = (*ops)[*total_ops - (n + 1 - i)];
- (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1];
- *total_ops -= n;
-
- *ops = (slang_operation *) slang_alloc_realloc (*ops, (*total_ops + n) * sizeof (slang_operation),
- *total_ops * sizeof (slang_operation));
- if (*ops == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- return 1;
+ unsigned int i;
+
+ op->children =
+ (slang_operation *) slang_alloc_malloc(n * sizeof(slang_operation));
+ if (op->children == NULL) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ op->num_children = n;
+
+ for (i = 0; i < n; i++)
+ op->children[i] = (*ops)[*total_ops - (n + 1 - i)];
+ (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1];
+ *total_ops -= n;
+
+ *ops = (slang_operation *)
+ slang_alloc_realloc(*ops,
+ (*total_ops + n) * sizeof(slang_operation),
+ *total_ops * sizeof(slang_operation));
+ if (*ops == NULL) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ return 1;
}
-static int is_constructor_name (const char *name, slang_atom a_name, slang_struct_scope *structs)
+static int
+is_constructor_name(const char *name, slang_atom a_name,
+ slang_struct_scope * structs)
{
- if (slang_type_specifier_type_from_string (name) != slang_spec_void)
- return 1;
- return slang_struct_scope_find (structs, a_name, 1) != NULL;
+ if (slang_type_specifier_type_from_string(name) != slang_spec_void)
+ return 1;
+ return slang_struct_scope_find(structs, a_name, 1) != NULL;
}
-static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper)
+static int
+parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
+ slang_operation * oper)
{
- slang_operation *ops = NULL;
- unsigned int num_ops = 0;
- int number;
-
- while (*C->I != OP_END)
- {
- slang_operation *op;
- const unsigned int op_code = *C->I++;
-
- /* allocate default operation, becomes a no-op if not used */
- ops = (slang_operation *) slang_alloc_realloc (ops,
- num_ops * sizeof (slang_operation), (num_ops + 1) * sizeof (slang_operation));
- if (ops == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- op = &ops[num_ops];
- if (!slang_operation_construct (op))
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- num_ops++;
- op->locals->outer_scope = O->vars;
-
- switch (op_code)
- {
- case OP_PUSH_VOID:
- op->type = slang_oper_void;
- break;
- case OP_PUSH_BOOL:
- op->type = slang_oper_literal_bool;
- if (!parse_number (C, &number))
- return 0;
- op->literal = (GLfloat) number;
- break;
- case OP_PUSH_INT:
- op->type = slang_oper_literal_int;
- if (!parse_number (C, &number))
- return 0;
- op->literal = (GLfloat) number;
- break;
- case OP_PUSH_FLOAT:
- op->type = slang_oper_literal_float;
- if (!parse_float (C, &op->literal))
- return 0;
- break;
- case OP_PUSH_IDENTIFIER:
- op->type = slang_oper_identifier;
- op->a_id = parse_identifier (C);
- if (op->a_id == SLANG_ATOM_NULL)
- return 0;
- break;
- case OP_SEQUENCE:
- op->type = slang_oper_sequence;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_ASSIGN:
- op->type = slang_oper_assign;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_ADDASSIGN:
- op->type = slang_oper_addassign;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_SUBASSIGN:
- op->type = slang_oper_subassign;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_MULASSIGN:
- op->type = slang_oper_mulassign;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_DIVASSIGN:
- op->type = slang_oper_divassign;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- /*case OP_MODASSIGN:*/
- /*case OP_LSHASSIGN:*/
- /*case OP_RSHASSIGN:*/
- /*case OP_ORASSIGN:*/
- /*case OP_XORASSIGN:*/
- /*case OP_ANDASSIGN:*/
- case OP_SELECT:
- op->type = slang_oper_select;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 3))
- return 0;
- break;
- case OP_LOGICALOR:
- op->type = slang_oper_logicalor;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_LOGICALXOR:
- op->type = slang_oper_logicalxor;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_LOGICALAND:
- op->type = slang_oper_logicaland;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- /*case OP_BITOR:*/
- /*case OP_BITXOR:*/
- /*case OP_BITAND:*/
- case OP_EQUAL:
- op->type = slang_oper_equal;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_NOTEQUAL:
- op->type = slang_oper_notequal;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_LESS:
- op->type = slang_oper_less;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_GREATER:
- op->type = slang_oper_greater;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_LESSEQUAL:
- op->type = slang_oper_lessequal;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_GREATEREQUAL:
- op->type = slang_oper_greaterequal;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- /*case OP_LSHIFT:*/
- /*case OP_RSHIFT:*/
- case OP_ADD:
- op->type = slang_oper_add;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_SUBTRACT:
- op->type = slang_oper_subtract;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_MULTIPLY:
- op->type = slang_oper_multiply;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_DIVIDE:
- op->type = slang_oper_divide;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- /*case OP_MODULUS:*/
- case OP_PREINCREMENT:
- op->type = slang_oper_preincrement;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
- return 0;
- break;
- case OP_PREDECREMENT:
- op->type = slang_oper_predecrement;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
- return 0;
- break;
- case OP_PLUS:
- op->type = slang_oper_plus;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
- return 0;
- break;
- case OP_MINUS:
- op->type = slang_oper_minus;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
- return 0;
- break;
- case OP_NOT:
- op->type = slang_oper_not;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
- return 0;
- break;
- /*case OP_COMPLEMENT:*/
- case OP_SUBSCRIPT:
- op->type = slang_oper_subscript;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
- return 0;
- break;
- case OP_CALL:
- op->type = slang_oper_call;
- op->a_id = parse_identifier (C);
- if (op->a_id == SLANG_ATOM_NULL)
- return 0;
- while (*C->I != OP_END)
- if (!parse_child_operation (C, O, op, 0))
- return 0;
- C->I++;
- if (!C->parsing_builtin && !slang_function_scope_find_by_name (O->funs, op->a_id, 1))
- {
- const char *id;
-
- id = slang_atom_pool_id (C->atoms, op->a_id);
- if (!is_constructor_name (id, op->a_id, O->structs))
- {
- slang_info_log_error (C->L, "%s: undeclared function name.", id);
- return 0;
- }
- }
- break;
- case OP_FIELD:
- op->type = slang_oper_field;
- op->a_id = parse_identifier (C);
- if (op->a_id == SLANG_ATOM_NULL)
- return 0;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
- return 0;
- break;
- case OP_POSTINCREMENT:
- op->type = slang_oper_postincrement;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
- return 0;
- break;
- case OP_POSTDECREMENT:
- op->type = slang_oper_postdecrement;
- if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
- return 0;
- break;
- default:
- return 0;
- }
- }
- C->I++;
-
- *oper = *ops;
- slang_alloc_free (ops);
- return 1;
+ slang_operation *ops = NULL;
+ unsigned int num_ops = 0;
+ int number;
+
+ while (*C->I != OP_END) {
+ slang_operation *op;
+ const unsigned int op_code = *C->I++;
+
+ /* allocate default operation, becomes a no-op if not used */
+ ops = (slang_operation *)
+ slang_alloc_realloc(ops,
+ num_ops * sizeof(slang_operation),
+ (num_ops + 1) * sizeof(slang_operation));
+ if (ops == NULL) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ op = &ops[num_ops];
+ if (!slang_operation_construct(op)) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ num_ops++;
+ op->locals->outer_scope = O->vars;
+
+ switch (op_code) {
+ case OP_PUSH_VOID:
+ op->type = slang_oper_void;
+ break;
+ case OP_PUSH_BOOL:
+ op->type = slang_oper_literal_bool;
+ if (!parse_number(C, &number))
+ return 0;
+ op->literal = (GLfloat) number;
+ break;
+ case OP_PUSH_INT:
+ op->type = slang_oper_literal_int;
+ if (!parse_number(C, &number))
+ return 0;
+ op->literal = (GLfloat) number;
+ break;
+ case OP_PUSH_FLOAT:
+ op->type = slang_oper_literal_float;
+ if (!parse_float(C, &op->literal))
+ return 0;
+ break;
+ case OP_PUSH_IDENTIFIER:
+ op->type = slang_oper_identifier;
+ op->a_id = parse_identifier(C);
+ if (op->a_id == SLANG_ATOM_NULL)
+ return 0;
+ break;
+ case OP_SEQUENCE:
+ op->type = slang_oper_sequence;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_ASSIGN:
+ op->type = slang_oper_assign;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_ADDASSIGN:
+ op->type = slang_oper_addassign;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_SUBASSIGN:
+ op->type = slang_oper_subassign;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_MULASSIGN:
+ op->type = slang_oper_mulassign;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_DIVASSIGN:
+ op->type = slang_oper_divassign;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ /*case OP_MODASSIGN: */
+ /*case OP_LSHASSIGN: */
+ /*case OP_RSHASSIGN: */
+ /*case OP_ORASSIGN: */
+ /*case OP_XORASSIGN: */
+ /*case OP_ANDASSIGN: */
+ case OP_SELECT:
+ op->type = slang_oper_select;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 3))
+ return 0;
+ break;
+ case OP_LOGICALOR:
+ op->type = slang_oper_logicalor;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_LOGICALXOR:
+ op->type = slang_oper_logicalxor;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_LOGICALAND:
+ op->type = slang_oper_logicaland;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ /*case OP_BITOR: */
+ /*case OP_BITXOR: */
+ /*case OP_BITAND: */
+ case OP_EQUAL:
+ op->type = slang_oper_equal;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_NOTEQUAL:
+ op->type = slang_oper_notequal;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_LESS:
+ op->type = slang_oper_less;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_GREATER:
+ op->type = slang_oper_greater;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_LESSEQUAL:
+ op->type = slang_oper_lessequal;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_GREATEREQUAL:
+ op->type = slang_oper_greaterequal;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ /*case OP_LSHIFT: */
+ /*case OP_RSHIFT: */
+ case OP_ADD:
+ op->type = slang_oper_add;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_SUBTRACT:
+ op->type = slang_oper_subtract;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_MULTIPLY:
+ op->type = slang_oper_multiply;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_DIVIDE:
+ op->type = slang_oper_divide;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ /*case OP_MODULUS: */
+ case OP_PREINCREMENT:
+ op->type = slang_oper_preincrement;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+ return 0;
+ break;
+ case OP_PREDECREMENT:
+ op->type = slang_oper_predecrement;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+ return 0;
+ break;
+ case OP_PLUS:
+ op->type = slang_oper_plus;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+ return 0;
+ break;
+ case OP_MINUS:
+ op->type = slang_oper_minus;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+ return 0;
+ break;
+ case OP_NOT:
+ op->type = slang_oper_not;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+ return 0;
+ break;
+ /*case OP_COMPLEMENT: */
+ case OP_SUBSCRIPT:
+ op->type = slang_oper_subscript;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+ return 0;
+ break;
+ case OP_CALL:
+ op->type = slang_oper_call;
+ op->a_id = parse_identifier(C);
+ if (op->a_id == SLANG_ATOM_NULL)
+ return 0;
+ while (*C->I != OP_END)
+ if (!parse_child_operation(C, O, op, 0))
+ return 0;
+ C->I++;
+
+ if (!C->parsing_builtin
+ && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) {
+ const char *id;
+
+ id = slang_atom_pool_id(C->atoms, op->a_id);
+ if (!is_constructor_name(id, op->a_id, O->structs)) {
+ slang_info_log_error(C->L, "%s: undeclared function name.", id);
+ return 0;
+ }
+ }
+ break;
+ case OP_FIELD:
+ op->type = slang_oper_field;
+ op->a_id = parse_identifier(C);
+ if (op->a_id == SLANG_ATOM_NULL)
+ return 0;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+ return 0;
+ break;
+ case OP_POSTINCREMENT:
+ op->type = slang_oper_postincrement;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+ return 0;
+ break;
+ case OP_POSTDECREMENT:
+ op->type = slang_oper_postdecrement;
+ if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ }
+ C->I++;
+
+ *oper = *ops;
+ slang_alloc_free(ops);
+
+ return 1;
}
/* parameter qualifier */
@@ -1222,78 +1264,76 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper
#define PARAMETER_ARRAY_NOT_PRESENT 0
#define PARAMETER_ARRAY_PRESENT 1
-static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O,
- slang_variable *param)
+static int
+parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O,
+ slang_variable * param)
{
- /* parse and validate the parameter's type qualifiers (there can be two at most) because
- * not all combinations are valid */
- if (!parse_type_qualifier (C, &param->type.qualifier))
- return 0;
- switch (*C->I++)
- {
- case PARAM_QUALIFIER_IN:
- if (param->type.qualifier != slang_qual_const && param->type.qualifier != slang_qual_none)
- {
- slang_info_log_error (C->L, "Invalid type qualifier.");
- return 0;
- }
- break;
- case PARAM_QUALIFIER_OUT:
- if (param->type.qualifier == slang_qual_none)
- param->type.qualifier = slang_qual_out;
- else
- {
- slang_info_log_error (C->L, "Invalid type qualifier.");
- return 0;
- }
- break;
- case PARAM_QUALIFIER_INOUT:
- if (param->type.qualifier == slang_qual_none)
- param->type.qualifier = slang_qual_inout;
- else
- {
- slang_info_log_error (C->L, "Invalid type qualifier.");
- return 0;
- }
- break;
- default:
- return 0;
- }
-
- /* parse parameter's type specifier and name */
- if (!parse_type_specifier (C, O, &param->type.specifier))
- return 0;
- param->a_name = parse_identifier (C);
- if (param->a_name == SLANG_ATOM_NULL)
- return 0;
-
- /* if the parameter is an array, parse its size (the size must be explicitly defined */
- if (*C->I++ == PARAMETER_ARRAY_PRESENT)
- {
- slang_type_specifier p;
-
- slang_type_specifier_ctr (&p);
- if (!slang_type_specifier_copy (&p, &param->type.specifier))
- {
- slang_type_specifier_dtr (&p);
- return GL_FALSE;
- }
- if (!convert_to_array (C, param, &p))
- {
- slang_type_specifier_dtr (&p);
- return GL_FALSE;
- }
- slang_type_specifier_dtr (&p);
- if (!parse_array_len (C, O, &param->array_len))
- return GL_FALSE;
- }
-
- /* calculate the parameter size */
- if (!calculate_var_size (C, O, param))
- return GL_FALSE;
-
- /* TODO: allocate the local address here? */
- return 1;
+ /* parse and validate the parameter's type qualifiers (there can be
+ * two at most) because not all combinations are valid
+ */
+ if (!parse_type_qualifier(C, &param->type.qualifier))
+ return 0;
+ switch (*C->I++) {
+ case PARAM_QUALIFIER_IN:
+ if (param->type.qualifier != slang_qual_const
+ && param->type.qualifier != slang_qual_none) {
+ slang_info_log_error(C->L, "Invalid type qualifier.");
+ return 0;
+ }
+ break;
+ case PARAM_QUALIFIER_OUT:
+ if (param->type.qualifier == slang_qual_none)
+ param->type.qualifier = slang_qual_out;
+ else {
+ slang_info_log_error(C->L, "Invalid type qualifier.");
+ return 0;
+ }
+ break;
+ case PARAM_QUALIFIER_INOUT:
+ if (param->type.qualifier == slang_qual_none)
+ param->type.qualifier = slang_qual_inout;
+ else {
+ slang_info_log_error(C->L, "Invalid type qualifier.");
+ return 0;
+ }
+ break;
+ default:
+ return 0;
+ }
+
+ /* parse parameter's type specifier and name */
+ if (!parse_type_specifier(C, O, &param->type.specifier))
+ return 0;
+ param->a_name = parse_identifier(C);
+ if (param->a_name == SLANG_ATOM_NULL)
+ return 0;
+
+ /* if the parameter is an array, parse its size (the size must be
+ * explicitly defined
+ */
+ if (*C->I++ == PARAMETER_ARRAY_PRESENT) {
+ slang_type_specifier p;
+
+ slang_type_specifier_ctr(&p);
+ if (!slang_type_specifier_copy(&p, &param->type.specifier)) {
+ slang_type_specifier_dtr(&p);
+ return GL_FALSE;
+ }
+ if (!convert_to_array(C, param, &p)) {
+ slang_type_specifier_dtr(&p);
+ return GL_FALSE;
+ }
+ slang_type_specifier_dtr(&p);
+ if (!parse_array_len(C, O, &param->array_len))
+ return GL_FALSE;
+ }
+
+ /* calculate the parameter size */
+ if (!calculate_var_size(C, O, param))
+ return GL_FALSE;
+
+ /* TODO: allocate the local address here? */
+ return 1;
}
/* function type */
@@ -1336,251 +1376,247 @@ static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O,
/*#define OPERATOR_COMPLEMENT 28*/
#define OPERATOR_NOT 29
-static const struct {
- unsigned int o_code;
- const char *o_name;
+static const struct
+{
+ unsigned int o_code;
+ const char *o_name;
} operator_names[] = {
- { OPERATOR_INCREMENT, "++" },
- { OPERATOR_ADDASSIGN, "+=" },
- { OPERATOR_PLUS, "+" },
- { OPERATOR_DECREMENT, "--" },
- { OPERATOR_SUBASSIGN, "-=" },
- { OPERATOR_MINUS, "-" },
- { OPERATOR_NOT, "!" },
- { OPERATOR_MULASSIGN, "*=" },
- { OPERATOR_MULTIPLY, "*" },
- { OPERATOR_DIVASSIGN, "/=" },
- { OPERATOR_DIVIDE, "/" },
- { OPERATOR_LESSEQUAL, "<=" },
- /*{ OPERATOR_LSHASSIGN, "<<=" },*/
- /*{ OPERATOR_LSHIFT, "<<" },*/
- { OPERATOR_LESS, "<" },
- { OPERATOR_GREATEREQUAL, ">=" },
- /*{ OPERATOR_RSHASSIGN, ">>=" },*/
- /*{ OPERATOR_RSHIFT, ">>" },*/
- { OPERATOR_GREATER, ">" },
- /*{ OPERATOR_MODASSIGN, "%=" },*/
- /*{ OPERATOR_MODULUS, "%" },*/
- /*{ OPERATOR_ANDASSIGN, "&=" },*/
- /*{ OPERATOR_BITAND, "&" },*/
- /*{ OPERATOR_ORASSIGN, "|=" },*/
- /*{ OPERATOR_BITOR, "|" },*/
- /*{ OPERATOR_COMPLEMENT, "~" },*/
- /*{ OPERATOR_XORASSIGN, "^=" },*/
- { OPERATOR_LOGICALXOR, "^^" },
- /*{ OPERATOR_BITXOR, "^" }*/
+ {OPERATOR_INCREMENT, "++"},
+ {OPERATOR_ADDASSIGN, "+="},
+ {OPERATOR_PLUS, "+"},
+ {OPERATOR_DECREMENT, "--"},
+ {OPERATOR_SUBASSIGN, "-="},
+ {OPERATOR_MINUS, "-"},
+ {OPERATOR_NOT, "!"},
+ {OPERATOR_MULASSIGN, "*="},
+ {OPERATOR_MULTIPLY, "*"},
+ {OPERATOR_DIVASSIGN, "/="},
+ {OPERATOR_DIVIDE, "/"},
+ {OPERATOR_LESSEQUAL, "<="},
+ /*{ OPERATOR_LSHASSIGN, "<<=" }, */
+ /*{ OPERATOR_LSHIFT, "<<" }, */
+ {OPERATOR_LESS, "<"},
+ {OPERATOR_GREATEREQUAL, ">="},
+ /*{ OPERATOR_RSHASSIGN, ">>=" }, */
+ /*{ OPERATOR_RSHIFT, ">>" }, */
+ {OPERATOR_GREATER, ">"},
+ /*{ OPERATOR_MODASSIGN, "%=" }, */
+ /*{ OPERATOR_MODULUS, "%" }, */
+ /*{ OPERATOR_ANDASSIGN, "&=" }, */
+ /*{ OPERATOR_BITAND, "&" }, */
+ /*{ OPERATOR_ORASSIGN, "|=" }, */
+ /*{ OPERATOR_BITOR, "|" }, */
+ /*{ OPERATOR_COMPLEMENT, "~" }, */
+ /*{ OPERATOR_XORASSIGN, "^=" }, */
+ {OPERATOR_LOGICALXOR, "^^"},
+ /*{ OPERATOR_BITXOR, "^" } */
};
-static slang_atom parse_operator_name (slang_parse_ctx *C)
+static slang_atom
+parse_operator_name(slang_parse_ctx * C)
{
- unsigned int i;
-
- for (i = 0; i < sizeof (operator_names) / sizeof (*operator_names); i++)
- {
- if (operator_names[i].o_code == (unsigned int) (*C->I))
- {
- slang_atom atom = slang_atom_pool_atom (C->atoms, operator_names[i].o_name);
- if (atom == SLANG_ATOM_NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- C->I++;
- return atom;
- }
- }
- return 0;
+ unsigned int i;
+
+ for (i = 0; i < sizeof(operator_names) / sizeof(*operator_names); i++) {
+ if (operator_names[i].o_code == (unsigned int) (*C->I)) {
+ slang_atom atom =
+ slang_atom_pool_atom(C->atoms, operator_names[i].o_name);
+ if (atom == SLANG_ATOM_NULL) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ C->I++;
+ return atom;
+ }
+ }
+ return 0;
}
-static int parse_function_prototype (slang_parse_ctx *C, slang_output_ctx *O, slang_function *func)
+static int
+parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,
+ slang_function * func)
{
- /* parse function type and name */
- if (!parse_fully_specified_type (C, O, &func->header.type))
- return 0;
- switch (*C->I++)
- {
- case FUNCTION_ORDINARY:
- func->kind = slang_func_ordinary;
- func->header.a_name = parse_identifier (C);
- if (func->header.a_name == SLANG_ATOM_NULL)
- return 0;
- break;
- case FUNCTION_CONSTRUCTOR:
- func->kind = slang_func_constructor;
- if (func->header.type.specifier.type == slang_spec_struct)
- return 0;
- func->header.a_name = slang_atom_pool_atom (C->atoms,
- slang_type_specifier_type_to_string (func->header.type.specifier.type));
- if (func->header.a_name == SLANG_ATOM_NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- break;
- case FUNCTION_OPERATOR:
- func->kind = slang_func_operator;
- func->header.a_name = parse_operator_name (C);
- if (func->header.a_name == SLANG_ATOM_NULL)
- return 0;
- break;
- default:
- return 0;
- }
-
- /* parse function parameters */
- while (*C->I++ == PARAMETER_NEXT)
- {
- slang_variable *p;
-
- func->parameters->variables = (slang_variable *) slang_alloc_realloc (
- func->parameters->variables,
- func->parameters->num_variables * sizeof (slang_variable),
- (func->parameters->num_variables + 1) * sizeof (slang_variable));
- if (func->parameters->variables == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- p = &func->parameters->variables[func->parameters->num_variables];
- if (!slang_variable_construct (p))
- return 0;
- func->parameters->num_variables++;
- if (!parse_parameter_declaration (C, O, p))
- return 0;
- }
-
- /* function formal parameters and local variables share the same scope, so save
- * the information about param count in a seperate place
- * also link the scope to the global variable scope so when a given identifier is not
- * found here, the search process continues in the global space */
- func->param_count = func->parameters->num_variables;
- func->parameters->outer_scope = O->vars;
- return 1;
+ /* parse function type and name */
+ if (!parse_fully_specified_type(C, O, &func->header.type))
+ return 0;
+ switch (*C->I++) {
+ case FUNCTION_ORDINARY:
+ func->kind = slang_func_ordinary;
+ func->header.a_name = parse_identifier(C);
+ if (func->header.a_name == SLANG_ATOM_NULL)
+ return 0;
+ break;
+ case FUNCTION_CONSTRUCTOR:
+ func->kind = slang_func_constructor;
+ if (func->header.type.specifier.type == slang_spec_struct)
+ return 0;
+ func->header.a_name =
+ slang_atom_pool_atom(C->atoms,
+ slang_type_specifier_type_to_string
+ (func->header.type.specifier.type));
+ if (func->header.a_name == SLANG_ATOM_NULL) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ break;
+ case FUNCTION_OPERATOR:
+ func->kind = slang_func_operator;
+ func->header.a_name = parse_operator_name(C);
+ if (func->header.a_name == SLANG_ATOM_NULL)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+
+ /* parse function parameters */
+ while (*C->I++ == PARAMETER_NEXT) {
+ slang_variable *p = slang_variable_scope_grow(func->parameters);
+ if (!p) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ if (!parse_parameter_declaration(C, O, p))
+ return 0;
+ }
+
+ /* function formal parameters and local variables share the same
+ * scope, so save the information about param count in a seperate
+ * place also link the scope to the global variable scope so when a
+ * given identifier is not found here, the search process continues
+ * in the global space
+ */
+ func->param_count = func->parameters->num_variables;
+ func->parameters->outer_scope = O->vars;
+ return 1;
}
-static int parse_function_definition (slang_parse_ctx *C, slang_output_ctx *O, slang_function *func)
+static int
+parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O,
+ slang_function * func)
{
- slang_output_ctx o = *O;
-
- if (!parse_function_prototype (C, O, func))
- return 0;
-
- /* create function's body operation */
- func->body = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
- if (func->body == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- if (!slang_operation_construct (func->body))
- {
- slang_alloc_free (func->body);
- func->body = NULL;
- slang_info_log_memory (C->L);
- return 0;
- }
-
- /* to parse the body the parse context is modified in order to capture parsed variables
- * into function's local variable scope */
- C->global_scope = 0;
- o.vars = func->parameters;
- if (!parse_statement (C, &o, func->body))
- return 0;
- C->global_scope = 1;
- return 1;
+ slang_output_ctx o = *O;
+
+ if (!parse_function_prototype(C, O, func))
+ return 0;
+
+ /* create function's body operation */
+ func->body =
+ (slang_operation *) slang_alloc_malloc(sizeof(slang_operation));
+ if (func->body == NULL) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ if (!slang_operation_construct(func->body)) {
+ slang_alloc_free(func->body);
+ func->body = NULL;
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+
+ /* to parse the body the parse context is modified in order to
+ * capture parsed variables into function's local variable scope
+ */
+ C->global_scope = GL_FALSE;
+ o.vars = func->parameters;
+ if (!parse_statement(C, &o, func->body))
+ return 0;
+
+ C->global_scope = GL_TRUE;
+ return 1;
}
-static GLboolean initialize_global (slang_assemble_ctx *A, slang_variable *var)
+static GLboolean
+initialize_global(slang_assemble_ctx * A, slang_variable * var)
{
- slang_assembly_file_restore_point point;
- slang_machine mach;
- slang_assembly_local_info save_local = A->local;
- slang_operation op_id, op_assign;
- GLboolean result;
-
- /* save the current assembly */
- if (!slang_assembly_file_restore_point_save (A->file, &point))
- return GL_FALSE;
-
- /* setup the machine */
- mach = *A->mach;
- mach.ip = A->file->count;
-
- /* allocate local storage for expression */
- A->local.ret_size = 0;
- A->local.addr_tmp = 0;
- A->local.swizzle_tmp = 4;
- if (!slang_assembly_file_push_label (A->file, slang_asm_local_alloc, 20))
- return GL_FALSE;
- if (!slang_assembly_file_push_label (A->file, slang_asm_enter, 20))
- return GL_FALSE;
-
- /* construct the left side of assignment */
- if (!slang_operation_construct (&op_id))
- return GL_FALSE;
- op_id.type = slang_oper_identifier;
- op_id.a_id = var->a_name;
-
- /* put the variable into operation's scope */
- op_id.locals->variables = (slang_variable *) slang_alloc_malloc (sizeof (slang_variable));
- if (op_id.locals->variables == NULL)
- {
- slang_operation_destruct (&op_id);
- return GL_FALSE;
- }
- op_id.locals->num_variables = 1;
- op_id.locals->variables[0] = *var;
-
- /* construct the assignment expression */
- if (!slang_operation_construct (&op_assign))
- {
- op_id.locals->num_variables = 0;
- slang_operation_destruct (&op_id);
- return GL_FALSE;
- }
- op_assign.type = slang_oper_assign;
- op_assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));
- if (op_assign.children == NULL)
- {
- slang_operation_destruct (&op_assign);
- op_id.locals->num_variables = 0;
- slang_operation_destruct (&op_id);
- return GL_FALSE;
- }
- op_assign.num_children = 2;
- op_assign.children[0] = op_id;
- op_assign.children[1] = *var->initializer;
-
- /* insert the actual expression */
- result = _slang_assemble_operation (A, &op_assign, slang_ref_forbid);
-
- /* carefully destroy the operations */
- op_assign.num_children = 0;
- slang_alloc_free (op_assign.children);
- op_assign.children = NULL;
- slang_operation_destruct (&op_assign);
- op_id.locals->num_variables = 0;
- slang_operation_destruct (&op_id);
-
- if (!result)
- return GL_FALSE;
- if (!slang_assembly_file_push (A->file, slang_asm_exit))
- return GL_FALSE;
-
- /* execute the expression */
- if (!_slang_execute2 (A->file, &mach))
- return GL_FALSE;
-
- /* restore the old assembly */
- if (!slang_assembly_file_restore_point_load (A->file, &point))
- return GL_FALSE;
- A->local = save_local;
-
- /* now we copy the contents of the initialized variable back to the original machine */
- _mesa_memcpy ((GLubyte *) A->mach->mem + var->address, (GLubyte *) mach.mem + var->address,
- var->size);
-
- return GL_TRUE;
+ slang_assembly_file_restore_point point;
+ slang_machine mach;
+ slang_assembly_local_info save_local = A->local;
+ slang_operation op_id, op_assign;
+ GLboolean result;
+
+ /* save the current assembly */
+ if (!slang_assembly_file_restore_point_save(A->file, &point))
+ return GL_FALSE;
+
+ /* setup the machine */
+ mach = *A->mach;
+ mach.ip = A->file->count;
+
+ /* allocate local storage for expression */
+ A->local.ret_size = 0;
+ A->local.addr_tmp = 0;
+ A->local.swizzle_tmp = 4;
+ if (!slang_assembly_file_push_label(A->file, slang_asm_local_alloc, 20))
+ return GL_FALSE;
+ if (!slang_assembly_file_push_label(A->file, slang_asm_enter, 20))
+ return GL_FALSE;
+
+ /* construct the left side of assignment */
+ if (!slang_operation_construct(&op_id))
+ return GL_FALSE;
+ op_id.type = slang_oper_identifier;
+ op_id.a_id = var->a_name;
+
+ /* put the variable into operation's scope */
+ op_id.locals->variables =
+ (slang_variable *) slang_alloc_malloc(sizeof(slang_variable));
+ if (op_id.locals->variables == NULL) {
+ slang_operation_destruct(&op_id);
+ return GL_FALSE;
+ }
+ op_id.locals->num_variables = 1;
+ op_id.locals->variables[0] = *var;
+
+ /* construct the assignment expression */
+ if (!slang_operation_construct(&op_assign)) {
+ op_id.locals->num_variables = 0;
+ slang_operation_destruct(&op_id);
+ return GL_FALSE;
+ }
+ op_assign.type = slang_oper_assign;
+ op_assign.children =
+ (slang_operation *) slang_alloc_malloc(2 * sizeof(slang_operation));
+ if (op_assign.children == NULL) {
+ slang_operation_destruct(&op_assign);
+ op_id.locals->num_variables = 0;
+ slang_operation_destruct(&op_id);
+ return GL_FALSE;
+ }
+ op_assign.num_children = 2;
+ op_assign.children[0] = op_id;
+ op_assign.children[1] = *var->initializer;
+
+ /* insert the actual expression */
+ result = _slang_assemble_operation(A, &op_assign, slang_ref_forbid);
+
+ /* carefully destroy the operations */
+ op_assign.num_children = 0;
+ slang_alloc_free(op_assign.children);
+ op_assign.children = NULL;
+ slang_operation_destruct(&op_assign);
+ op_id.locals->num_variables = 0;
+ slang_operation_destruct(&op_id);
+
+ if (!result)
+ return GL_FALSE;
+ if (!slang_assembly_file_push(A->file, slang_asm_exit))
+ return GL_FALSE;
+
+ /* execute the expression */
+ if (!_slang_execute2(A->file, &mach))
+ return GL_FALSE;
+
+ /* restore the old assembly */
+ if (!slang_assembly_file_restore_point_load(A->file, &point))
+ return GL_FALSE;
+ A->local = save_local;
+
+ /* now we copy the contents of the initialized variable back to the original machine */
+ _mesa_memcpy((GLubyte *) A->mach->mem + var->address,
+ (GLubyte *) mach.mem + var->address, var->size);
+
+ return GL_TRUE;
}
/* init declarator list */
@@ -1594,89 +1630,88 @@ static GLboolean initialize_global (slang_assemble_ctx *A, slang_variable *var)
#define VARIABLE_ARRAY_EXPLICIT 3
#define VARIABLE_ARRAY_UNKNOWN 4
-static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
- const slang_fully_specified_type *type)
+
+/**
+ * Parse the initializer for a variable declaration.
+ */
+static int
+parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
+ const slang_fully_specified_type * type)
{
- slang_variable *var;
-
- /* empty init declatator (without name, e.g. "float ;") */
- if (*C->I++ == VARIABLE_NONE)
- return 1;
-
- /* make room for the new variable and initialize it */
- O->vars->variables = (slang_variable *) slang_alloc_realloc (O->vars->variables,
- O->vars->num_variables * sizeof (slang_variable),
- (O->vars->num_variables + 1) * sizeof (slang_variable));
- if (O->vars->variables == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- var = &O->vars->variables[O->vars->num_variables];
- if (!slang_variable_construct (var))
- return 0;
- O->vars->num_variables++;
-
- /* copy the declarator qualifier type, parse the identifier */
- var->global = C->global_scope;
- var->type.qualifier = type->qualifier;
- var->a_name = parse_identifier (C);
- if (var->a_name == SLANG_ATOM_NULL)
- return 0;
-
- switch (*C->I++)
- {
- case VARIABLE_NONE:
- /* simple variable declarator - just copy the specifier */
- if (!slang_type_specifier_copy (&var->type.specifier, &type->specifier))
- return 0;
- break;
- case VARIABLE_INITIALIZER:
- /* initialized variable - copy the specifier and parse the expression */
- if (!slang_type_specifier_copy (&var->type.specifier, &type->specifier))
- return 0;
- var->initializer = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
- if (var->initializer == NULL)
- {
- slang_info_log_memory (C->L);
- return 0;
- }
- if (!slang_operation_construct (var->initializer))
- {
- slang_alloc_free (var->initializer);
- var->initializer = NULL;
- slang_info_log_memory (C->L);
- return 0;
- }
- if (!parse_expression (C, O, var->initializer))
- return 0;
- break;
+ slang_variable *var;
+
+ /* empty init declatator (without name, e.g. "float ;") */
+ if (*C->I++ == VARIABLE_NONE)
+ return 1;
+
+ /* make room for the new variable and initialize it */
+ var = slang_variable_scope_grow(O->vars);
+ if (!var) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+
+ /* copy the declarator qualifier type, parse the identifier */
+ var->global = C->global_scope;
+ var->type.qualifier = type->qualifier;
+ var->a_name = parse_identifier(C);
+ if (var->a_name == SLANG_ATOM_NULL)
+ return 0;
+
+ switch (*C->I++) {
+ case VARIABLE_NONE:
+ /* simple variable declarator - just copy the specifier */
+ if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
+ return 0;
+ break;
+ case VARIABLE_INITIALIZER:
+ /* initialized variable - copy the specifier and parse the expression */
+ if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
+ return 0;
+ var->initializer =
+ (slang_operation *) slang_alloc_malloc(sizeof(slang_operation));
+ if (var->initializer == NULL) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ if (!slang_operation_construct(var->initializer)) {
+ slang_alloc_free(var->initializer);
+ var->initializer = NULL;
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ if (!parse_expression(C, O, var->initializer))
+ return 0;
+ break;
#if 0
- case VARIABLE_ARRAY_UNKNOWN:
- /* unsized array - mark it as array and copy the specifier to the array element */
- if (!convert_to_array (C, var, &type->specifier))
- return GL_FALSE;
- break;
+ case VARIABLE_ARRAY_UNKNOWN:
+ /* unsized array - mark it as array and copy the specifier to
+ the array element
+ */
+ if (!convert_to_array(C, var, &type->specifier))
+ return GL_FALSE;
+ break;
#endif
- case VARIABLE_ARRAY_EXPLICIT:
- if (!convert_to_array (C, var, &type->specifier))
- return GL_FALSE;
- if (!parse_array_len (C, O, &var->array_len))
- return GL_FALSE;
- break;
- default:
- return 0;
- }
-
- /* allocate global address space for a variable with a known size */
- if (C->global_scope && !(var->type.specifier.type == slang_spec_array && var->array_len == 0))
- {
- if (!calculate_var_size (C, O, var))
- return GL_FALSE;
- var->address = slang_var_pool_alloc (O->global_pool, var->size);
- }
-
- /* initialize global variable */
+ case VARIABLE_ARRAY_EXPLICIT:
+ if (!convert_to_array(C, var, &type->specifier))
+ return GL_FALSE;
+ if (!parse_array_len(C, O, &var->array_len))
+ return GL_FALSE;
+ break;
+ default:
+ return 0;
+ }
+
+ /* allocate global address space for a variable with a known size */
+ if (C->global_scope
+ && !(var->type.specifier.type == slang_spec_array
+ && var->array_len == 0)) {
+ if (!calculate_var_size(C, O, var))
+ return GL_FALSE;
+ var->address = slang_var_pool_alloc(O->global_pool, var->size);
+ }
+
+ /* initialize global variable */
if (C->global_scope) {
if (var->initializer != NULL) {
slang_assemble_ctx A;
@@ -1687,160 +1722,171 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
A.space.funcs = O->funs;
A.space.structs = O->structs;
A.space.vars = O->vars;
- if (!initialize_global (&A, var))
+ if (!initialize_global(&A, var))
return 0;
}
else {
- _mesa_memset ((GLubyte *) (O->machine->mem) + var->address, 0, var->size);
+ _mesa_memset((GLubyte *) (O->machine->mem) + var->address, 0,
+ var->size);
}
- }
- return 1;
+ }
+ return 1;
}
-static int parse_init_declarator_list (slang_parse_ctx *C, slang_output_ctx *O)
+/**
+ * Parse a list of variable declarations. Each variable may have an
+ * initializer.
+ */
+static int
+parse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O)
{
- slang_fully_specified_type type;
-
- /* parse the fully specified type, common to all declarators */
- if (!slang_fully_specified_type_construct (&type))
- return 0;
- if (!parse_fully_specified_type (C, O, &type))
- {
- slang_fully_specified_type_destruct (&type);
- return 0;
- }
-
- /* parse declarators, pass-in the parsed type */
- do
- {
- if (!parse_init_declarator (C, O, &type))
- {
- slang_fully_specified_type_destruct (&type);
- return 0;
- }
- }
- while (*C->I++ == DECLARATOR_NEXT);
-
- slang_fully_specified_type_destruct (&type);
- return 1;
+ slang_fully_specified_type type;
+
+ /* parse the fully specified type, common to all declarators */
+ if (!slang_fully_specified_type_construct(&type))
+ return 0;
+ if (!parse_fully_specified_type(C, O, &type)) {
+ slang_fully_specified_type_destruct(&type);
+ return 0;
+ }
+
+ /* parse declarators, pass-in the parsed type */
+ do {
+ if (!parse_init_declarator(C, O, &type)) {
+ slang_fully_specified_type_destruct(&type);
+ return 0;
+ }
+ }
+ while (*C->I++ == DECLARATOR_NEXT);
+
+ slang_fully_specified_type_destruct(&type);
+ return 1;
}
-static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definition,
- slang_function **parsed_func_ret)
+
+/**
+ * Parse a function definition or declaration.
+ * \param C parsing context
+ * \param O output context
+ * \param definition if non-zero expect a definition, else a declaration
+ * \param parsed_func_ret returns the parsed function
+ * \return 1 if success, 0 if failure
+ */
+static int
+parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
+ slang_function ** parsed_func_ret)
{
- slang_function parsed_func, *found_func;
-
- /* parse function definition/declaration */
- if (!slang_function_construct (&parsed_func))
- return 0;
- if (definition)
- {
- if (!parse_function_definition (C, O, &parsed_func))
- {
- slang_function_destruct (&parsed_func);
- return 0;
- }
- }
- else
- {
- if (!parse_function_prototype (C, O, &parsed_func))
- {
- slang_function_destruct (&parsed_func);
- return 0;
- }
- }
-
- /* find a function with a prototype matching the parsed one - only the current scope
- * is being searched to allow built-in function overriding */
- found_func = slang_function_scope_find (O->funs, &parsed_func, 0);
- if (found_func == NULL)
- {
- /* add the parsed function to the function list */
- O->funs->functions = (slang_function *) slang_alloc_realloc (O->funs->functions,
- O->funs->num_functions * sizeof (slang_function),
- (O->funs->num_functions + 1) * sizeof (slang_function));
- if (O->funs->functions == NULL)
- {
- slang_info_log_memory (C->L);
- slang_function_destruct (&parsed_func);
- return 0;
- }
- O->funs->functions[O->funs->num_functions] = parsed_func;
- O->funs->num_functions++;
-
- /* return the newly parsed function */
- *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];
- }
- else
- {
- /* TODO: check function return type qualifiers and specifiers */
- if (definition)
- {
- if (found_func->body != NULL)
- {
- slang_info_log_error (C->L, "%s: function already has a body.",
- slang_atom_pool_id (C->atoms, parsed_func.header.a_name));
- slang_function_destruct (&parsed_func);
- return 0;
- }
-
- /* destroy the existing function declaration and replace it with the new one,
- * remember to save the fixup table */
- parsed_func.fixups = found_func->fixups;
- slang_fixup_table_init (&found_func->fixups);
- slang_function_destruct (found_func);
- *found_func = parsed_func;
- }
- else
- {
- /* another declaration of the same function prototype - ignore it */
- slang_function_destruct (&parsed_func);
- }
-
- /* return the found function */
- *parsed_func_ret = found_func;
- }
-
- /* assemble the parsed function */
- {
- slang_assemble_ctx A;
-
- A.file = O->assembly;
- A.mach = O->machine;
- A.atoms = C->atoms;
- A.space.funcs = O->funs;
- A.space.structs = O->structs;
- A.space.vars = O->vars;
- if (!_slang_assemble_function (&A, *parsed_func_ret))
- return 0;
- }
- return 1;
+ slang_function parsed_func, *found_func;
+
+ /* parse function definition/declaration */
+ if (!slang_function_construct(&parsed_func))
+ return 0;
+ if (definition) {
+ if (!parse_function_definition(C, O, &parsed_func)) {
+ slang_function_destruct(&parsed_func);
+ return 0;
+ }
+ }
+ else {
+ if (!parse_function_prototype(C, O, &parsed_func)) {
+ slang_function_destruct(&parsed_func);
+ return 0;
+ }
+ }
+
+ /* find a function with a prototype matching the parsed one - only
+ * the current scope is being searched to allow built-in function
+ * overriding
+ */
+ found_func = slang_function_scope_find(O->funs, &parsed_func, 0);
+ if (found_func == NULL) {
+ /* add the parsed function to the function list */
+ O->funs->functions =
+ (slang_function *) slang_alloc_realloc(O->funs->functions,
+ O->funs->num_functions *
+ sizeof(slang_function),
+ (O->funs->num_functions +
+ 1) * sizeof(slang_function));
+ if (O->funs->functions == NULL) {
+ slang_info_log_memory(C->L);
+ slang_function_destruct(&parsed_func);
+ return 0;
+ }
+ O->funs->functions[O->funs->num_functions] = parsed_func;
+ O->funs->num_functions++;
+
+ /* return the newly parsed function */
+ *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];
+ }
+ else {
+ /* TODO: check function return type qualifiers and specifiers */
+ if (definition) {
+ if (found_func->body != NULL) {
+ slang_info_log_error(C->L, "%s: function already has a body.",
+ slang_atom_pool_id(C->atoms,
+ parsed_func.header.
+ a_name));
+ slang_function_destruct(&parsed_func);
+ return 0;
+ }
+
+ /* destroy the existing function declaration and replace it
+ * with the new one, remember to save the fixup table
+ */
+ parsed_func.fixups = found_func->fixups;
+ slang_fixup_table_init(&found_func->fixups);
+ slang_function_destruct(found_func);
+ *found_func = parsed_func;
+ }
+ else {
+ /* another declaration of the same function prototype - ignore it */
+ slang_function_destruct(&parsed_func);
+ }
+
+ /* return the found function */
+ *parsed_func_ret = found_func;
+ }
+
+ /* assemble the parsed function */
+ {
+ slang_assemble_ctx A;
+
+ A.file = O->assembly;
+ A.mach = O->machine;
+ A.atoms = C->atoms;
+ A.space.funcs = O->funs;
+ A.space.structs = O->structs;
+ A.space.vars = O->vars;
+ if (!_slang_assemble_function(&A, *parsed_func_ret))
+ return 0;
+ }
+ return 1;
}
/* declaration */
#define DECLARATION_FUNCTION_PROTOTYPE 1
#define DECLARATION_INIT_DECLARATOR_LIST 2
-static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O)
+static int
+parse_declaration(slang_parse_ctx * C, slang_output_ctx * O)
{
- switch (*C->I++)
- {
- case DECLARATION_INIT_DECLARATOR_LIST:
- if (!parse_init_declarator_list (C, O))
- return 0;
- break;
- case DECLARATION_FUNCTION_PROTOTYPE:
- {
- slang_function *dummy_func;
-
- if (!parse_function (C, O, 0, &dummy_func))
- return 0;
- }
- break;
- default:
- return 0;
- }
- return 1;
+ switch (*C->I++) {
+ case DECLARATION_INIT_DECLARATOR_LIST:
+ if (!parse_init_declarator_list(C, O))
+ return 0;
+ break;
+ case DECLARATION_FUNCTION_PROTOTYPE:
+ {
+ slang_function *dummy_func;
+
+ if (!parse_function(C, O, 0, &dummy_func))
+ return 0;
+ }
+ break;
+ default:
+ return 0;
+ }
+ return 1;
}
/* external declaration */
@@ -1849,9 +1895,9 @@ static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O)
#define EXTERNAL_DECLARATION 2
static GLboolean
-parse_code_unit (slang_parse_ctx *C, slang_code_unit *unit)
+parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit)
{
- slang_output_ctx o;
+ slang_output_ctx o;
/* setup output context */
o.funs = &unit->funs;
@@ -1861,34 +1907,33 @@ parse_code_unit (slang_parse_ctx *C, slang_code_unit *unit)
o.global_pool = &unit->object->varpool;
o.machine = &unit->object->machine;
- /* parse individual functions and declarations */
- while (*C->I != EXTERNAL_NULL)
- {
- switch (*C->I++)
- {
- case EXTERNAL_FUNCTION_DEFINITION:
- {
- slang_function *func;
-
- if (!parse_function (C, &o, 1, &func))
- return 0;
- }
- break;
- case EXTERNAL_DECLARATION:
- if (!parse_declaration (C, &o))
- return 0;
- break;
- default:
- return 0;
- }
- }
- C->I++;
- return 1;
+ /* parse individual functions and declarations */
+ while (*C->I != EXTERNAL_NULL) {
+ switch (*C->I++) {
+ case EXTERNAL_FUNCTION_DEFINITION:
+ {
+ slang_function *func;
+
+ if (!parse_function(C, &o, 1, &func))
+ return 0;
+ }
+ break;
+ case EXTERNAL_DECLARATION:
+ if (!parse_declaration(C, &o))
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ }
+ C->I++;
+ return 1;
}
static GLboolean
-compile_binary (const byte *prod, slang_code_unit *unit, slang_unit_type type,
- slang_info_log *infolog, slang_code_unit *builtin, slang_code_unit *downlink)
+compile_binary(const byte * prod, slang_code_unit * unit,
+ slang_unit_type type, slang_info_log * infolog,
+ slang_code_unit * builtin, slang_code_unit * downlink)
{
slang_parse_ctx C;
@@ -1901,7 +1946,7 @@ compile_binary (const byte *prod, slang_code_unit *unit, slang_unit_type type,
C.global_scope = GL_TRUE;
C.atoms = &unit->object->atompool;
- if (!check_revision (&C))
+ if (!check_revision(&C))
return GL_FALSE;
if (downlink != NULL) {
@@ -1911,58 +1956,64 @@ compile_binary (const byte *prod, slang_code_unit *unit, slang_unit_type type,
}
/* parse translation unit */
- return parse_code_unit (&C, unit);
+ return parse_code_unit(&C, unit);
}
static GLboolean
-compile_with_grammar (grammar id, const char *source, slang_code_unit *unit, slang_unit_type type,
- slang_info_log *infolog, slang_code_unit *builtin)
+compile_with_grammar(grammar id, const char *source, slang_code_unit * unit,
+ slang_unit_type type, slang_info_log * infolog,
+ slang_code_unit * builtin)
{
byte *prod;
GLuint size, start, version;
slang_string preprocessed;
/* First retrieve the version number. */
- if (!_slang_preprocess_version (source, &version, &start, infolog))
+ if (!_slang_preprocess_version(source, &version, &start, infolog))
return GL_FALSE;
if (version > 110) {
- slang_info_log_error (infolog, "language version specified is not supported.");
+ slang_info_log_error(infolog,
+ "language version specified is not supported.");
return GL_FALSE;
}
/* Now preprocess the source string. */
- slang_string_init (&preprocessed);
- if (!_slang_preprocess_directives (&preprocessed, &source[start], infolog)) {
- slang_string_free (&preprocessed);
- slang_info_log_error (infolog, "failed to preprocess the source.");
+ slang_string_init(&preprocessed);
+ if (!_slang_preprocess_directives(&preprocessed, &source[start], infolog)) {
+ slang_string_free(&preprocessed);
+ slang_info_log_error(infolog, "failed to preprocess the source.");
return GL_FALSE;
}
/* Finally check the syntax and generate its binary representation. */
- if (!grammar_fast_check (id, (const byte *) (slang_string_cstr (&preprocessed)), &prod, &size, 65536)) {
+ if (!grammar_fast_check
+ (id, (const byte *) (slang_string_cstr(&preprocessed)), &prod, &size,
+ 65536)) {
char buf[1024];
GLint pos;
- slang_string_free (&preprocessed);
- grammar_get_last_error ((byte *) (buf), sizeof (buf), &pos);
- slang_info_log_error (infolog, buf);
+ slang_string_free(&preprocessed);
+ grammar_get_last_error((byte *) (buf), sizeof(buf), &pos);
+ slang_info_log_error(infolog, buf);
return GL_FALSE;
}
- slang_string_free (&preprocessed);
+ slang_string_free(&preprocessed);
/* Syntax is okay - translate it to internal representation. */
- if (!compile_binary (prod, unit, type, infolog, builtin, &builtin[SLANG_BUILTIN_TOTAL - 1])) {
- grammar_alloc_free (prod);
+ if (!compile_binary
+ (prod, unit, type, infolog, builtin,
+ &builtin[SLANG_BUILTIN_TOTAL - 1])) {
+ grammar_alloc_free(prod);
return GL_FALSE;
}
- grammar_alloc_free (prod);
+ grammar_alloc_free(prod);
return GL_TRUE;
}
-static const char *slang_shader_syn =
+LONGSTRING static const char *slang_shader_syn =
#include "library/slang_shader_syn.h"
-;
+ ;
static const byte slang_core_gc[] = {
#include "library/slang_core_gc.h"
@@ -1987,106 +2038,111 @@ static const byte slang_builtin_vec4_gc[] = {
#endif
static GLboolean
-compile_object (grammar *id, const char *source, slang_code_object *object, slang_unit_type type,
- slang_info_log *infolog)
+compile_object(grammar * id, const char *source, slang_code_object * object,
+ slang_unit_type type, slang_info_log * infolog)
{
slang_code_unit *builtins = NULL;
/* load GLSL grammar */
- *id = grammar_load_from_text ((const byte *) (slang_shader_syn));
- if (*id == 0)
- {
- byte buf[1024];
- int pos;
-
- grammar_get_last_error (buf, 1024, &pos);
- slang_info_log_error (infolog, (const char *) (buf));
+ *id = grammar_load_from_text((const byte *) (slang_shader_syn));
+ if (*id == 0) {
+ byte buf[1024];
+ int pos;
+
+ grammar_get_last_error(buf, 1024, &pos);
+ slang_info_log_error(infolog, (const char *) (buf));
return GL_FALSE;
- }
-
- /* set shader type - the syntax is slightly different for different shaders */
- if (type == slang_unit_fragment_shader || type == slang_unit_fragment_builtin)
- grammar_set_reg8 (*id, (const byte *) "shader_type", 1);
- else
- grammar_set_reg8 (*id, (const byte *) "shader_type", 2);
-
- /* enable language extensions */
- grammar_set_reg8 (*id, (const byte *) "parsing_builtin", 1);
-
- /* if parsing user-specified shader, load built-in library */
- if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader)
- {
- /* compile core functionality first */
- if (!compile_binary (slang_core_gc, &object->builtin[SLANG_BUILTIN_CORE],
- slang_unit_fragment_builtin, infolog, NULL, NULL))
+ }
+
+ /* set shader type - the syntax is slightly different for different shaders */
+ if (type == slang_unit_fragment_shader
+ || type == slang_unit_fragment_builtin)
+ grammar_set_reg8(*id, (const byte *) "shader_type", 1);
+ else
+ grammar_set_reg8(*id, (const byte *) "shader_type", 2);
+
+ /* enable language extensions */
+ grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1);
+
+ /* if parsing user-specified shader, load built-in library */
+ if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader) {
+ /* compile core functionality first */
+ if (!compile_binary(slang_core_gc, &object->builtin[SLANG_BUILTIN_CORE],
+ slang_unit_fragment_builtin, infolog, NULL, NULL))
return GL_FALSE;
- /* compile common functions and variables, link to core */
- if (!compile_binary (slang_common_builtin_gc, &object->builtin[SLANG_BUILTIN_COMMON],
- slang_unit_fragment_builtin, infolog, NULL,
- &object->builtin[SLANG_BUILTIN_CORE]))
+ /* compile common functions and variables, link to core */
+ if (!compile_binary
+ (slang_common_builtin_gc, &object->builtin[SLANG_BUILTIN_COMMON],
+ slang_unit_fragment_builtin, infolog, NULL,
+ &object->builtin[SLANG_BUILTIN_CORE]))
return GL_FALSE;
- /* compile target-specific functions and variables, link to common */
- if (type == slang_unit_fragment_shader)
- {
- if (!compile_binary (slang_fragment_builtin_gc, &object->builtin[SLANG_BUILTIN_TARGET],
- slang_unit_fragment_builtin, infolog, NULL,
- &object->builtin[SLANG_BUILTIN_COMMON]))
+ /* compile target-specific functions and variables, link to common */
+ if (type == slang_unit_fragment_shader) {
+ if (!compile_binary
+ (slang_fragment_builtin_gc,
+ &object->builtin[SLANG_BUILTIN_TARGET],
+ slang_unit_fragment_builtin, infolog, NULL,
+ &object->builtin[SLANG_BUILTIN_COMMON]))
return GL_FALSE;
- }
- else if (type == slang_unit_vertex_shader)
- {
- if (!compile_binary (slang_vertex_builtin_gc, &object->builtin[SLANG_BUILTIN_TARGET],
- slang_unit_vertex_builtin, infolog, NULL,
- &object->builtin[SLANG_BUILTIN_COMMON]))
+ }
+ else if (type == slang_unit_vertex_shader) {
+ if (!compile_binary
+ (slang_vertex_builtin_gc, &object->builtin[SLANG_BUILTIN_TARGET],
+ slang_unit_vertex_builtin, infolog, NULL,
+ &object->builtin[SLANG_BUILTIN_COMMON]))
return GL_FALSE;
- }
+ }
#if defined(USE_X86_ASM) || defined(SLANG_X86)
/* compile x86 4-component vector overrides, link to target */
- if (!compile_binary (slang_builtin_vec4_gc, &object->builtin[SLANG_BUILTIN_VEC4],
- slang_unit_fragment_builtin, infolog, NULL,
- &object->builtin[SLANG_BUILTIN_TARGET]))
+ if (!compile_binary
+ (slang_builtin_vec4_gc, &object->builtin[SLANG_BUILTIN_VEC4],
+ slang_unit_fragment_builtin, infolog, NULL,
+ &object->builtin[SLANG_BUILTIN_TARGET]))
return GL_FALSE;
#endif
- /* disable language extensions */
- grammar_set_reg8 (*id, (const byte *) "parsing_builtin", 0);
+ /* disable language extensions */
+ grammar_set_reg8(*id, (const byte *) "parsing_builtin", 0);
builtins = object->builtin;
- }
+ }
- /* compile the actual shader - pass-in built-in library for external shader */
- return compile_with_grammar (*id, source, &object->unit, type, infolog, builtins);
+ /* compile the actual shader - pass-in built-in library for external shader */
+ return compile_with_grammar(*id, source, &object->unit, type, infolog,
+ builtins);
}
GLboolean
-_slang_compile (const char *source, slang_code_object *object, slang_unit_type type,
- slang_info_log *infolog)
+_slang_compile(const char *source, slang_code_object * object,
+ slang_unit_type type, slang_info_log * infolog)
{
GLboolean success;
grammar id = 0;
- _slang_code_object_dtr (object);
- _slang_code_object_ctr (object);
+ _slang_code_object_dtr(object);
+ _slang_code_object_ctr(object);
- success = compile_object (&id, source, object, type, infolog);
+ success = compile_object(&id, source, object, type, infolog);
if (id != 0)
- grammar_destroy (id);
+ grammar_destroy(id);
if (!success)
return GL_FALSE;
- if (!_slang_build_export_data_table (&object->expdata, &object->unit.vars))
+ if (!_slang_build_export_data_table(&object->expdata, &object->unit.vars))
return GL_FALSE;
- if (!_slang_build_export_code_table (&object->expcode, &object->unit.funs, &object->unit))
+ if (!_slang_build_export_code_table
+ (&object->expcode, &object->unit.funs, &object->unit))
return GL_FALSE;
#if defined(USE_X86_ASM) || defined(SLANG_X86)
/* XXX: lookup the @main label */
- if (!_slang_x86_codegen (&object->machine, &object->assembly, object->expcode.entries[0].address))
+ if (!_slang_x86_codegen
+ (&object->machine, &object->assembly,
+ object->expcode.entries[0].address))
return GL_FALSE;
#endif
return GL_TRUE;
}
-
diff --git a/src/mesa/shader/slang/slang_compile_function.c b/src/mesa/shader/slang/slang_compile_function.c
index eb8fd1bd40..e6e0d89ddb 100644
--- a/src/mesa/shader/slang/slang_compile_function.c
+++ b/src/mesa/shader/slang/slang_compile_function.c
@@ -33,50 +33,74 @@
/* slang_fixup_table */
-void slang_fixup_table_init (slang_fixup_table *fix)
+void
+slang_fixup_table_init(slang_fixup_table * fix)
{
- fix->table = NULL;
- fix->count = 0;
+ fix->table = NULL;
+ fix->count = 0;
}
-void slang_fixup_table_free (slang_fixup_table *fix)
+void
+slang_fixup_table_free(slang_fixup_table * fix)
{
- slang_alloc_free (fix->table);
- slang_fixup_table_init (fix);
+ slang_alloc_free(fix->table);
+ slang_fixup_table_init(fix);
}
+/**
+ * Add a new fixup address to the table.
+ */
+GLboolean
+slang_fixup_save(slang_fixup_table *fixups, GLuint address)
+{
+ fixups->table = (GLuint *)
+ slang_alloc_realloc(fixups->table,
+ fixups->count * sizeof(GLuint),
+ (fixups->count + 1) * sizeof(GLuint));
+ if (fixups->table == NULL)
+ return GL_FALSE;
+ fixups->table[fixups->count] = address;
+ fixups->count++;
+ return GL_TRUE;
+}
+
+
+
/* slang_function */
-int slang_function_construct (slang_function *func)
+int
+slang_function_construct(slang_function * func)
{
- func->kind = slang_func_ordinary;
- if (!slang_variable_construct (&func->header))
- return 0;
- func->parameters = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
- if (func->parameters == NULL)
- {
- slang_variable_destruct (&func->header);
- return 0;
- }
- _slang_variable_scope_ctr (func->parameters);
- func->param_count = 0;
- func->body = NULL;
- func->address = ~0;
- slang_fixup_table_init (&func->fixups);
- return 1;
+ func->kind = slang_func_ordinary;
+ if (!slang_variable_construct(&func->header))
+ return 0;
+
+ func->parameters = (slang_variable_scope *)
+ slang_alloc_malloc(sizeof(slang_variable_scope));
+ if (func->parameters == NULL) {
+ slang_variable_destruct(&func->header);
+ return 0;
+ }
+
+ _slang_variable_scope_ctr(func->parameters);
+ func->param_count = 0;
+ func->body = NULL;
+ func->address = ~0;
+ slang_fixup_table_init(&func->fixups);
+ return 1;
}
-void slang_function_destruct (slang_function *func)
+void
+slang_function_destruct(slang_function * func)
{
- slang_variable_destruct (&func->header);
- slang_variable_scope_destruct (func->parameters);
- slang_alloc_free (func->parameters);
- if (func->body != NULL)
- {
- slang_operation_destruct (func->body);
- slang_alloc_free (func->body);
- }
- slang_fixup_table_free (&func->fixups);
+ slang_variable_destruct(&func->header);
+ slang_variable_scope_destruct(func->parameters);
+ slang_alloc_free(func->parameters);
+ if (func->body != NULL) {
+ slang_operation_destruct(func->body);
+ slang_alloc_free(func->body);
+ }
+ slang_fixup_table_free(&func->fixups);
}
/*
@@ -84,60 +108,82 @@ void slang_function_destruct (slang_function *func)
*/
GLvoid
-_slang_function_scope_ctr (slang_function_scope *self)
+_slang_function_scope_ctr(slang_function_scope * self)
{
self->functions = NULL;
self->num_functions = 0;
self->outer_scope = NULL;
}
-void slang_function_scope_destruct (slang_function_scope *scope)
+void
+slang_function_scope_destruct(slang_function_scope * scope)
{
- unsigned int i;
+ unsigned int i;
- for (i = 0; i < scope->num_functions; i++)
- slang_function_destruct (scope->functions + i);
- slang_alloc_free (scope->functions);
+ for (i = 0; i < scope->num_functions; i++)
+ slang_function_destruct(scope->functions + i);
+ slang_alloc_free(scope->functions);
}
-int slang_function_scope_find_by_name (slang_function_scope *funcs, slang_atom a_name, int all_scopes)
+
+/**
+ * Search a list of functions for a particular function by name.
+ * \param funcs the list of functions to search
+ * \param a_name the name to search for
+ * \param all_scopes if non-zero, search containing scopes too.
+ * \return pointer to found function, or NULL.
+ */
+int
+slang_function_scope_find_by_name(slang_function_scope * funcs,
+ slang_atom a_name, int all_scopes)
{
- unsigned int i;
-
- for (i = 0; i < funcs->num_functions; i++)
- if (a_name == funcs->functions[i].header.a_name)
- return 1;
- if (all_scopes && funcs->outer_scope != NULL)
- return slang_function_scope_find_by_name (funcs->outer_scope, a_name, 1);
- return 0;
+ unsigned int i;
+
+ for (i = 0; i < funcs->num_functions; i++)
+ if (a_name == funcs->functions[i].header.a_name)
+ return 1;
+ if (all_scopes && funcs->outer_scope != NULL)
+ return slang_function_scope_find_by_name(funcs->outer_scope, a_name, 1);
+ return 0;
}
-slang_function *slang_function_scope_find (slang_function_scope *funcs, slang_function *fun,
- int all_scopes)
+
+/**
+ * Search a list of functions for a particular function (for implementing
+ * function calls. Matching is done by first comparing the function's name,
+ * then the function's parameter list.
+ *
+ * \param funcs the list of functions to search
+ * \param fun the function to search for
+ * \param all_scopes if non-zero, search containing scopes too.
+ * \return pointer to found function, or NULL.
+ */
+slang_function *
+slang_function_scope_find(slang_function_scope * funcs, slang_function * fun,
+ int all_scopes)
{
- unsigned int i;
-
- for (i = 0; i < funcs->num_functions; i++)
- {
- slang_function *f = &funcs->functions[i];
- unsigned int j;
-
- if (fun->header.a_name != f->header.a_name)
- continue;
- if (fun->param_count != f->param_count)
- continue;
- for (j = 0; j < fun->param_count; j++)
- {
- if (!slang_type_specifier_equal (&fun->parameters->variables[j].type.specifier,
- &f->parameters->variables[j].type.specifier))
- break;
- }
- if (j == fun->param_count)
- return f;
- }
- if (all_scopes && funcs->outer_scope != NULL)
- return slang_function_scope_find (funcs->outer_scope, fun, 1);
- return NULL;
+ unsigned int i;
+
+ for (i = 0; i < funcs->num_functions; i++) {
+ slang_function *f = &funcs->functions[i];
+ unsigned int j;
+
+ if (fun->header.a_name != f->header.a_name)
+ continue;
+ if (fun->param_count != f->param_count)
+ continue;
+ for (j = 0; j < fun->param_count; j++) {
+ if (!slang_type_specifier_equal
+ (&fun->parameters->variables[j].type.specifier,
+ &f->parameters->variables[j].type.specifier))
+ break;
+ }
+ if (j == fun->param_count)
+ return f;
+ }
+ if (all_scopes && funcs->outer_scope != NULL)
+ return slang_function_scope_find(funcs->outer_scope, fun, 1);
+ return NULL;
}
/*
@@ -145,31 +191,30 @@ slang_function *slang_function_scope_find (slang_function_scope *funcs, slang_fu
*/
GLboolean
-_slang_build_export_code_table (slang_export_code_table *tbl, slang_function_scope *funs,
- slang_code_unit *unit)
+_slang_build_export_code_table(slang_export_code_table * tbl,
+ slang_function_scope * funs,
+ slang_code_unit * unit)
{
- slang_atom mainAtom;
- GLuint i;
-
- mainAtom = slang_atom_pool_atom (tbl->atoms, "main");
- if (mainAtom == SLANG_ATOM_NULL)
- return GL_FALSE;
-
- for (i = 0; i < funs->num_functions; i++)
- {
- if (funs->functions[i].header.a_name == mainAtom)
- {
- slang_function *fun = &funs->functions[i];
- slang_export_code_entry *e;
- slang_assemble_ctx A;
-
- e = slang_export_code_table_add (tbl);
- if (e == NULL)
- return GL_FALSE;
+ slang_atom mainAtom;
+ GLuint i;
+
+ mainAtom = slang_atom_pool_atom(tbl->atoms, "main");
+ if (mainAtom == SLANG_ATOM_NULL)
+ return GL_FALSE;
+
+ for (i = 0; i < funs->num_functions; i++) {
+ if (funs->functions[i].header.a_name == mainAtom) {
+ slang_function *fun = &funs->functions[i];
+ slang_export_code_entry *e;
+ slang_assemble_ctx A;
+
+ e = slang_export_code_table_add(tbl);
+ if (e == NULL)
+ return GL_FALSE;
e->address = unit->object->assembly.count;
- e->name = slang_atom_pool_atom (tbl->atoms, "@main");
- if (e->name == SLANG_ATOM_NULL)
- return GL_FALSE;
+ e->name = slang_atom_pool_atom(tbl->atoms, "@main");
+ if (e->name == SLANG_ATOM_NULL)
+ return GL_FALSE;
A.file = &unit->object->assembly;
A.mach = &unit->object->machine;
@@ -177,12 +222,13 @@ _slang_build_export_code_table (slang_export_code_table *tbl, slang_function_sco
A.space.funcs = &unit->funs;
A.space.structs = &unit->structs;
A.space.vars = &unit->vars;
- slang_assembly_file_push_label (&unit->object->assembly, slang_asm_local_alloc, 20);
- slang_assembly_file_push_label (&unit->object->assembly, slang_asm_enter, 20);
- _slang_assemble_function_call (&A, fun, NULL, 0, GL_FALSE);
- slang_assembly_file_push (&unit->object->assembly, slang_asm_exit);
- }
- }
- return GL_TRUE;
+ slang_assembly_file_push_label(&unit->object->assembly,
+ slang_asm_local_alloc, 20);
+ slang_assembly_file_push_label(&unit->object->assembly,
+ slang_asm_enter, 20);
+ _slang_assemble_function_call(&A, fun, NULL, 0, GL_FALSE);
+ slang_assembly_file_push(&unit->object->assembly, slang_asm_exit);
+ }
+ }
+ return GL_TRUE;
}
-
diff --git a/src/mesa/shader/slang/slang_compile_function.h b/src/mesa/shader/slang/slang_compile_function.h
index 24bc0d6ffd..c05c6f4d85 100644
--- a/src/mesa/shader/slang/slang_compile_function.h
+++ b/src/mesa/shader/slang/slang_compile_function.h
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.2
*
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
*
@@ -22,7 +22,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#if !defined SLANG_COMPILE_FUNCTION_H
+#ifndef SLANG_COMPILE_FUNCTION_H
#define SLANG_COMPILE_FUNCTION_H
#if defined __cplusplus
@@ -31,57 +31,81 @@ extern "C" {
struct slang_code_unit_;
+/**
+ * Types of functions.
+ */
typedef enum slang_function_kind_
{
- slang_func_ordinary,
- slang_func_constructor,
- slang_func_operator
+ slang_func_ordinary,
+ slang_func_constructor,
+ slang_func_operator
} slang_function_kind;
+
+/**
+ * When we need to fill in addresses which we won't know until the future,
+ * we keep track of them with a fix-up table.
+ */
typedef struct slang_fixup_table_
{
- GLuint *table;
- GLuint count;
+ GLuint *table; /**< array[count] of addresses */
+ GLuint count;
} slang_fixup_table;
-void slang_fixup_table_init (slang_fixup_table *);
-void slang_fixup_table_free (slang_fixup_table *);
+extern void slang_fixup_table_init(slang_fixup_table *);
+extern void slang_fixup_table_free(slang_fixup_table *);
+extern GLboolean slang_fixup_save(slang_fixup_table *fixups, GLuint address);
+
+/**
+ * Description of a compiled shader function.
+ */
typedef struct slang_function_
{
- slang_function_kind kind;
- slang_variable header;
- slang_variable_scope *parameters;
- unsigned int param_count;
- slang_operation *body;
- unsigned int address;
- slang_fixup_table fixups;
+ slang_function_kind kind;
+ slang_variable header; /**< The function's name and return type */
+ slang_variable_scope *parameters; /**< formal parameters AND local vars */
+ unsigned int param_count; /**< number of formal params (no locals) */
+ slang_operation *body; /**< The instruction tree */
+ unsigned int address; /**< Address of this func in memory */
+ slang_fixup_table fixups; /**< Mem locations which need func's address */
} slang_function;
-int slang_function_construct (slang_function *);
-void slang_function_destruct (slang_function *);
+extern int slang_function_construct(slang_function *);
+extern void slang_function_destruct(slang_function *);
+
+/**
+ * Basically, a list of compiled functions.
+ */
typedef struct slang_function_scope_
{
- slang_function *functions;
+ slang_function *functions;
GLuint num_functions;
- struct slang_function_scope_ *outer_scope;
+ struct slang_function_scope_ *outer_scope;
} slang_function_scope;
+
extern GLvoid
-_slang_function_scope_ctr (slang_function_scope *);
+_slang_function_scope_ctr(slang_function_scope *);
+
+extern void
+slang_function_scope_destruct(slang_function_scope *);
+
+extern int
+slang_function_scope_find_by_name(slang_function_scope *, slang_atom, int);
-void slang_function_scope_destruct (slang_function_scope *);
-int slang_function_scope_find_by_name (slang_function_scope *, slang_atom, int);
-slang_function *slang_function_scope_find (slang_function_scope *, slang_function *, int);
+extern slang_function *
+slang_function_scope_find(slang_function_scope *, slang_function *, int);
extern GLboolean
-_slang_build_export_code_table (slang_export_code_table *, slang_function_scope *,
- struct slang_code_unit_ *);
+_slang_build_export_code_table(slang_export_code_table *,
+ slang_function_scope *,
+ struct slang_code_unit_ *);
+
#ifdef __cplusplus
}
#endif
-#endif
-
+#endif /* SLANG_COMPILE_FUNCTION_H */
diff --git a/src/mesa/shader/slang/slang_compile_operation.c b/src/mesa/shader/slang/slang_compile_operation.c
index 7e92013559..73f57bfb12 100644
--- a/src/mesa/shader/slang/slang_compile_operation.c
+++ b/src/mesa/shader/slang/slang_compile_operation.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.2
*
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
*
@@ -31,68 +31,85 @@
#include "imports.h"
#include "slang_compile.h"
-/* slang_operation */
-int slang_operation_construct (slang_operation *oper)
+/**
+ * Init a slang_operation object
+ */
+GLboolean
+slang_operation_construct(slang_operation * oper)
{
- oper->type = slang_oper_none;
- oper->children = NULL;
- oper->num_children = 0;
- oper->literal = (float) 0;
- oper->a_id = SLANG_ATOM_NULL;
- oper->locals = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
- if (oper->locals == NULL)
- return 0;
- _slang_variable_scope_ctr (oper->locals);
- return 1;
+ oper->type = slang_oper_none;
+ oper->children = NULL;
+ oper->num_children = 0;
+ oper->literal = (float) 0;
+ oper->a_id = SLANG_ATOM_NULL;
+ oper->locals =
+ (slang_variable_scope *)
+ slang_alloc_malloc(sizeof(slang_variable_scope));
+ if (oper->locals == NULL)
+ return GL_FALSE;
+ _slang_variable_scope_ctr(oper->locals);
+ return GL_TRUE;
}
-void slang_operation_destruct (slang_operation *oper)
+void
+slang_operation_destruct(slang_operation * oper)
{
- unsigned int i;
+ GLuint i;
- for (i = 0; i < oper->num_children; i++)
- slang_operation_destruct (oper->children + i);
- slang_alloc_free (oper->children);
- slang_variable_scope_destruct (oper->locals);
- slang_alloc_free (oper->locals);
+ for (i = 0; i < oper->num_children; i++)
+ slang_operation_destruct(oper->children + i);
+ slang_alloc_free(oper->children);
+ slang_variable_scope_destruct(oper->locals);
+ slang_alloc_free(oper->locals);
}
-int slang_operation_copy (slang_operation *x, const slang_operation *y)
+/**
+ * Recursively copy a slang_operation node.
+ * \return GL_TRUE for success, GL_FALSE if failure
+ */
+GLboolean
+slang_operation_copy(slang_operation * x, const slang_operation * y)
{
- slang_operation z;
- unsigned int i;
+ slang_operation z;
+ GLuint i;
- if (!slang_operation_construct (&z))
- return 0;
- z.type = y->type;
- z.children = (slang_operation *) slang_alloc_malloc (y->num_children * sizeof (slang_operation));
- if (z.children == NULL)
- {
- slang_operation_destruct (&z);
- return 0;
- }
- for (z.num_children = 0; z.num_children < y->num_children; z.num_children++)
- if (!slang_operation_construct (&z.children[z.num_children]))
- {
- slang_operation_destruct (&z);
- return 0;
- }
- for (i = 0; i < z.num_children; i++)
- if (!slang_operation_copy (&z.children[i], &y->children[i]))
- {
- slang_operation_destruct (&z);
- return 0;
- }
- z.literal = y->literal;
- z.a_id = y->a_id;
- if (!slang_variable_scope_copy (z.locals, y->locals))
- {
- slang_operation_destruct (&z);
- return 0;
- }
- slang_operation_destruct (x);
- *x = z;
- return 1;
+ if (!slang_operation_construct(&z))
+ return GL_FALSE;
+ z.type = y->type;
+ z.children = (slang_operation *)
+ slang_alloc_malloc(y->num_children * sizeof(slang_operation));
+ if (z.children == NULL) {
+ slang_operation_destruct(&z);
+ return GL_FALSE;
+ }
+ for (z.num_children = 0; z.num_children < y->num_children;
+ z.num_children++) {
+ if (!slang_operation_construct(&z.children[z.num_children])) {
+ slang_operation_destruct(&z);
+ return GL_FALSE;
+ }
+ }
+ for (i = 0; i < z.num_children; i++) {
+ if (!slang_operation_copy(&z.children[i], &y->children[i])) {
+ slang_operation_destruct(&z);
+ return GL_FALSE;
+ }
+ }
+ z.literal = y->literal;
+ z.a_id = y->a_id;
+ if (!slang_variable_scope_copy(z.locals, y->locals)) {
+ slang_operation_destruct(&z);
+ return GL_FALSE;
+ }
+ slang_operation_destruct(x);
+ *x = z;
+ return GL_TRUE;
}
+
+slang_operation *
+slang_operation_new(GLuint count)
+{
+ return (slang_operation *) _mesa_calloc(count * sizeof(slang_operation));
+}
diff --git a/src/mesa/shader/slang/slang_compile_operation.h b/src/mesa/shader/slang/slang_compile_operation.h
index d9bce36b9b..a9376ec945 100644
--- a/src/mesa/shader/slang/slang_compile_operation.h
+++ b/src/mesa/shader/slang/slang_compile_operation.h
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.2
*
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
*
@@ -22,96 +22,119 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#if !defined SLANG_COMPILE_OPERATION_H
+#ifndef SLANG_COMPILE_OPERATION_H
#define SLANG_COMPILE_OPERATION_H
#if defined __cplusplus
extern "C" {
#endif
+
+/**
+ * Types of slang operations.
+ * These are the types of the AST (abstract syntax tree) nodes.
+ * [foo] indicates a sub-tree or reference to another type of node
+ */
typedef enum slang_operation_type_
{
- slang_oper_none,
- slang_oper_block_no_new_scope,
- slang_oper_block_new_scope,
- slang_oper_variable_decl,
- slang_oper_asm,
- slang_oper_break,
- slang_oper_continue,
- slang_oper_discard,
- slang_oper_return,
- slang_oper_expression,
- slang_oper_if,
- slang_oper_while,
- slang_oper_do,
- slang_oper_for,
- slang_oper_void,
- slang_oper_literal_bool,
- slang_oper_literal_int,
- slang_oper_literal_float,
- slang_oper_identifier,
- slang_oper_sequence,
- slang_oper_assign,
- slang_oper_addassign,
- slang_oper_subassign,
- slang_oper_mulassign,
- slang_oper_divassign,
- /*slang_oper_modassign,*/
- /*slang_oper_lshassign,*/
- /*slang_oper_rshassign,*/
- /*slang_oper_orassign,*/
- /*slang_oper_xorassign,*/
- /*slang_oper_andassign,*/
- slang_oper_select,
- slang_oper_logicalor,
- slang_oper_logicalxor,
- slang_oper_logicaland,
- /*slang_oper_bitor,*/
- /*slang_oper_bitxor,*/
- /*slang_oper_bitand,*/
- slang_oper_equal,
- slang_oper_notequal,
- slang_oper_less,
- slang_oper_greater,
- slang_oper_lessequal,
- slang_oper_greaterequal,
- /*slang_oper_lshift,*/
- /*slang_oper_rshift,*/
- slang_oper_add,
- slang_oper_subtract,
- slang_oper_multiply,
- slang_oper_divide,
- /*slang_oper_modulus,*/
- slang_oper_preincrement,
- slang_oper_predecrement,
- slang_oper_plus,
- slang_oper_minus,
- /*slang_oper_complement,*/
- slang_oper_not,
- slang_oper_subscript,
- slang_oper_call,
- slang_oper_field,
- slang_oper_postincrement,
- slang_oper_postdecrement
+ slang_oper_none,
+ slang_oper_block_no_new_scope, /* "{" sequence "}" */
+ slang_oper_block_new_scope, /* "{" sequence "}" */
+ slang_oper_variable_decl, /* [type] [var] or [var] = [expr] */
+ slang_oper_asm,
+ slang_oper_break, /* "break" statement */
+ slang_oper_continue, /* "continue" statement */
+ slang_oper_discard, /* "discard" (kill fragment) statement */
+ slang_oper_return, /* "return" [expr] */
+ slang_oper_expression, /* [expr] */
+ slang_oper_if, /* "if" [0] then [1] else [2] */
+ slang_oper_while, /* "while" [cond] [body] */
+ slang_oper_do, /* "do" [body] "while" [cond] */
+ slang_oper_for, /* "for" [init] [while] [incr] [body] */
+ slang_oper_void, /* nop */
+ slang_oper_literal_bool, /* "true" or "false" */
+ slang_oper_literal_int, /* integer literal */
+ slang_oper_literal_float, /* float literal */
+ slang_oper_identifier, /* var name, func name, etc */
+ slang_oper_sequence, /* [expr] "," [expr] "," etc */
+ slang_oper_assign, /* [var] "=" [expr] */
+ slang_oper_addassign, /* [var] "+=" [expr] */
+ slang_oper_subassign, /* [var] "-=" [expr] */
+ slang_oper_mulassign, /* [var] "*=" [expr] */
+ slang_oper_divassign, /* [var] "/=" [expr] */
+ /*slang_oper_modassign, */
+ /*slang_oper_lshassign, */
+ /*slang_oper_rshassign, */
+ /*slang_oper_orassign, */
+ /*slang_oper_xorassign, */
+ /*slang_oper_andassign, */
+ slang_oper_select, /* [expr] "?" [expr] ":" [expr] */
+ slang_oper_logicalor, /* [expr] "||" [expr] */
+ slang_oper_logicalxor, /* [expr] "^^" [expr] */
+ slang_oper_logicaland, /* [expr] "&&" [expr] */
+ /*slang_oper_bitor, */
+ /*slang_oper_bitxor, */
+ /*slang_oper_bitand, */
+ slang_oper_equal, /* [expr] "==" [expr] */
+ slang_oper_notequal, /* [expr] "!=" [expr] */
+ slang_oper_less, /* [expr] "<" [expr] */
+ slang_oper_greater, /* [expr] ">" [expr] */
+ slang_oper_lessequal, /* [expr] "<=" [expr] */
+ slang_oper_greaterequal, /* [expr] ">=" [expr] */
+ /*slang_oper_lshift, */
+ /*slang_oper_rshift, */
+ slang_oper_add, /* [expr] "+" [expr] */
+ slang_oper_subtract, /* [expr] "-" [expr] */
+ slang_oper_multiply, /* [expr] "*" [expr] */
+ slang_oper_divide, /* [expr] "/" [expr] */
+ /*slang_oper_modulus, */
+ slang_oper_preincrement, /* "++" [var] */
+ slang_oper_predecrement, /* "--" [var] */
+ slang_oper_plus, /* "-" [expr] */
+ slang_oper_minus, /* "+" [expr] */
+ /*slang_oper_complement, */
+ slang_oper_not, /* "!" [expr] */
+ slang_oper_subscript, /* [expr] "[" [expr] "]" */
+ slang_oper_call, /* [func name] [param] [param] [...] */
+ slang_oper_field, /* i.e.: ".next" or ".xzy" or ".xxx" etc */
+ slang_oper_postincrement, /* [var] "++" */
+ slang_oper_postdecrement /* [var] "--" */
} slang_operation_type;
+
+/**
+ * A slang_operation is basically a compiled instruction (such as assignment,
+ * a while-loop, a conditional, a multiply, a function call, etc).
+ * The AST (abstract syntax tree) is built from these nodes.
+ * NOTE: This structure could have been implemented as a union of simpler
+ * structs which would correspond to the operation types above.
+ */
typedef struct slang_operation_
{
- slang_operation_type type;
- struct slang_operation_ *children;
- unsigned int num_children;
- float literal; /* type: bool, literal_int, literal_float */
- slang_atom a_id; /* type: asm, identifier, call, field */
- slang_variable_scope *locals;
+ slang_operation_type type;
+ struct slang_operation_ *children;
+ GLuint num_children;
+ GLfloat literal; /**< Used for float, int and bool values */
+ slang_atom a_id; /**< type: asm, identifier, call, field */
+ slang_variable_scope *locals; /**< local vars for scope */
} slang_operation;
-int slang_operation_construct (slang_operation *);
-void slang_operation_destruct (slang_operation *);
-int slang_operation_copy (slang_operation *, const slang_operation *);
+
+extern GLboolean
+slang_operation_construct(slang_operation *);
+
+extern void
+slang_operation_destruct(slang_operation *);
+
+extern GLboolean
+slang_operation_copy(slang_operation *, const slang_operation *);
+
+extern slang_operation *
+slang_operation_new(GLuint count);
+
#ifdef __cplusplus
}
#endif
-#endif
-
+#endif /* SLANG_COMPILE_OPERATION_H */
diff --git a/src/mesa/shader/slang/slang_compile_variable.c b/src/mesa/shader/slang/slang_compile_variable.c
index b62743addb..a8a2d6aa6a 100644
--- a/src/mesa/shader/slang/slang_compile_variable.c
+++ b/src/mesa/shader/slang/slang_compile_variable.c
@@ -35,89 +35,92 @@
typedef struct
{
- const char *name;
- slang_type_specifier_type type;
+ const char *name;
+ slang_type_specifier_type type;
} type_specifier_type_name;
-static type_specifier_type_name type_specifier_type_names[] = {
- { "void", slang_spec_void },
- { "bool", slang_spec_bool },
- { "bvec2", slang_spec_bvec2 },
- { "bvec3", slang_spec_bvec3 },
- { "bvec4", slang_spec_bvec4 },
- { "int", slang_spec_int },
- { "ivec2", slang_spec_ivec2 },
- { "ivec3", slang_spec_ivec3 },
- { "ivec4", slang_spec_ivec4 },
- { "float", slang_spec_float },
- { "vec2", slang_spec_vec2 },
- { "vec3", slang_spec_vec3 },
- { "vec4", slang_spec_vec4 },
- { "mat2", slang_spec_mat2 },
- { "mat3", slang_spec_mat3 },
- { "mat4", slang_spec_mat4 },
- { "sampler1D", slang_spec_sampler1D },
- { "sampler2D", slang_spec_sampler2D },
- { "sampler3D", slang_spec_sampler3D },
- { "samplerCube", slang_spec_samplerCube },
- { "sampler1DShadow", slang_spec_sampler1DShadow },
- { "sampler2DShadow", slang_spec_sampler2DShadow },
- { NULL, slang_spec_void }
+static const type_specifier_type_name type_specifier_type_names[] = {
+ {"void", slang_spec_void},
+ {"bool", slang_spec_bool},
+ {"bvec2", slang_spec_bvec2},
+ {"bvec3", slang_spec_bvec3},
+ {"bvec4", slang_spec_bvec4},
+ {"int", slang_spec_int},
+ {"ivec2", slang_spec_ivec2},
+ {"ivec3", slang_spec_ivec3},
+ {"ivec4", slang_spec_ivec4},
+ {"float", slang_spec_float},
+ {"vec2", slang_spec_vec2},
+ {"vec3", slang_spec_vec3},
+ {"vec4", slang_spec_vec4},
+ {"mat2", slang_spec_mat2},
+ {"mat3", slang_spec_mat3},
+ {"mat4", slang_spec_mat4},
+ {"sampler1D", slang_spec_sampler1D},
+ {"sampler2D", slang_spec_sampler2D},
+ {"sampler3D", slang_spec_sampler3D},
+ {"samplerCube", slang_spec_samplerCube},
+ {"sampler1DShadow", slang_spec_sampler1DShadow},
+ {"sampler2DShadow", slang_spec_sampler2DShadow},
+ {NULL, slang_spec_void}
};
-slang_type_specifier_type slang_type_specifier_type_from_string (const char *name)
+slang_type_specifier_type
+slang_type_specifier_type_from_string(const char *name)
{
- type_specifier_type_name *p = type_specifier_type_names;
- while (p->name != NULL)
- {
- if (slang_string_compare (p->name, name) == 0)
- break;
- p++;
- }
- return p->type;
+ const type_specifier_type_name *p = type_specifier_type_names;
+ while (p->name != NULL) {
+ if (slang_string_compare(p->name, name) == 0)
+ break;
+ p++;
+ }
+ return p->type;
}
-const char *slang_type_specifier_type_to_string (slang_type_specifier_type type)
+const char *
+slang_type_specifier_type_to_string(slang_type_specifier_type type)
{
- type_specifier_type_name *p = type_specifier_type_names;
- while (p->name != NULL)
- {
- if (p->type == type)
- break;
- p++;
- }
- return p->name;
+ const type_specifier_type_name *p = type_specifier_type_names;
+ while (p->name != NULL) {
+ if (p->type == type)
+ break;
+ p++;
+ }
+ return p->name;
}
/* slang_fully_specified_type */
-int slang_fully_specified_type_construct (slang_fully_specified_type *type)
+int
+slang_fully_specified_type_construct(slang_fully_specified_type * type)
{
- type->qualifier = slang_qual_none;
- slang_type_specifier_ctr (&type->specifier);
- return 1;
+ type->qualifier = slang_qual_none;
+ slang_type_specifier_ctr(&type->specifier);
+ return 1;
}
-void slang_fully_specified_type_destruct (slang_fully_specified_type *type)
+void
+slang_fully_specified_type_destruct(slang_fully_specified_type * type)
{
- slang_type_specifier_dtr (&type->specifier);
+ slang_type_specifier_dtr(&type->specifier);
}
-int slang_fully_specified_type_copy (slang_fully_specified_type *x, const slang_fully_specified_type *y)
+int
+slang_fully_specified_type_copy(slang_fully_specified_type * x,
+ const slang_fully_specified_type * y)
{
- slang_fully_specified_type z;
-
- if (!slang_fully_specified_type_construct (&z))
- return 0;
- z.qualifier = y->qualifier;
- if (!slang_type_specifier_copy (&z.specifier, &y->specifier))
- {
- slang_fully_specified_type_destruct (&z);
- return 0;
- }
- slang_fully_specified_type_destruct (x);
- *x = z;
- return 1;
+ slang_fully_specified_type z;
+
+ if (!slang_fully_specified_type_construct(&z))
+ return 0;
+ z.qualifier = y->qualifier;
+ if (!slang_type_specifier_copy(&z.specifier, &y->specifier)) {
+ slang_fully_specified_type_destruct(&z);
+ return 0;
+ }
+ slang_fully_specified_type_destruct(x);
+ *x = z;
+ return 1;
}
/*
@@ -125,246 +128,281 @@ int slang_fully_specified_type_copy (slang_fully_specified_type *x, const slang_
*/
GLvoid
-_slang_variable_scope_ctr (slang_variable_scope *self)
+_slang_variable_scope_ctr(slang_variable_scope * self)
{
self->variables = NULL;
self->num_variables = 0;
self->outer_scope = NULL;
}
-void slang_variable_scope_destruct (slang_variable_scope *scope)
+void
+slang_variable_scope_destruct(slang_variable_scope * scope)
{
- unsigned int i;
+ unsigned int i;
+
+ if (!scope)
+ return;
+ for (i = 0; i < scope->num_variables; i++)
+ slang_variable_destruct(scope->variables + i);
+ slang_alloc_free(scope->variables);
+ /* do not free scope->outer_scope */
+}
- for (i = 0; i < scope->num_variables; i++)
- slang_variable_destruct (scope->variables + i);
- slang_alloc_free (scope->variables);
- /* do not free scope->outer_scope */
+int
+slang_variable_scope_copy(slang_variable_scope * x,
+ const slang_variable_scope * y)
+{
+ slang_variable_scope z;
+ unsigned int i;
+
+ _slang_variable_scope_ctr(&z);
+ z.variables = (slang_variable *)
+ slang_alloc_malloc(y->num_variables * sizeof(slang_variable));
+ if (z.variables == NULL) {
+ slang_variable_scope_destruct(&z);
+ return 0;
+ }
+ for (z.num_variables = 0; z.num_variables < y->num_variables;
+ z.num_variables++) {
+ if (!slang_variable_construct(&z.variables[z.num_variables])) {
+ slang_variable_scope_destruct(&z);
+ return 0;
+ }
+ }
+ for (i = 0; i < z.num_variables; i++) {
+ if (!slang_variable_copy(&z.variables[i], &y->variables[i])) {
+ slang_variable_scope_destruct(&z);
+ return 0;
+ }
+ }
+ z.outer_scope = y->outer_scope;
+ slang_variable_scope_destruct(x);
+ *x = z;
+ return 1;
}
-int slang_variable_scope_copy (slang_variable_scope *x, const slang_variable_scope *y)
+
+/**
+ * Grow the variable list by one.
+ * \return pointer to space for the new variable (will be initialized)
+ */
+slang_variable *
+slang_variable_scope_grow(slang_variable_scope *scope)
{
- slang_variable_scope z;
- unsigned int i;
-
- _slang_variable_scope_ctr (&z);
- z.variables = (slang_variable *) slang_alloc_malloc (y->num_variables * sizeof (slang_variable));
- if (z.variables == NULL)
- {
- slang_variable_scope_destruct (&z);
- return 0;
- }
- for (z.num_variables = 0; z.num_variables < y->num_variables; z.num_variables++)
- if (!slang_variable_construct (&z.variables[z.num_variables]))
- {
- slang_variable_scope_destruct (&z);
- return 0;
- }
- for (i = 0; i < z.num_variables; i++)
- if (!slang_variable_copy (&z.variables[i], &y->variables[i]))
- {
- slang_variable_scope_destruct (&z);
- return 0;
- }
- z.outer_scope = y->outer_scope;
- slang_variable_scope_destruct (x);
- *x = z;
- return 1;
+ const int n = scope->num_variables;
+ scope->variables = (slang_variable *)
+ slang_alloc_realloc(scope->variables,
+ n * sizeof(slang_variable),
+ (n + 1) * sizeof(slang_variable));
+ if (!scope->variables)
+ return NULL;
+
+ scope->num_variables++;
+
+ if (!slang_variable_construct(scope->variables + n))
+ return NULL;
+
+ return scope->variables + n;
}
+
+
/* slang_variable */
-int slang_variable_construct (slang_variable *var)
+int
+slang_variable_construct(slang_variable * var)
{
- if (!slang_fully_specified_type_construct (&var->type))
- return 0;
- var->a_name = SLANG_ATOM_NULL;
- var->array_len = 0;
- var->initializer = NULL;
- var->address = ~0;
- var->size = 0;
- var->global = 0;
- return 1;
+ if (!slang_fully_specified_type_construct(&var->type))
+ return 0;
+ var->a_name = SLANG_ATOM_NULL;
+ var->array_len = 0;
+ var->initializer = NULL;
+ var->address = ~0;
+ var->address2 = 0;
+ var->size = 0;
+ var->global = GL_FALSE;
+ return 1;
}
-void slang_variable_destruct (slang_variable *var)
+void
+slang_variable_destruct(slang_variable * var)
{
- slang_fully_specified_type_destruct (&var->type);
- if (var->initializer != NULL)
- {
- slang_operation_destruct (var->initializer);
- slang_alloc_free (var->initializer);
- }
+ slang_fully_specified_type_destruct(&var->type);
+ if (var->initializer != NULL) {
+ slang_operation_destruct(var->initializer);
+ slang_alloc_free(var->initializer);
+ }
}
-int slang_variable_copy (slang_variable *x, const slang_variable *y)
+int
+slang_variable_copy(slang_variable * x, const slang_variable * y)
{
- slang_variable z;
-
- if (!slang_variable_construct (&z))
- return 0;
- if (!slang_fully_specified_type_copy (&z.type, &y->type))
- {
- slang_variable_destruct (&z);
- return 0;
- }
- z.a_name = y->a_name;
- z.array_len = y->array_len;
- if (y->initializer != NULL)
- {
- z.initializer = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
- if (z.initializer == NULL)
- {
- slang_variable_destruct (&z);
- return 0;
- }
- if (!slang_operation_construct (z.initializer))
- {
- slang_alloc_free (z.initializer);
- slang_variable_destruct (&z);
- return 0;
- }
- if (!slang_operation_copy (z.initializer, y->initializer))
- {
- slang_variable_destruct (&z);
- return 0;
- }
- }
- z.address = y->address;
- z.size = y->size;
- z.global = y->global;
- slang_variable_destruct (x);
- *x = z;
- return 1;
+ slang_variable z;
+
+ if (!slang_variable_construct(&z))
+ return 0;
+ if (!slang_fully_specified_type_copy(&z.type, &y->type)) {
+ slang_variable_destruct(&z);
+ return 0;
+ }
+ z.a_name = y->a_name;
+ z.array_len = y->array_len;
+ if (y->initializer != NULL) {
+ z.initializer =
+ (slang_operation *) slang_alloc_malloc(sizeof(slang_operation));
+ if (z.initializer == NULL) {
+ slang_variable_destruct(&z);
+ return 0;
+ }
+ if (!slang_operation_construct(z.initializer)) {
+ slang_alloc_free(z.initializer);
+ slang_variable_destruct(&z);
+ return 0;
+ }
+ if (!slang_operation_copy(z.initializer, y->initializer)) {
+ slang_variable_destruct(&z);
+ return 0;
+ }
+ }
+ z.address = y->address;
+ z.size = y->size;
+ z.global = y->global;
+ slang_variable_destruct(x);
+ *x = z;
+ return 1;
}
-slang_variable *_slang_locate_variable (slang_variable_scope *scope, slang_atom a_name, GLboolean all)
+slang_variable *
+_slang_locate_variable(const slang_variable_scope * scope,
+ const slang_atom a_name, GLboolean all)
{
- GLuint i;
-
- for (i = 0; i < scope->num_variables; i++)
- if (a_name == scope->variables[i].a_name)
- return &scope->variables[i];
- if (all && scope->outer_scope != NULL)
- return _slang_locate_variable (scope->outer_scope, a_name, 1);
- return NULL;
+ GLuint i;
+
+ for (i = 0; i < scope->num_variables; i++)
+ if (a_name == scope->variables[i].a_name)
+ return &scope->variables[i];
+ if (all && scope->outer_scope != NULL)
+ return _slang_locate_variable(scope->outer_scope, a_name, 1);
+ return NULL;
}
/*
* _slang_build_export_data_table()
*/
-static GLenum gl_type_from_specifier (const slang_type_specifier *type)
+static GLenum
+gl_type_from_specifier(const slang_type_specifier * type)
{
- switch (type->type)
- {
- case slang_spec_bool:
- return GL_BOOL_ARB;
- case slang_spec_bvec2:
- return GL_BOOL_VEC2_ARB;
- case slang_spec_bvec3:
- return GL_BOOL_VEC3_ARB;
- case slang_spec_bvec4:
- return GL_BOOL_VEC4_ARB;
- case slang_spec_int:
- return GL_INT;
- case slang_spec_ivec2:
- return GL_INT_VEC2_ARB;
- case slang_spec_ivec3:
- return GL_INT_VEC3_ARB;
- case slang_spec_ivec4:
- return GL_INT_VEC4_ARB;
- case slang_spec_float:
- return GL_FLOAT;
- case slang_spec_vec2:
- return GL_FLOAT_VEC2_ARB;
- case slang_spec_vec3:
- return GL_FLOAT_VEC3_ARB;
- case slang_spec_vec4:
- return GL_FLOAT_VEC4_ARB;
- case slang_spec_mat2:
- return GL_FLOAT_MAT2_ARB;
- case slang_spec_mat3:
- return GL_FLOAT_MAT3_ARB;
- case slang_spec_mat4:
- return GL_FLOAT_MAT4_ARB;
- case slang_spec_sampler1D:
- return GL_SAMPLER_1D_ARB;
- case slang_spec_sampler2D:
- return GL_SAMPLER_2D_ARB;
- case slang_spec_sampler3D:
- return GL_SAMPLER_3D_ARB;
- case slang_spec_samplerCube:
- return GL_SAMPLER_CUBE_ARB;
- case slang_spec_sampler1DShadow:
- return GL_SAMPLER_1D_SHADOW_ARB;
- case slang_spec_sampler2DShadow:
- return GL_SAMPLER_2D_SHADOW_ARB;
- case slang_spec_array:
- return gl_type_from_specifier (type->_array);
- default:
- return GL_FLOAT;
- }
+ switch (type->type) {
+ case slang_spec_bool:
+ return GL_BOOL_ARB;
+ case slang_spec_bvec2:
+ return GL_BOOL_VEC2_ARB;
+ case slang_spec_bvec3:
+ return GL_BOOL_VEC3_ARB;
+ case slang_spec_bvec4:
+ return GL_BOOL_VEC4_ARB;
+ case slang_spec_int:
+ return GL_INT;
+ case slang_spec_ivec2:
+ return GL_INT_VEC2_ARB;
+ case slang_spec_ivec3:
+ return GL_INT_VEC3_ARB;
+ case slang_spec_ivec4:
+ return GL_INT_VEC4_ARB;
+ case slang_spec_float:
+ return GL_FLOAT;
+ case slang_spec_vec2:
+ return GL_FLOAT_VEC2_ARB;
+ case slang_spec_vec3:
+ return GL_FLOAT_VEC3_ARB;
+ case slang_spec_vec4:
+ return GL_FLOAT_VEC4_ARB;
+ case slang_spec_mat2:
+ return GL_FLOAT_MAT2_ARB;
+ case slang_spec_mat3:
+ return GL_FLOAT_MAT3_ARB;
+ case slang_spec_mat4:
+ return GL_FLOAT_MAT4_ARB;
+ case slang_spec_sampler1D:
+ return GL_SAMPLER_1D_ARB;
+ case slang_spec_sampler2D:
+ return GL_SAMPLER_2D_ARB;
+ case slang_spec_sampler3D:
+ return GL_SAMPLER_3D_ARB;
+ case slang_spec_samplerCube:
+ return GL_SAMPLER_CUBE_ARB;
+ case slang_spec_sampler1DShadow:
+ return GL_SAMPLER_1D_SHADOW_ARB;
+ case slang_spec_sampler2DShadow:
+ return GL_SAMPLER_2D_SHADOW_ARB;
+ case slang_spec_array:
+ return gl_type_from_specifier(type->_array);
+ default:
+ return GL_FLOAT;
+ }
}
-static GLboolean build_quant (slang_export_data_quant *q, slang_variable *var)
+static GLboolean
+build_quant(slang_export_data_quant * q, const slang_variable * var)
{
- slang_type_specifier *spec = &var->type.specifier;
-
- q->name = var->a_name;
- q->size = var->size;
- if (spec->type == slang_spec_array)
- {
- q->array_len = var->array_len;
- q->size /= var->array_len;
- spec = spec->_array;
- }
- if (spec->type == slang_spec_struct)
- {
- GLuint i;
-
- q->u.field_count = spec->_struct->fields->num_variables;
- q->structure = (slang_export_data_quant *) slang_alloc_malloc (
- q->u.field_count * sizeof (slang_export_data_quant));
- if (q->structure == NULL)
- return GL_FALSE;
-
- for (i = 0; i < q->u.field_count; i++)
- slang_export_data_quant_ctr (&q->structure[i]);
- for (i = 0; i < q->u.field_count; i++)
- if (!build_quant (&q->structure[i], &spec->_struct->fields->variables[i]))
- return GL_FALSE;
- }
- else
- q->u.basic_type = gl_type_from_specifier (spec);
- return GL_TRUE;
+ const slang_type_specifier *spec = &var->type.specifier;
+
+ q->name = var->a_name;
+ q->size = var->size;
+ if (spec->type == slang_spec_array) {
+ q->array_len = var->array_len;
+ q->size /= var->array_len;
+ spec = spec->_array;
+ }
+ if (spec->type == slang_spec_struct) {
+ GLuint i;
+
+ q->u.field_count = spec->_struct->fields->num_variables;
+ q->structure = (slang_export_data_quant *)
+ slang_alloc_malloc(q->u.field_count
+ * sizeof(slang_export_data_quant));
+ if (q->structure == NULL)
+ return GL_FALSE;
+
+ for (i = 0; i < q->u.field_count; i++)
+ slang_export_data_quant_ctr(&q->structure[i]);
+ for (i = 0; i < q->u.field_count; i++) {
+ if (!build_quant(&q->structure[i],
+ &spec->_struct->fields->variables[i]))
+ return GL_FALSE;
+ }
+ }
+ else
+ q->u.basic_type = gl_type_from_specifier(spec);
+ return GL_TRUE;
}
-GLboolean _slang_build_export_data_table (slang_export_data_table *tbl, slang_variable_scope *vars)
+GLboolean
+_slang_build_export_data_table(slang_export_data_table * tbl,
+ slang_variable_scope * vars)
{
- GLuint i;
-
- for (i = 0; i < vars->num_variables; i++)
- {
- slang_variable *var = &vars->variables[i];
- slang_export_data_entry *e;
-
- e = slang_export_data_table_add (tbl);
- if (e == NULL)
- return GL_FALSE;
- if (!build_quant (&e->quant, var))
- return GL_FALSE;
- if (var->type.qualifier == slang_qual_uniform)
- e->access = slang_exp_uniform;
- else if (var->type.qualifier == slang_qual_attribute)
- e->access = slang_exp_attribute;
- else
- e->access = slang_exp_varying;
- e->address = var->address;
- }
-
- if (vars->outer_scope != NULL)
- return _slang_build_export_data_table (tbl, vars->outer_scope);
- return GL_TRUE;
+ GLuint i;
+
+ for (i = 0; i < vars->num_variables; i++) {
+ const slang_variable *var = &vars->variables[i];
+ slang_export_data_entry *e;
+
+ e = slang_export_data_table_add(tbl);
+ if (e == NULL)
+ return GL_FALSE;
+ if (!build_quant(&e->quant, var))
+ return GL_FALSE;
+ if (var->type.qualifier == slang_qual_uniform)
+ e->access = slang_exp_uniform;
+ else if (var->type.qualifier == slang_qual_attribute)
+ e->access = slang_exp_attribute;
+ else
+ e->access = slang_exp_varying;
+ e->address = var->address;
+ }
+
+ if (vars->outer_scope != NULL)
+ return _slang_build_export_data_table(tbl, vars->outer_scope);
+ return GL_TRUE;
}
-
diff --git a/src/mesa/shader/slang/slang_compile_variable.h b/src/mesa/shader/slang/slang_compile_variable.h
index 6b9679a3b7..b0910e855e 100644
--- a/src/mesa/shader/slang/slang_compile_variable.h
+++ b/src/mesa/shader/slang/slang_compile_variable.h
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.2
*
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
*
@@ -22,74 +22,113 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#if !defined SLANG_COMPILE_VARIABLE_H
+#ifndef SLANG_COMPILE_VARIABLE_H
#define SLANG_COMPILE_VARIABLE_H
#if defined __cplusplus
extern "C" {
#endif
+
typedef enum slang_type_qualifier_
{
- slang_qual_none,
- slang_qual_const,
- slang_qual_attribute,
- slang_qual_varying,
- slang_qual_uniform,
- slang_qual_out,
- slang_qual_inout,
- slang_qual_fixedoutput, /* internal */
- slang_qual_fixedinput /* internal */
+ slang_qual_none,
+ slang_qual_const,
+ slang_qual_attribute,
+ slang_qual_varying,
+ slang_qual_uniform,
+ slang_qual_out,
+ slang_qual_inout,
+ slang_qual_fixedoutput, /* internal */
+ slang_qual_fixedinput /* internal */
} slang_type_qualifier;
-slang_type_specifier_type slang_type_specifier_type_from_string (const char *);
-const char *slang_type_specifier_type_to_string (slang_type_specifier_type);
+extern slang_type_specifier_type
+slang_type_specifier_type_from_string(const char *);
+
+extern const char *
+slang_type_specifier_type_to_string(slang_type_specifier_type);
+
+
typedef struct slang_fully_specified_type_
{
- slang_type_qualifier qualifier;
- slang_type_specifier specifier;
+ slang_type_qualifier qualifier;
+ slang_type_specifier specifier;
} slang_fully_specified_type;
-int slang_fully_specified_type_construct (slang_fully_specified_type *);
-void slang_fully_specified_type_destruct (slang_fully_specified_type *);
-int slang_fully_specified_type_copy (slang_fully_specified_type *, const slang_fully_specified_type *);
+extern int
+slang_fully_specified_type_construct(slang_fully_specified_type *);
+
+extern void
+slang_fully_specified_type_destruct(slang_fully_specified_type *);
+
+extern int
+slang_fully_specified_type_copy(slang_fully_specified_type *,
+ const slang_fully_specified_type *);
+
+
+/**
+ * A shading language program variable.
+ */
+typedef struct slang_variable_
+{
+ slang_fully_specified_type type; /**< Variable's data type */
+ slang_atom a_name; /**< The variable's name (char *) */
+ GLuint array_len; /**< only if type == slang_spec_array */
+ struct slang_operation_ *initializer; /**< Optional initializer code */
+ GLuint address; /**< Storage location */
+ GLuint address2; /**< Storage location */
+ GLuint size; /**< Variable's size in bytes */
+ GLboolean global; /**< A global var? */
+ void *aux; /**< Used during code gen */
+} slang_variable;
+
+/**
+ * Basically a list of variables, with a pointer to the parent scope.
+ */
typedef struct slang_variable_scope_
{
- struct slang_variable_ *variables;
+ slang_variable *variables; /**< Array [num_variables] */
GLuint num_variables;
- struct slang_variable_scope_ *outer_scope;
+ struct slang_variable_scope_ *outer_scope;
} slang_variable_scope;
extern GLvoid
-_slang_variable_scope_ctr (slang_variable_scope *);
+_slang_variable_scope_ctr(slang_variable_scope *);
-void slang_variable_scope_destruct (slang_variable_scope *);
-int slang_variable_scope_copy (slang_variable_scope *, const slang_variable_scope *);
+extern void
+slang_variable_scope_destruct(slang_variable_scope *);
-typedef struct slang_variable_
-{
- slang_fully_specified_type type;
- slang_atom a_name;
- GLuint array_len; /* type: spec_array */
- struct slang_operation_ *initializer;
- unsigned int address;
- unsigned int size;
- int global;
-} slang_variable;
+extern int
+slang_variable_scope_copy(slang_variable_scope *,
+ const slang_variable_scope *);
+
+slang_variable *
+slang_variable_scope_grow(slang_variable_scope *);
-int slang_variable_construct (slang_variable *);
-void slang_variable_destruct (slang_variable *);
-int slang_variable_copy (slang_variable *, const slang_variable *);
+extern int
+slang_variable_construct(slang_variable *);
+
+extern void
+slang_variable_destruct(slang_variable *);
+
+extern int
+slang_variable_copy(slang_variable *, const slang_variable *);
+
+extern slang_variable *
+_slang_locate_variable(const slang_variable_scope *, const slang_atom a_name,
+ GLboolean all);
+
+extern GLboolean
+_slang_build_export_data_table(slang_export_data_table *,
+ slang_variable_scope *);
-slang_variable *_slang_locate_variable (slang_variable_scope *, slang_atom a_name, GLboolean all);
-GLboolean _slang_build_export_data_table (slang_export_data_table *, slang_variable_scope *);
#ifdef __cplusplus
}
#endif
-#endif
-
+#endif /* SLANG_COMPILE_VARIABLE_H */
diff --git a/src/mesa/shader/slang/slang_execute.c b/src/mesa/shader/slang/slang_execute.c
index 98bfd896c4..e469de0207 100644
--- a/src/mesa/shader/slang/slang_execute.c
+++ b/src/mesa/shader/slang/slang_execute.c
@@ -36,571 +36,625 @@
#define DEBUG_SLANG 0
-GLvoid slang_machine_ctr (slang_machine *self)
+GLvoid
+slang_machine_ctr(slang_machine * self)
{
- slang_machine_init (self);
+ slang_machine_init(self);
self->infolog = NULL;
#if defined(USE_X86_ASM) || defined(SLANG_X86)
- self->x86.compiled_func = NULL;
+ self->x86.compiled_func = NULL;
#endif
}
-GLvoid slang_machine_dtr (slang_machine *self)
+GLvoid
+slang_machine_dtr(slang_machine * self)
{
if (self->infolog != NULL) {
- slang_info_log_destruct (self->infolog);
- slang_alloc_free (self->infolog);
+ slang_info_log_destruct(self->infolog);
+ slang_alloc_free(self->infolog);
}
#if defined(USE_X86_ASM) || defined(SLANG_X86)
- if (self->x86.compiled_func != NULL)
- _mesa_exec_free (self->x86.compiled_func);
+ if (self->x86.compiled_func != NULL)
+ _mesa_exec_free(self->x86.compiled_func);
#endif
}
-void slang_machine_init (slang_machine *mach)
+
+/**
+ * Initialize the shader virtual machine.
+ * NOTE: stack grows downward in memory.
+ */
+void
+slang_machine_init(slang_machine * mach)
{
- mach->ip = 0;
- mach->sp = SLANG_MACHINE_STACK_SIZE;
- mach->bp = 0;
- mach->kill = 0;
- mach->exit = 0;
+ mach->ip = 0;
+ mach->sp = SLANG_MACHINE_STACK_SIZE;
+ mach->bp = 0;
+ mach->kill = GL_FALSE;
+ mach->exit = GL_FALSE;
}
#if DEBUG_SLANG
-static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i)
+static void
+dump_instruction(FILE * f, slang_assembly * a, unsigned int i)
{
- fprintf (f, "%.5u:\t", i);
-
- switch (a->type)
- {
- /* core */
- case slang_asm_none:
- fprintf (f, "none");
- break;
- case slang_asm_float_copy:
- fprintf (f, "float_copy\t%d, %d", a->param[0], a->param[1]);
- break;
- case slang_asm_float_move:
- fprintf (f, "float_move\t%d, %d", a->param[0], a->param[1]);
- break;
- case slang_asm_float_push:
- fprintf (f, "float_push\t%f", a->literal);
- break;
- case slang_asm_float_deref:
- fprintf (f, "float_deref");
- break;
- case slang_asm_float_add:
- fprintf (f, "float_add");
- break;
- case slang_asm_float_multiply:
- fprintf (f, "float_multiply");
- break;
- case slang_asm_float_divide:
- fprintf (f, "float_divide");
- break;
- case slang_asm_float_negate:
- fprintf (f, "float_negate");
- break;
- case slang_asm_float_less:
- fprintf (f, "float_less");
- break;
- case slang_asm_float_equal_exp:
- fprintf (f, "float_equal");
- break;
- case slang_asm_float_equal_int:
- fprintf (f, "float_equal\t%d, %d", a->param[0], a->param[1]);
- break;
- case slang_asm_float_to_int:
- fprintf (f, "float_to_int");
- break;
- case slang_asm_float_sine:
- fprintf (f, "float_sine");
- break;
- case slang_asm_float_arcsine:
- fprintf (f, "float_arcsine");
- break;
- case slang_asm_float_arctan:
- fprintf (f, "float_arctan");
- break;
- case slang_asm_float_power:
- fprintf (f, "float_power");
- break;
- case slang_asm_float_log2:
- fprintf (f, "float_log2");
- break;
- case slang_asm_float_floor:
- fprintf (f, "float_floor");
- break;
- case slang_asm_float_ceil:
- fprintf (f, "float_ceil");
- break;
- case slang_asm_float_noise1:
- fprintf (f, "float_noise1");
- break;
- case slang_asm_float_noise2:
- fprintf (f, "float_noise2");
- break;
- case slang_asm_float_noise3:
- fprintf (f, "float_noise3");
- break;
- case slang_asm_float_noise4:
- fprintf (f, "float_noise4");
- break;
- case slang_asm_int_copy:
- fprintf (f, "int_copy\t%d, %d", a->param[0], a->param[1]);
- break;
- case slang_asm_int_move:
- fprintf (f, "int_move\t%d, %d", a->param[0], a->param[1]);
- break;
- case slang_asm_int_push:
- fprintf (f, "int_push\t%d", (GLint) a->literal);
- break;
- case slang_asm_int_deref:
- fprintf (f, "int_deref");
- break;
- case slang_asm_int_to_float:
- fprintf (f, "int_to_float");
- break;
- case slang_asm_int_to_addr:
- fprintf (f, "int_to_addr");
- break;
- case slang_asm_bool_copy:
- fprintf (f, "bool_copy\t%d, %d", a->param[0], a->param[1]);
- break;
- case slang_asm_bool_move:
- fprintf (f, "bool_move\t%d, %d", a->param[0], a->param[1]);
- break;
- case slang_asm_bool_push:
- fprintf (f, "bool_push\t%d", a->literal != 0.0f);
- break;
- case slang_asm_bool_deref:
- fprintf (f, "bool_deref");
- break;
- case slang_asm_addr_copy:
- fprintf (f, "addr_copy");
- break;
- case slang_asm_addr_push:
- fprintf (f, "addr_push\t%u", a->param[0]);
- break;
- case slang_asm_addr_deref:
- fprintf (f, "addr_deref");
- break;
- case slang_asm_addr_add:
- fprintf (f, "addr_add");
- break;
- case slang_asm_addr_multiply:
- fprintf (f, "addr_multiply");
- break;
- case slang_asm_vec4_tex1d:
- fprintf (f, "vec4_tex1d");
- break;
- case slang_asm_vec4_tex2d:
- fprintf (f, "vec4_tex2d");
- break;
- case slang_asm_vec4_tex3d:
- fprintf (f, "vec4_tex3d");
- break;
- case slang_asm_vec4_texcube:
- fprintf (f, "vec4_texcube");
- break;
- case slang_asm_vec4_shad1d:
- fprintf (f, "vec4_shad1d");
- break;
- case slang_asm_vec4_shad2d:
- fprintf (f, "vec4_shad2d");
- break;
- case slang_asm_jump:
- fprintf (f, "jump\t%u", a->param[0]);
- break;
- case slang_asm_jump_if_zero:
- fprintf (f, "jump_if_zero\t%u", a->param[0]);
- break;
- case slang_asm_enter:
- fprintf (f, "enter\t%u", a->param[0]);
- break;
- case slang_asm_leave:
- fprintf (f, "leave");
- break;
- case slang_asm_local_alloc:
- fprintf (f, "local_alloc\t%u", a->param[0]);
- break;
- case slang_asm_local_free:
- fprintf (f, "local_free\t%u", a->param[0]);
- break;
- case slang_asm_local_addr:
- fprintf (f, "local_addr\t%u, %u", a->param[0], a->param[1]);
- break;
- case slang_asm_global_addr:
- fprintf (f, "global_addr\t%u", a->param[0]);
- break;
- case slang_asm_call:
- fprintf (f, "call\t%u", a->param[0]);
- break;
- case slang_asm_return:
- fprintf (f, "return");
- break;
- case slang_asm_discard:
- fprintf (f, "discard");
- break;
- case slang_asm_exit:
- fprintf (f, "exit");
- break;
- /* GL_MESA_shader_debug */
- case slang_asm_float_print:
- fprintf (f, "float_print");
- break;
- case slang_asm_int_print:
- fprintf (f, "int_print");
- break;
- case slang_asm_bool_print:
- fprintf (f, "bool_print");
- break;
- /* vec4 */
+ fprintf(f, "%.5u:\t", i);
+
+ switch (a->type) {
+ /* core */
+ case slang_asm_none:
+ fprintf(f, "none");
+ break;
+ case slang_asm_float_copy:
+ fprintf(f, "float_copy\t%d, %d", a->param[0], a->param[1]);
+ break;
+ case slang_asm_float_move:
+ fprintf(f, "float_move\t%d, %d", a->param[0], a->param[1]);
+ break;
+ case slang_asm_float_push:
+ fprintf(f, "float_push\t%f", a->literal);
+ break;
+ case slang_asm_float_deref:
+ fprintf(f, "float_deref");
+ break;
+ case slang_asm_float_add:
+ fprintf(f, "float_add");
+ break;
+ case slang_asm_float_multiply:
+ fprintf(f, "float_multiply");
+ break;
+ case slang_asm_float_divide:
+ fprintf(f, "float_divide");
+ break;
+ case slang_asm_float_negate:
+ fprintf(f, "float_negate");
+ break;
+ case slang_asm_float_less:
+ fprintf(f, "float_less");
+ break;
+ case slang_asm_float_equal_exp:
+ fprintf(f, "float_equal");
+ break;
+ case slang_asm_float_equal_int:
+ fprintf(f, "float_equal\t%d, %d", a->param[0], a->param[1]);
+ break;
+ case slang_asm_float_to_int:
+ fprintf(f, "float_to_int");
+ break;
+ case slang_asm_float_sine:
+ fprintf(f, "float_sine");
+ break;
+ case slang_asm_float_arcsine:
+ fprintf(f, "float_arcsine");
+ break;
+ case slang_asm_float_arctan:
+ fprintf(f, "float_arctan");
+ break;
+ case slang_asm_float_power:
+ fprintf(f, "float_power");
+ break;
+ case slang_asm_float_log2:
+ fprintf(f, "float_log2");
+ break;
+ case slang_asm_float_floor:
+ fprintf(f, "float_floor");
+ break;
+ case slang_asm_float_ceil:
+ fprintf(f, "float_ceil");
+ break;
+ case slang_asm_float_noise1:
+ fprintf(f, "float_noise1");
+ break;
+ case slang_asm_float_noise2:
+ fprintf(f, "float_noise2");
+ break;
+ case slang_asm_float_noise3:
+ fprintf(f, "float_noise3");
+ break;
+ case slang_asm_float_noise4:
+ fprintf(f, "float_noise4");
+ break;
+ case slang_asm_int_copy:
+ fprintf(f, "int_copy\t%d, %d", a->param[0], a->param[1]);
+ break;
+ case slang_asm_int_move:
+ fprintf(f, "int_move\t%d, %d", a->param[0], a->param[1]);
+ break;
+ case slang_asm_int_push:
+ fprintf(f, "int_push\t%d", (GLint) a->literal);
+ break;
+ case slang_asm_int_deref:
+ fprintf(f, "int_deref");
+ break;
+ case slang_asm_int_to_float:
+ fprintf(f, "int_to_float");
+ break;
+ case slang_asm_int_to_addr:
+ fprintf(f, "int_to_addr");
+ break;
+ case slang_asm_bool_copy:
+ fprintf(f, "bool_copy\t%d, %d", a->param[0], a->param[1]);
+ break;
+ case slang_asm_bool_move:
+ fprintf(f, "bool_move\t%d, %d", a->param[0], a->param[1]);
+ break;
+ case slang_asm_bool_push:
+ fprintf(f, "bool_push\t%d", a->literal != 0.0f);
+ break;
+ case slang_asm_bool_deref:
+ fprintf(f, "bool_deref");
+ break;
+ case slang_asm_addr_copy:
+ fprintf(f, "addr_copy");
+ break;
+ case slang_asm_addr_push:
+ fprintf(f, "addr_push\t%u", a->param[0]);
+ break;
+ case slang_asm_addr_deref:
+ fprintf(f, "addr_deref");
+ break;
+ case slang_asm_addr_add:
+ fprintf(f, "addr_add");
+ break;
+ case slang_asm_addr_multiply:
+ fprintf(f, "addr_multiply");
+ break;
+ case slang_asm_vec4_tex1d:
+ fprintf(f, "vec4_tex1d");
+ break;
+ case slang_asm_vec4_tex2d:
+ fprintf(f, "vec4_tex2d");
+ break;
+ case slang_asm_vec4_tex3d:
+ fprintf(f, "vec4_tex3d");
+ break;
+ case slang_asm_vec4_texcube:
+ fprintf(f, "vec4_texcube");
+ break;
+ case slang_asm_vec4_shad1d:
+ fprintf(f, "vec4_shad1d");
+ break;
+ case slang_asm_vec4_shad2d:
+ fprintf(f, "vec4_shad2d");
+ break;
+ case slang_asm_jump:
+ fprintf(f, "jump\t%u", a->param[0]);
+ break;
+ case slang_asm_jump_if_zero:
+ fprintf(f, "jump_if_zero\t%u", a->param[0]);
+ break;
+ case slang_asm_enter:
+ fprintf(f, "enter\t%u", a->param[0]);
+ break;
+ case slang_asm_leave:
+ fprintf(f, "leave");
+ break;
+ case slang_asm_local_alloc:
+ fprintf(f, "local_alloc\t%u", a->param[0]);
+ break;
+ case slang_asm_local_free:
+ fprintf(f, "local_free\t%u", a->param[0]);
+ break;
+ case slang_asm_local_addr:
+ fprintf(f, "local_addr\t%u, %u", a->param[0], a->param[1]);
+ break;
+ case slang_asm_global_addr:
+ fprintf(f, "global_addr\t%u", a->param[0]);
+ break;
+ case slang_asm_call:
+ fprintf(f, "call\t%u", a->param[0]);
+ break;
+ case slang_asm_return:
+ fprintf(f, "return");
+ break;
+ case slang_asm_discard:
+ fprintf(f, "discard");
+ break;
+ case slang_asm_exit:
+ fprintf(f, "exit");
+ break;
+ /* GL_MESA_shader_debug */
+ case slang_asm_float_print:
+ fprintf(f, "float_print");
+ break;
+ case slang_asm_int_print:
+ fprintf(f, "int_print");
+ break;
+ case slang_asm_bool_print:
+ fprintf(f, "bool_print");
+ break;
+ /* vec4 */
case slang_asm_float_to_vec4:
- fprintf (f, "float_to_vec4");
+ fprintf(f, "float_to_vec4");
break;
case slang_asm_vec4_add:
- fprintf (f, "vec4_add");
+ fprintf(f, "vec4_add");
break;
case slang_asm_vec4_subtract:
- fprintf (f, "vec4_subtract");
+ fprintf(f, "vec4_subtract");
break;
case slang_asm_vec4_multiply:
- fprintf (f, "vec4_multiply");
+ fprintf(f, "vec4_multiply");
break;
case slang_asm_vec4_divide:
- fprintf (f, "vec4_divide");
+ fprintf(f, "vec4_divide");
break;
case slang_asm_vec4_negate:
- fprintf (f, "vec4_negate");
+ fprintf(f, "vec4_negate");
break;
case slang_asm_vec4_dot:
- fprintf (f, "vec4_dot");
+ fprintf(f, "vec4_dot");
break;
case slang_asm_vec4_copy:
- fprintf (f, "vec4_copy");
+ fprintf(f, "vec4_copy");
break;
case slang_asm_vec4_deref:
- fprintf (f, "vec4_deref");
+ fprintf(f, "vec4_deref");
break;
case slang_asm_vec4_equal_int:
- fprintf (f, "vec4_equal");
+ fprintf(f, "vec4_equal");
break;
default:
- break;
- }
+ break;
+ }
- fprintf (f, "\n");
+ fprintf(f, "\n");
}
-static void dump (const slang_assembly_file *file)
+static void
+dump(const slang_assembly_file * file)
{
- unsigned int i;
- static unsigned int counter = 0;
- FILE *f;
- char filename[256];
+ unsigned int i;
+ static unsigned int counter = 0;
+ FILE *f;
+ char filename[256];
- counter++;
- _mesa_sprintf (filename, "~mesa-slang-assembly-dump-(%u).txt", counter);
- f = fopen (filename, "w");
- if (f == NULL)
- return;
+ counter++;
+ _mesa_sprintf(filename, "~mesa-slang-assembly-dump-(%u).txt", counter);
+ f = fopen(filename, "w");
+ if (f == NULL)
+ return;
- for (i = 0; i < file->count; i++)
- dump_instruction (f, file->code + i, i);
+ for (i = 0; i < file->count; i++)
+ dump_instruction(f, file->code + i, i);
- fclose (f);
+ fclose(f);
}
#endif
static GLvoid
-ensure_infolog_created (slang_info_log **infolog)
+ensure_infolog_created(slang_info_log ** infolog)
{
if (*infolog == NULL) {
- *infolog = slang_alloc_malloc (sizeof (slang_info_log));
+ *infolog = slang_alloc_malloc(sizeof(slang_info_log));
if (*infolog == NULL)
return;
- slang_info_log_construct (*infolog);
+ slang_info_log_construct(*infolog);
}
}
GLboolean
-_slang_execute2 (const slang_assembly_file *file, slang_machine *mach)
+_slang_execute2(const slang_assembly_file * file, slang_machine * mach)
{
- slang_machine_slot *stack;
+ slang_machine_slot *stack;
#if DEBUG_SLANG
- static unsigned int counter = 0;
- char filename[256];
- FILE *f;
+ static unsigned int counter = 0;
+ char filename[256];
+ FILE *f;
#endif
- /* assume 32-bit floats and uints; should work fine also on 64-bit platforms */
- static_assert(sizeof (GLfloat) == 4);
- static_assert(sizeof (GLuint) == 4);
+ /* assume 32-bit floats and uints; should work fine also on 64-bit platforms */
+ static_assert(sizeof(GLfloat) == 4);
+ static_assert(sizeof(GLuint) == 4);
#if DEBUG_SLANG
- dump (file);
- counter++;
- _mesa_sprintf (filename, "~mesa-slang-assembly-exec-(%u).txt", counter);
- f = fopen (filename, "w");
+ dump(file);
+ counter++;
+ _mesa_sprintf(filename, "~mesa-slang-assembly-exec-(%u).txt", counter);
+ f = fopen(filename, "w");
#endif
#if defined(USE_X86_ASM) || defined(SLANG_X86)
- if (mach->x86.compiled_func != NULL)
- {
- mach->x86.compiled_func (mach);
- return GL_TRUE;
- }
+ if (mach->x86.compiled_func != NULL) {
+ mach->x86.compiled_func(mach);
+ return GL_TRUE;
+ }
#endif
- stack = mach->mem + SLANG_MACHINE_GLOBAL_SIZE;
+ stack = mach->mem + SLANG_MACHINE_GLOBAL_SIZE;
- while (!mach->exit)
- {
- slang_assembly *a = &file->code[mach->ip];
+ while (!mach->exit) {
+ const slang_assembly *a = &file->code[mach->ip];
#if DEBUG_SLANG
- if (f != NULL && a->type != slang_asm_none)
- {
- unsigned int i;
+ if (f != NULL && a->type != slang_asm_none) {
+ unsigned int i;
- dump_instruction (f, file->code + mach->ip, mach->ip);
- fprintf (f, "\t\tsp=%u bp=%u\n", mach->sp, mach->bp);
- for (i = mach->sp; i < SLANG_MACHINE_STACK_SIZE; i++)
- fprintf (f, "\t%.5u\t%6f\t%u\n", i, stack[i]._float, stack[i]._addr);
- fflush (f);
- }
+ dump_instruction(f, file->code + mach->ip, mach->ip);
+ fprintf(f, "\t\tsp=%u bp=%u\n", mach->sp, mach->bp);
+ for (i = mach->sp; i < SLANG_MACHINE_STACK_SIZE; i++)
+ fprintf(f, "\t%.5u\t%6f\t%u\n", i, stack[i]._float,
+ stack[i]._addr);
+ fflush(f);
+ }
#endif
- mach->ip++;
+ mach->ip++;
- switch (a->type)
- {
- /* core */
- case slang_asm_none:
- break;
- case slang_asm_float_copy:
- case slang_asm_int_copy:
- case slang_asm_bool_copy:
- mach->mem[(stack[mach->sp + a->param[0] / 4]._addr + a->param[1]) / 4]._float =
- stack[mach->sp]._float;
- mach->sp++;
- break;
- case slang_asm_float_move:
- case slang_asm_int_move:
- case slang_asm_bool_move:
- stack[mach->sp + a->param[0] / 4]._float =
- stack[mach->sp + (stack[mach->sp]._addr + a->param[1]) / 4]._float;
- break;
- case slang_asm_float_push:
- case slang_asm_int_push:
- case slang_asm_bool_push:
- mach->sp--;
- stack[mach->sp]._float = a->literal;
- break;
- case slang_asm_float_deref:
- case slang_asm_int_deref:
- case slang_asm_bool_deref:
- stack[mach->sp]._float = mach->mem[stack[mach->sp]._addr / 4]._float;
- break;
- case slang_asm_float_add:
- stack[mach->sp + 1]._float += stack[mach->sp]._float;
- mach->sp++;
- break;
- case slang_asm_float_multiply:
- stack[mach->sp + 1]._float *= stack[mach->sp]._float;
- mach->sp++;
- break;
- case slang_asm_float_divide:
- stack[mach->sp + 1]._float /= stack[mach->sp]._float;
- mach->sp++;
- break;
- case slang_asm_float_negate:
- stack[mach->sp]._float = -stack[mach->sp]._float;
- break;
- case slang_asm_float_less:
- stack[mach->sp + 1]._float =
- stack[mach->sp + 1]._float < stack[mach->sp]._float ? (GLfloat) 1 : (GLfloat) 0;
- mach->sp++;
- break;
- case slang_asm_float_equal_exp:
- stack[mach->sp + 1]._float =
- stack[mach->sp + 1]._float == stack[mach->sp]._float ? (GLfloat) 1 : (GLfloat) 0;
- mach->sp++;
- break;
- case slang_asm_float_equal_int:
- mach->sp--;
- stack[mach->sp]._float = stack[mach->sp + 1 + a->param[0] / 4]._float ==
- stack[mach->sp + 1 + a->param[1] / 4]._float ? (GLfloat) 1 : (GLfloat) 0;
- break;
- case slang_asm_float_to_int:
- stack[mach->sp]._float = (GLfloat) (GLint) stack[mach->sp]._float;
- break;
- case slang_asm_float_sine:
- stack[mach->sp]._float = (GLfloat) _mesa_sin (stack[mach->sp]._float);
- break;
- case slang_asm_float_arcsine:
- stack[mach->sp]._float = _mesa_asinf (stack[mach->sp]._float);
- break;
- case slang_asm_float_arctan:
- stack[mach->sp]._float = _mesa_atanf (stack[mach->sp]._float);
- break;
- case slang_asm_float_power:
- stack[mach->sp + 1]._float =
- (GLfloat) _mesa_pow (stack[mach->sp + 1]._float, stack[mach->sp]._float);
- mach->sp++;
- break;
- case slang_asm_float_log2:
- stack[mach->sp]._float = LOG2 (stack[mach->sp]._float);
- break;
- case slang_asm_float_floor:
- stack[mach->sp]._float = FLOORF (stack[mach->sp]._float);
- break;
- case slang_asm_float_ceil:
- stack[mach->sp]._float = CEILF (stack[mach->sp]._float);
- break;
- case slang_asm_float_noise1:
- stack[mach->sp]._float = _slang_library_noise1 (stack[mach->sp]._float);
- break;
- case slang_asm_float_noise2:
- stack[mach->sp + 1]._float = _slang_library_noise2 (stack[mach->sp]._float,
- stack[mach->sp + 1]._float);
- mach->sp++;
- break;
- case slang_asm_float_noise3:
- stack[mach->sp + 2]._float = _slang_library_noise3 (stack[mach->sp]._float,
- stack[mach->sp + 1]._float, stack[mach->sp + 2]._float);
- mach->sp += 2;
- break;
- case slang_asm_float_noise4:
- stack[mach->sp + 3]._float = _slang_library_noise4 (stack[mach->sp]._float,
- stack[mach->sp + 1]._float, stack[mach->sp + 2]._float, stack[mach->sp + 3]._float);
- mach->sp += 3;
- break;
- case slang_asm_int_to_float:
- break;
- case slang_asm_int_to_addr:
- stack[mach->sp]._addr = (GLuint) (GLint) stack[mach->sp]._float;
- break;
- case slang_asm_addr_copy:
- mach->mem[stack[mach->sp + 1]._addr / 4]._addr = stack[mach->sp]._addr;
- mach->sp++;
- break;
- case slang_asm_addr_push:
- case slang_asm_global_addr:
- mach->sp--;
- stack[mach->sp]._addr = a->param[0];
- break;
- case slang_asm_addr_deref:
- stack[mach->sp]._addr = mach->mem[stack[mach->sp]._addr / 4]._addr;
- break;
- case slang_asm_addr_add:
- stack[mach->sp + 1]._addr += stack[mach->sp]._addr;
- mach->sp++;
- break;
- case slang_asm_addr_multiply:
- stack[mach->sp + 1]._addr *= stack[mach->sp]._addr;
- mach->sp++;
- break;
- case slang_asm_vec4_tex1d:
- _slang_library_tex1d (stack[mach->sp]._float, stack[mach->sp + 1]._float,
- stack[mach->sp + 2]._float, &mach->mem[stack[mach->sp + 3]._addr / 4]._float);
- mach->sp += 3;
- break;
- case slang_asm_vec4_tex2d:
- _slang_library_tex2d (stack[mach->sp]._float, stack[mach->sp + 1]._float,
- stack[mach->sp + 2]._float, stack[mach->sp + 3]._float,
- &mach->mem[stack[mach->sp + 4]._addr / 4]._float);
- mach->sp += 4;
- break;
- case slang_asm_vec4_tex3d:
- _slang_library_tex3d (stack[mach->sp]._float, stack[mach->sp + 1]._float,
- stack[mach->sp + 2]._float, stack[mach->sp + 3]._float, stack[mach->sp + 4]._float,
- &mach->mem[stack[mach->sp + 5]._addr / 4]._float);
- mach->sp += 5;
- break;
- case slang_asm_vec4_texcube:
- _slang_library_texcube (stack[mach->sp]._float, stack[mach->sp + 1]._float,
- stack[mach->sp + 2]._float, stack[mach->sp + 3]._float, stack[mach->sp + 4]._float,
- &mach->mem[stack[mach->sp + 5]._addr / 4]._float);
- mach->sp += 5;
- break;
- case slang_asm_vec4_shad1d:
- _slang_library_shad1d (stack[mach->sp]._float, stack[mach->sp + 1]._float,
- stack[mach->sp + 2]._float, stack[mach->sp + 3]._float, stack[mach->sp + 4]._float,
- &mach->mem[stack[mach->sp + 5]._addr / 4]._float);
- mach->sp += 5;
- break;
- case slang_asm_vec4_shad2d:
- _slang_library_shad2d (stack[mach->sp]._float, stack[mach->sp + 1]._float,
- stack[mach->sp + 2]._float, stack[mach->sp + 3]._float, stack[mach->sp + 4]._float,
- &mach->mem[stack[mach->sp + 5]._addr / 4]._float);
- mach->sp += 5;
- break;
- case slang_asm_jump:
- mach->ip = a->param[0];
- break;
- case slang_asm_jump_if_zero:
- if (stack[mach->sp]._float == 0.0f)
- mach->ip = a->param[0];
- mach->sp++;
- break;
- case slang_asm_enter:
- mach->sp--;
- stack[mach->sp]._addr = mach->bp;
- mach->bp = mach->sp + a->param[0] / 4;
- break;
- case slang_asm_leave:
- mach->bp = stack[mach->sp]._addr;
- mach->sp++;
- break;
- case slang_asm_local_alloc:
- mach->sp -= a->param[0] / 4;
- break;
- case slang_asm_local_free:
- mach->sp += a->param[0] / 4;
- break;
- case slang_asm_local_addr:
- mach->sp--;
- stack[mach->sp]._addr = SLANG_MACHINE_GLOBAL_SIZE * 4 + mach->bp * 4 -
- (a->param[0] + a->param[1]) + 4;
- break;
- case slang_asm_call:
- mach->sp--;
- stack[mach->sp]._addr = mach->ip;
- mach->ip = a->param[0];
- break;
- case slang_asm_return:
- mach->ip = stack[mach->sp]._addr;
- mach->sp++;
- break;
- case slang_asm_discard:
- mach->kill = 1;
- break;
- case slang_asm_exit:
- mach->exit = 1;
- break;
- /* GL_MESA_shader_debug */
- case slang_asm_float_print:
- _mesa_printf ("slang print: %f\n", stack[mach->sp]._float);
- ensure_infolog_created (&mach->infolog);
- slang_info_log_print (mach->infolog, "%f", stack[mach->sp]._float);
- break;
- case slang_asm_int_print:
- _mesa_printf ("slang print: %d\n", (GLint) stack[mach->sp]._float);
- ensure_infolog_created (&mach->infolog);
- slang_info_log_print (mach->infolog, "%d", (GLint) (stack[mach->sp]._float));
- break;
- case slang_asm_bool_print:
- _mesa_printf ("slang print: %s\n", (GLint) stack[mach->sp]._float ? "true" : "false");
- ensure_infolog_created (&mach->infolog);
- slang_info_log_print (mach->infolog, "%s",
- (GLint) (stack[mach->sp]._float) ? "true" : "false");
- break;
- /* vec4 */
+ switch (a->type) {
+ /* core */
+ case slang_asm_none:
+ break;
+ case slang_asm_float_copy:
+ case slang_asm_int_copy:
+ case slang_asm_bool_copy:
+ /* store top value on stack to memory */
+ {
+ GLuint address
+ = (stack[mach->sp + a->param[0] / 4]._addr + a->param[1]) / 4;
+ GLfloat value = stack[mach->sp]._float;
+ mach->mem[address]._float = value;
+ }
+ mach->sp++;
+ break;
+ case slang_asm_float_move:
+ case slang_asm_int_move:
+ case slang_asm_bool_move:
+ stack[mach->sp + a->param[0] / 4]._float =
+ stack[mach->sp +
+ (stack[mach->sp]._addr + a->param[1]) / 4]._float;
+ break;
+ case slang_asm_float_push:
+ case slang_asm_int_push:
+ case slang_asm_bool_push:
+ /* push float/int/bool literal onto stop of stack */
+ mach->sp--;
+ stack[mach->sp]._float = a->literal;
+ break;
+ case slang_asm_float_deref:
+ case slang_asm_int_deref:
+ case slang_asm_bool_deref:
+ /* load value from memory, replace stop of stack with it */
+ stack[mach->sp]._float = mach->mem[stack[mach->sp]._addr / 4]._float;
+ break;
+ case slang_asm_float_add:
+ /* pop two top floats, push sum */
+ stack[mach->sp + 1]._float += stack[mach->sp]._float;
+ mach->sp++;
+ break;
+ case slang_asm_float_multiply:
+ stack[mach->sp + 1]._float *= stack[mach->sp]._float;
+ mach->sp++;
+ break;
+ case slang_asm_float_divide:
+ stack[mach->sp + 1]._float /= stack[mach->sp]._float;
+ mach->sp++;
+ break;
+ case slang_asm_float_negate:
+ stack[mach->sp]._float = -stack[mach->sp]._float;
+ break;
+ case slang_asm_float_less:
+ stack[mach->sp + 1]._float =
+ (stack[mach->sp + 1]._float < stack[mach->sp]._float)
+ ? (GLfloat) 1 : (GLfloat) 0;
+ mach->sp++;
+ break;
+ case slang_asm_float_equal_exp:
+ stack[mach->sp + 1]._float =
+ (stack[mach->sp + 1]._float == stack[mach->sp]._float)
+ ? (GLfloat) 1 : (GLfloat) 0;
+ mach->sp++;
+ break;
+ case slang_asm_float_equal_int:
+ /* pop top two values, compare, push 0 or 1 */
+ mach->sp--;
+ stack[mach->sp]._float =
+ (stack[mach->sp + 1 + a->param[0] / 4]._float ==
+ stack[mach->sp + 1 + a->param[1] / 4]._float)
+ ? (GLfloat) 1 : (GLfloat) 0;
+ break;
+ case slang_asm_float_to_int:
+ stack[mach->sp]._float = (GLfloat) (GLint) stack[mach->sp]._float;
+ break;
+ case slang_asm_float_sine:
+ stack[mach->sp]._float = (GLfloat) _mesa_sin(stack[mach->sp]._float);
+ break;
+ case slang_asm_float_arcsine:
+ stack[mach->sp]._float = _mesa_asinf(stack[mach->sp]._float);
+ break;
+ case slang_asm_float_arctan:
+ stack[mach->sp]._float = _mesa_atanf(stack[mach->sp]._float);
+ break;
+ case slang_asm_float_power:
+ stack[mach->sp + 1]._float = (GLfloat)
+ _mesa_pow(stack[mach->sp + 1]._float, stack[mach->sp]._float);
+ mach->sp++;
+ break;
+ case slang_asm_float_log2:
+ stack[mach->sp]._float = LOG2(stack[mach->sp]._float);
+ break;
+ case slang_asm_float_floor:
+ stack[mach->sp]._float = FLOORF(stack[mach->sp]._float);
+ break;
+ case slang_asm_float_ceil:
+ stack[mach->sp]._float = CEILF(stack[mach->sp]._float);
+ break;
+ case slang_asm_float_noise1:
+ stack[mach->sp]._float =
+ _slang_library_noise1(stack[mach->sp]._float);
+ break;
+ case slang_asm_float_noise2:
+ stack[mach->sp + 1]._float =
+ _slang_library_noise2(stack[mach->sp]._float,
+ stack[mach->sp + 1]._float);
+ mach->sp++;
+ break;
+ case slang_asm_float_noise3:
+ stack[mach->sp + 2]._float =
+ _slang_library_noise3(stack[mach->sp]._float,
+ stack[mach->sp + 1]._float,
+ stack[mach->sp + 2]._float);
+ mach->sp += 2;
+ break;
+ case slang_asm_float_noise4:
+ stack[mach->sp + 3]._float =
+ _slang_library_noise4(stack[mach->sp]._float,
+ stack[mach->sp + 1]._float,
+ stack[mach->sp + 2]._float,
+ stack[mach->sp + 3]._float);
+ mach->sp += 3;
+ break;
+ case slang_asm_int_to_float:
+ break;
+ case slang_asm_int_to_addr:
+ stack[mach->sp]._addr = (GLuint) (GLint) stack[mach->sp]._float;
+ break;
+ case slang_asm_addr_copy:
+ mach->mem[stack[mach->sp + 1]._addr / 4]._addr =
+ stack[mach->sp]._addr;
+ mach->sp++;
+ break;
+ case slang_asm_addr_push:
+ case slang_asm_global_addr:
+ mach->sp--;
+ stack[mach->sp]._addr = a->param[0];
+ break;
+ case slang_asm_addr_deref:
+ stack[mach->sp]._addr = mach->mem[stack[mach->sp]._addr / 4]._addr;
+ break;
+ case slang_asm_addr_add:
+ stack[mach->sp + 1]._addr += stack[mach->sp]._addr;
+ mach->sp++;
+ break;
+ case slang_asm_addr_multiply:
+ stack[mach->sp + 1]._addr *= stack[mach->sp]._addr;
+ mach->sp++;
+ break;
+ case slang_asm_vec4_tex1d:
+ _slang_library_tex1d(stack[mach->sp]._float,
+ stack[mach->sp + 1]._float,
+ stack[mach->sp + 2]._float,
+ &mach->mem[stack[mach->sp + 3]._addr /
+ 4]._float);
+ mach->sp += 3;
+ break;
+ case slang_asm_vec4_tex2d:
+ _slang_library_tex2d(stack[mach->sp]._float,
+ stack[mach->sp + 1]._float,
+ stack[mach->sp + 2]._float,
+ stack[mach->sp + 3]._float,
+ &mach->mem[stack[mach->sp + 4]._addr /
+ 4]._float);
+ mach->sp += 4;
+ break;
+ case slang_asm_vec4_tex3d:
+ _slang_library_tex3d(stack[mach->sp]._float,
+ stack[mach->sp + 1]._float,
+ stack[mach->sp + 2]._float,
+ stack[mach->sp + 3]._float,
+ stack[mach->sp + 4]._float,
+ &mach->mem[stack[mach->sp + 5]._addr /
+ 4]._float);
+ mach->sp += 5;
+ break;
+ case slang_asm_vec4_texcube:
+ _slang_library_texcube(stack[mach->sp]._float,
+ stack[mach->sp + 1]._float,
+ stack[mach->sp + 2]._float,
+ stack[mach->sp + 3]._float,
+ stack[mach->sp + 4]._float,
+ &mach->mem[stack[mach->sp + 5]._addr /
+ 4]._float);
+ mach->sp += 5;
+ break;
+ case slang_asm_vec4_shad1d:
+ _slang_library_shad1d(stack[mach->sp]._float,
+ stack[mach->sp + 1]._float,
+ stack[mach->sp + 2]._float,
+ stack[mach->sp + 3]._float,
+ stack[mach->sp + 4]._float,
+ &mach->mem[stack[mach->sp + 5]._addr /
+ 4]._float);
+ mach->sp += 5;
+ break;
+ case slang_asm_vec4_shad2d:
+ _slang_library_shad2d(stack[mach->sp]._float,
+ stack[mach->sp + 1]._float,
+ stack[mach->sp + 2]._float,
+ stack[mach->sp + 3]._float,
+ stack[mach->sp + 4]._float,
+ &mach->mem[stack[mach->sp + 5]._addr /
+ 4]._float);
+ mach->sp += 5;
+ break;
+ case slang_asm_jump:
+ mach->ip = a->param[0];
+ break;
+ case slang_asm_jump_if_zero:
+ if (stack[mach->sp]._float == 0.0f)
+ mach->ip = a->param[0];
+ mach->sp++;
+ break;
+ case slang_asm_enter:
+ mach->sp--;
+ stack[mach->sp]._addr = mach->bp;
+ mach->bp = mach->sp + a->param[0] / 4;
+ break;
+ case slang_asm_leave:
+ mach->bp = stack[mach->sp]._addr;
+ mach->sp++;
+ break;
+ case slang_asm_local_alloc:
+ mach->sp -= a->param[0] / 4;
+ break;
+ case slang_asm_local_free:
+ mach->sp += a->param[0] / 4;
+ break;
+ case slang_asm_local_addr:
+ mach->sp--;
+ stack[mach->sp]._addr =
+ SLANG_MACHINE_GLOBAL_SIZE * 4 + mach->bp * 4 - (a->param[0] +
+ a->param[1]) + 4;
+ break;
+ case slang_asm_call:
+ mach->sp--;
+ stack[mach->sp]._addr = mach->ip;
+ mach->ip = a->param[0];
+ break;
+ case slang_asm_return:
+ mach->ip = stack[mach->sp]._addr;
+ mach->sp++;
+ break;
+ case slang_asm_discard:
+ mach->kill = GL_TRUE;
+ break;
+ case slang_asm_exit:
+ mach->exit = GL_TRUE;
+ break;
+ /* GL_MESA_shader_debug */
+ case slang_asm_float_print:
+ _mesa_printf("slang print: %f\n", stack[mach->sp]._float);
+ ensure_infolog_created(&mach->infolog);
+ slang_info_log_print(mach->infolog, "%f", stack[mach->sp]._float);
+ break;
+ case slang_asm_int_print:
+ _mesa_printf("slang print: %d\n", (GLint) stack[mach->sp]._float);
+ ensure_infolog_created(&mach->infolog);
+ slang_info_log_print(mach->infolog, "%d",
+ (GLint) (stack[mach->sp]._float));
+ break;
+ case slang_asm_bool_print:
+ _mesa_printf("slang print: %s\n",
+ (GLint) stack[mach->sp]._float ? "true" : "false");
+ ensure_infolog_created(&mach->infolog);
+ slang_info_log_print(mach->infolog, "%s",
+ (GLint) (stack[mach->sp].
+ _float) ? "true" : "false");
+ break;
+ /* vec4 */
case slang_asm_float_to_vec4:
/* [vec4] | float > [vec4] */
{
@@ -660,7 +714,8 @@ _slang_execute2 (const slang_assembly_file *file, slang_machine *mach)
mach->mem[da / 4]._float = -mach->mem[da / 4]._float;
mach->mem[(da + 4) / 4]._float = -mach->mem[(da + 4) / 4]._float;
mach->mem[(da + 8) / 4]._float = -mach->mem[(da + 8) / 4]._float;
- mach->mem[(da + 12) / 4]._float = -mach->mem[(da + 12) / 4]._float;
+ mach->mem[(da + 12) / 4]._float =
+ -mach->mem[(da + 12) / 4]._float;
}
break;
case slang_asm_vec4_dot:
@@ -721,9 +776,8 @@ _slang_execute2 (const slang_assembly_file *file, slang_machine *mach)
#if DEBUG_SLANG
if (f != NULL)
- fclose (f);
+ fclose(f);
#endif
return GL_TRUE;
}
-
diff --git a/src/mesa/shader/slang/slang_execute.h b/src/mesa/shader/slang/slang_execute.h
index cb152c7142..138f139308 100644
--- a/src/mesa/shader/slang/slang_execute.h
+++ b/src/mesa/shader/slang/slang_execute.h
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.2
*
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
*
@@ -22,7 +22,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#if !defined SLANG_EXECUTE_H
+#ifndef SLANG_EXECUTE_H
#define SLANG_EXECUTE_H
#include "slang_assemble.h"
@@ -31,55 +31,75 @@
extern "C" {
#endif
+
+/**
+ * A memory location
+ */
typedef union slang_machine_slot_
{
- GLfloat _float;
- GLuint _addr;
+ GLfloat _float;
+ GLuint _addr;
} slang_machine_slot;
#define SLANG_MACHINE_GLOBAL_SIZE 3072
#define SLANG_MACHINE_STACK_SIZE 1024
#define SLANG_MACHINE_MEMORY_SIZE (SLANG_MACHINE_GLOBAL_SIZE + SLANG_MACHINE_STACK_SIZE)
+
#if defined(USE_X86_ASM) || defined(SLANG_X86)
+/**
+ * Extra machine state for x86 execution.
+ */
typedef struct
{
- GLvoid (* compiled_func) (struct slang_machine_ *);
- GLuint esp_restore;
- GLshort fpucntl_rnd_neg;
- GLshort fpucntl_restore;
+ GLvoid(*compiled_func) (struct slang_machine_ *);
+ GLuint esp_restore;
+ GLshort fpucntl_rnd_neg;
+ GLshort fpucntl_restore;
} slang_machine_x86;
#endif
+
+/**
+ * Runtime shader machine state.
+ */
typedef struct slang_machine_
{
- GLuint ip; /* instruction pointer, for flow control */
- GLuint sp; /* stack pointer, for stack access */
- GLuint bp; /* base pointer, for local variable access */
- GLuint kill; /* discard the fragment */
- GLuint exit; /* terminate the shader */
- slang_machine_slot mem[SLANG_MACHINE_MEMORY_SIZE];
- struct slang_info_log_ *infolog; /* printMESA() support */
+ GLuint ip; /**< instruction pointer, for flow control */
+ GLuint sp; /**< stack pointer, for stack access */
+ GLuint bp; /**< base pointer, for local variable access */
+ GLboolean kill; /**< discard the fragment? */
+ GLboolean exit; /**< terminate the shader */
+ /** Machine memory */
+ slang_machine_slot mem[SLANG_MACHINE_MEMORY_SIZE];
+ struct slang_info_log_ *infolog; /**< printMESA() support */
#if defined(USE_X86_ASM) || defined(SLANG_X86)
- slang_machine_x86 x86;
+ slang_machine_x86 x86;
#endif
} slang_machine;
-GLvoid slang_machine_ctr (slang_machine *);
-GLvoid slang_machine_dtr (slang_machine *);
-void slang_machine_init (slang_machine *);
+extern GLvoid
+slang_machine_ctr(slang_machine *);
+
+extern GLvoid
+slang_machine_dtr(slang_machine *);
+
+extern void
+slang_machine_init(slang_machine *);
+
+extern GLboolean
+_slang_execute2(const slang_assembly_file *, slang_machine *);
-GLboolean
-_slang_execute2 (const slang_assembly_file *, slang_machine *);
#if defined(USE_X86_ASM) || defined(SLANG_X86)
-GLboolean _slang_x86_codegen (slang_machine *, slang_assembly_file *, GLuint);
+extern GLboolean
+_slang_x86_codegen(slang_machine *, slang_assembly_file *, GLuint);
#endif
+
#ifdef __cplusplus
}
#endif
#endif
-
diff --git a/src/mesa/shader/slang/slang_execute_x86.c b/src/mesa/shader/slang/slang_execute_x86.c
index 3e21edff6a..958086ff07 100644
--- a/src/mesa/shader/slang/slang_execute_x86.c
+++ b/src/mesa/shader/slang/slang_execute_x86.c
@@ -40,40 +40,42 @@
typedef struct
{
- GLuint index;
- GLubyte *csr;
+ GLuint index;
+ GLubyte *csr;
} fixup;
typedef struct
{
- struct x86_function f;
- struct x86_reg r_eax;
- struct x86_reg r_ecx;
- struct x86_reg r_edx;
+ struct x86_function f;
+ struct x86_reg r_eax;
+ struct x86_reg r_ecx;
+ struct x86_reg r_edx;
struct x86_reg r_ebx;
- struct x86_reg r_esp;
- struct x86_reg r_ebp;
- struct x86_reg r_st0;
- struct x86_reg r_st1;
- struct x86_reg r_st2;
- struct x86_reg r_st3;
+ struct x86_reg r_esp;
+ struct x86_reg r_ebp;
+ struct x86_reg r_st0;
+ struct x86_reg r_st1;
+ struct x86_reg r_st2;
+ struct x86_reg r_st3;
struct x86_reg r_st4;
- fixup *fixups;
- GLuint fixup_count;
- GLubyte **labels;
- slang_machine *mach;
- GLubyte *l_discard;
- GLubyte *l_exit;
- GLshort fpucntl;
+ fixup *fixups;
+ GLuint fixup_count;
+ GLubyte **labels;
+ slang_machine *mach;
+ GLubyte *l_discard;
+ GLubyte *l_exit;
+ GLshort fpucntl;
} codegen_ctx;
-static GLvoid add_fixup (codegen_ctx *G, GLuint index, GLubyte *csr)
+static GLvoid
+add_fixup(codegen_ctx * G, GLuint index, GLubyte * csr)
{
- G->fixups = (fixup *) slang_alloc_realloc (G->fixups, G->fixup_count * sizeof (fixup),
- (G->fixup_count + 1) * sizeof (fixup));
- G->fixups[G->fixup_count].index = index;
- G->fixups[G->fixup_count].csr = csr;
- G->fixup_count++;
+ G->fixups =
+ (fixup *) slang_alloc_realloc(G->fixups, G->fixup_count * sizeof(fixup),
+ (G->fixup_count + 1) * sizeof(fixup));
+ G->fixups[G->fixup_count].index = index;
+ G->fixups[G->fixup_count].csr = csr;
+ G->fixup_count++;
}
#ifdef NO_FAST_MATH
@@ -88,661 +90,665 @@ static GLvoid add_fixup (codegen_ctx *G, GLuint index, GLubyte *csr)
/*
* XXX
- * These should produce a valid code that computes powers. Unfortunately, it does not.
+ * These should produce a valid code that computes powers.
+ * Unfortunately, it does not.
*/
-static void set_fpu_round_neg_inf (codegen_ctx *G)
+static void
+set_fpu_round_neg_inf(codegen_ctx * G)
{
- if (G->fpucntl != RND_NEG_FPU)
- {
- G->fpucntl = RND_NEG_FPU;
- x87_fnclex (&G->f);
- x86_mov_reg_imm (&G->f, G->r_eax, (GLint) &G->mach->x86.fpucntl_rnd_neg);
- x87_fldcw (&G->f, x86_deref (G->r_eax));
- }
+ if (G->fpucntl != RND_NEG_FPU) {
+ G->fpucntl = RND_NEG_FPU;
+ x87_fnclex(&G->f);
+ x86_mov_reg_imm(&G->f, G->r_eax,
+ (GLint) & G->mach->x86.fpucntl_rnd_neg);
+ x87_fldcw(&G->f, x86_deref(G->r_eax));
+ }
}
-static void emit_x87_ex2 (codegen_ctx *G)
+static void
+emit_x87_ex2(codegen_ctx * G)
{
- set_fpu_round_neg_inf (G);
-
- x87_fld (&G->f, G->r_st0); /* a a */
- x87_fprndint (&G->f); /* int(a) a */
- x87_fld (&G->f, G->r_st0); /* int(a) int(a) a */
- x87_fstp (&G->f, G->r_st3); /* int(a) a int(a)*/
- x87_fsubp (&G->f, G->r_st1);/* frac(a) int(a) */
- x87_f2xm1 (&G->f); /* (2^frac(a))-1 int(a)*/
- x87_fld1 (&G->f); /* 1 (2^frac(a))-1 int(a)*/
- x87_faddp (&G->f, G->r_st1);/* 2^frac(a) int(a) */
- x87_fscale (&G->f); /* 2^a */
+ set_fpu_round_neg_inf(G);
+
+ x87_fld(&G->f, G->r_st0); /* a a */
+ x87_fprndint(&G->f); /* int(a) a */
+ x87_fld(&G->f, G->r_st0); /* int(a) int(a) a */
+ x87_fstp(&G->f, G->r_st3); /* int(a) a int(a) */
+ x87_fsubp(&G->f, G->r_st1); /* frac(a) int(a) */
+ x87_f2xm1(&G->f); /* (2^frac(a))-1 int(a) */
+ x87_fld1(&G->f); /* 1 (2^frac(a))-1 int(a) */
+ x87_faddp(&G->f, G->r_st1); /* 2^frac(a) int(a) */
+ x87_fscale(&G->f); /* 2^a */
}
-static void emit_pow (codegen_ctx *G)
+static void
+emit_pow(codegen_ctx * G)
{
- x87_fld (&G->f, x86_deref (G->r_esp));
- x87_fld (&G->f, x86_make_disp (G->r_esp, 4));
- x87_fyl2x (&G->f);
- emit_x87_ex2 (G);
+ x87_fld(&G->f, x86_deref(G->r_esp));
+ x87_fld(&G->f, x86_make_disp(G->r_esp, 4));
+ x87_fyl2x(&G->f);
+ emit_x87_ex2(G);
}
#endif
-static GLfloat do_ceilf (GLfloat x)
+static GLfloat
+do_ceilf(GLfloat x)
{
- return CEILF (x);
+ return CEILF(x);
}
-static GLfloat do_floorf (GLfloat x)
+static GLfloat
+do_floorf(GLfloat x)
{
- return FLOORF (x);
+ return FLOORF(x);
}
static GLfloat
-do_ftoi (GLfloat x)
+do_ftoi(GLfloat x)
{
return (GLfloat) ((GLint) (x));
}
-static GLfloat do_powf (GLfloat y, GLfloat x)
+static GLfloat
+do_powf(GLfloat y, GLfloat x)
{
- return (GLfloat) _mesa_pow ((GLdouble) x, (GLdouble) y);
+ return (GLfloat) _mesa_pow((GLdouble) x, (GLdouble) y);
}
static GLvoid
-ensure_infolog_created (slang_info_log **infolog)
+ensure_infolog_created(slang_info_log ** infolog)
{
if (*infolog == NULL) {
- *infolog = slang_alloc_malloc (sizeof (slang_info_log));
+ *infolog = slang_alloc_malloc(sizeof(slang_info_log));
if (*infolog == NULL)
return;
- slang_info_log_construct (*infolog);
+ slang_info_log_construct(*infolog);
}
}
-static GLvoid do_print_float (slang_info_log **infolog, GLfloat x)
+static GLvoid
+do_print_float(slang_info_log ** infolog, GLfloat x)
{
- _mesa_printf ("slang print: %f\n", x);
- ensure_infolog_created (infolog);
- slang_info_log_print (*infolog, "%f", x);
+ _mesa_printf("slang print: %f\n", x);
+ ensure_infolog_created(infolog);
+ slang_info_log_print(*infolog, "%f", x);
}
-static GLvoid do_print_int (slang_info_log **infolog, GLfloat x)
+static GLvoid
+do_print_int(slang_info_log ** infolog, GLfloat x)
{
- _mesa_printf ("slang print: %d\n", (GLint) (x));
- ensure_infolog_created (infolog);
- slang_info_log_print (*infolog, "%d", (GLint) (x));
+ _mesa_printf("slang print: %d\n", (GLint) (x));
+ ensure_infolog_created(infolog);
+ slang_info_log_print(*infolog, "%d", (GLint) (x));
}
-static GLvoid do_print_bool (slang_info_log **infolog, GLfloat x)
+static GLvoid
+do_print_bool(slang_info_log ** infolog, GLfloat x)
{
- _mesa_printf ("slang print: %s\n", (GLint) (x) ? "true" : "false");
- ensure_infolog_created (infolog);
- slang_info_log_print (*infolog, "%s", (GLint) (x) ? "true" : "false");
+ _mesa_printf("slang print: %s\n", (GLint) (x) ? "true" : "false");
+ ensure_infolog_created(infolog);
+ slang_info_log_print(*infolog, "%s", (GLint) (x) ? "true" : "false");
}
#define FLOAT_ONE 0x3f800000
#define FLOAT_ZERO 0
-static GLvoid codegen_assem (codegen_ctx *G, slang_assembly *a, slang_info_log **infolog)
+static GLvoid
+codegen_assem(codegen_ctx * G, slang_assembly * a, slang_info_log ** infolog)
{
- GLint disp, i;
-
- switch (a->type)
- {
- case slang_asm_none:
- break;
- case slang_asm_float_copy:
- case slang_asm_int_copy:
- case slang_asm_bool_copy:
- x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, a->param[0]));
- x86_pop (&G->f, G->r_ecx);
- x86_mov (&G->f, x86_make_disp (G->r_eax, a->param[1]), G->r_ecx);
- break;
- case slang_asm_float_move:
- case slang_asm_int_move:
- case slang_asm_bool_move:
- x86_lea (&G->f, G->r_eax, x86_make_disp (G->r_esp, a->param[1]));
- x86_add (&G->f, G->r_eax, x86_deref (G->r_esp));
- x86_mov (&G->f, G->r_eax, x86_deref (G->r_eax));
- x86_mov (&G->f, x86_make_disp (G->r_esp, a->param[0]), G->r_eax);
- break;
- case slang_asm_float_push:
- case slang_asm_int_push:
- case slang_asm_bool_push:
- /* TODO: use push imm32 */
- x86_mov_reg_imm (&G->f, G->r_eax, *((GLint *) &a->literal));
- x86_push (&G->f, G->r_eax);
- break;
- case slang_asm_float_deref:
- case slang_asm_int_deref:
- case slang_asm_bool_deref:
- case slang_asm_addr_deref:
- x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp));
- x86_mov (&G->f, G->r_eax, x86_deref (G->r_eax));
- x86_mov (&G->f, x86_deref (G->r_esp), G->r_eax);
- break;
- case slang_asm_float_add:
- x87_fld (&G->f, x86_make_disp (G->r_esp, 4));
- x87_fld (&G->f, x86_deref (G->r_esp));
- x87_faddp (&G->f, G->r_st1);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_multiply:
- x87_fld (&G->f, x86_make_disp (G->r_esp, 4));
- x87_fld (&G->f, x86_deref (G->r_esp));
- x87_fmulp (&G->f, G->r_st1);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_divide:
- x87_fld (&G->f, x86_make_disp (G->r_esp, 4));
- x87_fld (&G->f, x86_deref (G->r_esp));
- x87_fdivp (&G->f, G->r_st1);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_negate:
- x87_fld (&G->f, x86_deref (G->r_esp));
- x87_fchs (&G->f);
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_less:
- x87_fld (&G->f, x86_make_disp (G->r_esp, 4));
- x87_fcomp (&G->f, x86_deref (G->r_esp));
- x87_fnstsw (&G->f, G->r_eax);
- /* TODO: use test r8,imm8 */
- x86_mov_reg_imm (&G->f, G->r_ecx, 0x100);
- x86_test (&G->f, G->r_eax, G->r_ecx);
- {
- GLubyte *lab0, *lab1;
-
- /* TODO: use jcc rel8 */
- lab0 = x86_jcc_forward (&G->f, cc_E);
- x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ONE);
- /* TODO: use jmp rel8 */
- lab1 = x86_jmp_forward (&G->f);
- x86_fixup_fwd_jump (&G->f, lab0);
- x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ZERO);
- x86_fixup_fwd_jump (&G->f, lab1);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
- x86_mov (&G->f, x86_deref (G->r_esp), G->r_ecx);
- }
- break;
- case slang_asm_float_equal_exp:
- x87_fld (&G->f, x86_make_disp (G->r_esp, 4));
- x87_fcomp (&G->f, x86_deref (G->r_esp));
- x87_fnstsw (&G->f, G->r_eax);
- /* TODO: use test r8,imm8 */
- x86_mov_reg_imm (&G->f, G->r_ecx, 0x4000);
- x86_test (&G->f, G->r_eax, G->r_ecx);
- {
- GLubyte *lab0, *lab1;
-
- /* TODO: use jcc rel8 */
- lab0 = x86_jcc_forward (&G->f, cc_E);
- x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ONE);
- /* TODO: use jmp rel8 */
- lab1 = x86_jmp_forward (&G->f);
- x86_fixup_fwd_jump (&G->f, lab0);
- x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ZERO);
- x86_fixup_fwd_jump (&G->f, lab1);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
- x86_mov (&G->f, x86_deref (G->r_esp), G->r_ecx);
- }
- break;
- case slang_asm_float_equal_int:
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, -4));
- x87_fld (&G->f, x86_make_disp (G->r_esp, a->param[0] + 4));
- x87_fcomp (&G->f, x86_make_disp (G->r_esp, a->param[1] + 4));
- x87_fnstsw (&G->f, G->r_eax);
- /* TODO: use test r8,imm8 */
- x86_mov_reg_imm (&G->f, G->r_ecx, 0x4000);
- x86_test (&G->f, G->r_eax, G->r_ecx);
- {
- GLubyte *lab0, *lab1;
-
- /* TODO: use jcc rel8 */
- lab0 = x86_jcc_forward (&G->f, cc_E);
- x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ONE);
- /* TODO: use jmp rel8 */
- lab1 = x86_jmp_forward (&G->f);
- x86_fixup_fwd_jump (&G->f, lab0);
- x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ZERO);
- x86_fixup_fwd_jump (&G->f, lab1);
- x86_mov (&G->f, x86_deref (G->r_esp), G->r_ecx);
- }
- break;
- case slang_asm_float_to_int:
+ GLint disp, i;
+
+ switch (a->type) {
+ case slang_asm_none:
+ break;
+ case slang_asm_float_copy:
+ case slang_asm_int_copy:
+ case slang_asm_bool_copy:
+ x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, a->param[0]));
+ x86_pop(&G->f, G->r_ecx);
+ x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1]), G->r_ecx);
+ break;
+ case slang_asm_float_move:
+ case slang_asm_int_move:
+ case slang_asm_bool_move:
+ x86_lea(&G->f, G->r_eax, x86_make_disp(G->r_esp, a->param[1]));
+ x86_add(&G->f, G->r_eax, x86_deref(G->r_esp));
+ x86_mov(&G->f, G->r_eax, x86_deref(G->r_eax));
+ x86_mov(&G->f, x86_make_disp(G->r_esp, a->param[0]), G->r_eax);
+ break;
+ case slang_asm_float_push:
+ case slang_asm_int_push:
+ case slang_asm_bool_push:
+ /* TODO: use push imm32 */
+ x86_mov_reg_imm(&G->f, G->r_eax, *((GLint *) & a->literal));
+ x86_push(&G->f, G->r_eax);
+ break;
+ case slang_asm_float_deref:
+ case slang_asm_int_deref:
+ case slang_asm_bool_deref:
+ case slang_asm_addr_deref:
+ x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp));
+ x86_mov(&G->f, G->r_eax, x86_deref(G->r_eax));
+ x86_mov(&G->f, x86_deref(G->r_esp), G->r_eax);
+ break;
+ case slang_asm_float_add:
+ x87_fld(&G->f, x86_make_disp(G->r_esp, 4));
+ x87_fld(&G->f, x86_deref(G->r_esp));
+ x87_faddp(&G->f, G->r_st1);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4));
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_multiply:
+ x87_fld(&G->f, x86_make_disp(G->r_esp, 4));
+ x87_fld(&G->f, x86_deref(G->r_esp));
+ x87_fmulp(&G->f, G->r_st1);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4));
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_divide:
+ x87_fld(&G->f, x86_make_disp(G->r_esp, 4));
+ x87_fld(&G->f, x86_deref(G->r_esp));
+ x87_fdivp(&G->f, G->r_st1);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4));
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_negate:
+ x87_fld(&G->f, x86_deref(G->r_esp));
+ x87_fchs(&G->f);
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_less:
+ x87_fld(&G->f, x86_make_disp(G->r_esp, 4));
+ x87_fcomp(&G->f, x86_deref(G->r_esp));
+ x87_fnstsw(&G->f, G->r_eax);
+ /* TODO: use test r8,imm8 */
+ x86_mov_reg_imm(&G->f, G->r_ecx, 0x100);
+ x86_test(&G->f, G->r_eax, G->r_ecx);
+ {
+ GLubyte *lab0, *lab1;
+ /* TODO: use jcc rel8 */
+ lab0 = x86_jcc_forward(&G->f, cc_E);
+ x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE);
+ /* TODO: use jmp rel8 */
+ lab1 = x86_jmp_forward(&G->f);
+ x86_fixup_fwd_jump(&G->f, lab0);
+ x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO);
+ x86_fixup_fwd_jump(&G->f, lab1);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4));
+ x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx);
+ }
+ break;
+ case slang_asm_float_equal_exp:
+ x87_fld(&G->f, x86_make_disp(G->r_esp, 4));
+ x87_fcomp(&G->f, x86_deref(G->r_esp));
+ x87_fnstsw(&G->f, G->r_eax);
+ /* TODO: use test r8,imm8 */
+ x86_mov_reg_imm(&G->f, G->r_ecx, 0x4000);
+ x86_test(&G->f, G->r_eax, G->r_ecx);
+ {
+ GLubyte *lab0, *lab1;
+ /* TODO: use jcc rel8 */
+ lab0 = x86_jcc_forward(&G->f, cc_E);
+ x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE);
+ /* TODO: use jmp rel8 */
+ lab1 = x86_jmp_forward(&G->f);
+ x86_fixup_fwd_jump(&G->f, lab0);
+ x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO);
+ x86_fixup_fwd_jump(&G->f, lab1);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4));
+ x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx);
+ }
+ break;
+ case slang_asm_float_equal_int:
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, -4));
+ x87_fld(&G->f, x86_make_disp(G->r_esp, a->param[0] + 4));
+ x87_fcomp(&G->f, x86_make_disp(G->r_esp, a->param[1] + 4));
+ x87_fnstsw(&G->f, G->r_eax);
+ /* TODO: use test r8,imm8 */
+ x86_mov_reg_imm(&G->f, G->r_ecx, 0x4000);
+ x86_test(&G->f, G->r_eax, G->r_ecx);
+ {
+ GLubyte *lab0, *lab1;
+ /* TODO: use jcc rel8 */
+ lab0 = x86_jcc_forward(&G->f, cc_E);
+ x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE);
+ /* TODO: use jmp rel8 */
+ lab1 = x86_jmp_forward(&G->f);
+ x86_fixup_fwd_jump(&G->f, lab0);
+ x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO);
+ x86_fixup_fwd_jump(&G->f, lab1);
+ x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx);
+ }
+ break;
+ case slang_asm_float_to_int:
/* TODO: use fistp without rounding */
- x86_call (&G->f, (GLubyte *) (do_ftoi));
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_sine:
- /* TODO: use fsin */
- x86_call (&G->f, (GLubyte *) _mesa_sinf);
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_arcsine:
- /* TODO: use fpatan (?) */
- x86_call (&G->f, (GLubyte *) _mesa_asinf);
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_arctan:
- /* TODO: use fpatan */
- x86_call (&G->f, (GLubyte *) _mesa_atanf);
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_power:
- /* TODO: use emit_pow() */
- x86_call (&G->f, (GLubyte *) do_powf);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_log2:
- x87_fld1 (&G->f);
- x87_fld (&G->f, x86_deref (G->r_esp));
- x87_fyl2x (&G->f);
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_floor:
- x86_call (&G->f, (GLubyte *) do_floorf);
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_ceil:
- x86_call (&G->f, (GLubyte *) do_ceilf);
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_noise1:
- x86_call (&G->f, (GLubyte *) _slang_library_noise1);
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_noise2:
- x86_call (&G->f, (GLubyte *) _slang_library_noise2);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_noise3:
- x86_call (&G->f, (GLubyte *) _slang_library_noise4);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 8));
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_float_noise4:
- x86_call (&G->f, (GLubyte *) _slang_library_noise4);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 12));
- x87_fstp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_int_to_float:
- break;
- case slang_asm_int_to_addr:
- x87_fld (&G->f, x86_deref (G->r_esp));
- x87_fistp (&G->f, x86_deref (G->r_esp));
- break;
- case slang_asm_addr_copy:
- x86_pop (&G->f, G->r_eax);
- x86_mov (&G->f, G->r_ecx, x86_deref (G->r_esp));
- x86_mov (&G->f, x86_deref (G->r_ecx), G->r_eax);
- break;
- case slang_asm_addr_push:
- /* TODO: use push imm32 */
- x86_mov_reg_imm (&G->f, G->r_eax, (GLint) a->param[0]);
- x86_push (&G->f, G->r_eax);
- break;
- case slang_asm_addr_add:
- x86_pop (&G->f, G->r_eax);
- x86_add (&G->f, x86_deref (G->r_esp), G->r_eax);
- break;
- case slang_asm_addr_multiply:
- x86_pop (&G->f, G->r_ecx);
- x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp));
- x86_mul (&G->f, G->r_ecx);
- x86_mov (&G->f, x86_deref (G->r_esp), G->r_eax);
- break;
- case slang_asm_vec4_tex1d:
- x86_call (&G->f, (GLubyte *) _slang_library_tex1d);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 12));
- break;
- case slang_asm_vec4_tex2d:
- x86_call (&G->f, (GLubyte *) _slang_library_tex2d);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16));
- break;
- case slang_asm_vec4_tex3d:
- x86_call (&G->f, (GLubyte *) _slang_library_tex3d);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 20));
- break;
- case slang_asm_vec4_texcube:
- x86_call (&G->f, (GLubyte *) _slang_library_texcube);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 20));
- break;
- case slang_asm_vec4_shad1d:
- x86_call (&G->f, (GLubyte *) _slang_library_shad1d);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 20));
- break;
- case slang_asm_vec4_shad2d:
- x86_call (&G->f, (GLubyte *) _slang_library_shad2d);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 20));
- break;
- case slang_asm_jump:
- add_fixup (G, a->param[0], x86_jmp_forward (&G->f));
- break;
- case slang_asm_jump_if_zero:
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
- x86_xor (&G->f, G->r_eax, G->r_eax);
- x86_cmp (&G->f, G->r_eax, x86_make_disp (G->r_esp, -4));
- {
- GLubyte *lab0;
-
- /* TODO: use jcc rel8 */
- lab0 = x86_jcc_forward (&G->f, cc_NE);
- add_fixup (G, a->param[0], x86_jmp_forward (&G->f));
- x86_fixup_fwd_jump (&G->f, lab0);
- }
- break;
- case slang_asm_enter:
- /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */
- assert (a->param[0] != 0);
- x86_push (&G->f, G->r_ebp);
- x86_lea (&G->f, G->r_ebp, x86_make_disp (G->r_esp, (GLint) a->param[0]));
- break;
- case slang_asm_leave:
- x86_pop (&G->f, G->r_ebp);
- break;
- case slang_asm_local_alloc:
- /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */
- assert (a->param[0] != 0);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, -(GLint) a->param[0]));
- break;
- case slang_asm_local_free:
- /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */
- assert (a->param[0] != 0);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, (GLint) a->param[0]));
- break;
- case slang_asm_local_addr:
- disp = -(GLint) (a->param[0] + a->param[1]) + 4;
- if (disp != 0)
- {
- x86_lea (&G->f, G->r_eax, x86_make_disp (G->r_ebp, disp));
- x86_push (&G->f, G->r_eax);
- }
- else
- x86_push (&G->f, G->r_ebp);
- break;
- case slang_asm_global_addr:
- /* TODO: use push imm32 */
- x86_mov_reg_imm (&G->f, G->r_eax, (GLint) &G->mach->mem + a->param[0]);
- x86_push (&G->f, G->r_eax);
- break;
- case slang_asm_call:
- add_fixup (G, a->param[0], x86_call_forward (&G->f));
- break;
- case slang_asm_return:
- x86_ret (&G->f);
- break;
- case slang_asm_discard:
- x86_jmp (&G->f, G->l_discard);
- break;
- case slang_asm_exit:
- x86_jmp (&G->f, G->l_exit);
- break;
- /* GL_MESA_shader_debug */
+ x86_call(&G->f, (GLubyte *) (do_ftoi));
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_sine:
+ /* TODO: use fsin */
+ x86_call(&G->f, (GLubyte *) _mesa_sinf);
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_arcsine:
+ /* TODO: use fpatan (?) */
+ x86_call(&G->f, (GLubyte *) _mesa_asinf);
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_arctan:
+ /* TODO: use fpatan */
+ x86_call(&G->f, (GLubyte *) _mesa_atanf);
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_power:
+ /* TODO: use emit_pow() */
+ x86_call(&G->f, (GLubyte *) do_powf);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4));
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_log2:
+ x87_fld1(&G->f);
+ x87_fld(&G->f, x86_deref(G->r_esp));
+ x87_fyl2x(&G->f);
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_floor:
+ x86_call(&G->f, (GLubyte *) do_floorf);
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_ceil:
+ x86_call(&G->f, (GLubyte *) do_ceilf);
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_noise1:
+ x86_call(&G->f, (GLubyte *) _slang_library_noise1);
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_noise2:
+ x86_call(&G->f, (GLubyte *) _slang_library_noise2);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4));
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_noise3:
+ x86_call(&G->f, (GLubyte *) _slang_library_noise4);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 8));
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_float_noise4:
+ x86_call(&G->f, (GLubyte *) _slang_library_noise4);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 12));
+ x87_fstp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_int_to_float:
+ break;
+ case slang_asm_int_to_addr:
+ x87_fld(&G->f, x86_deref(G->r_esp));
+ x87_fistp(&G->f, x86_deref(G->r_esp));
+ break;
+ case slang_asm_addr_copy:
+ x86_pop(&G->f, G->r_eax);
+ x86_mov(&G->f, G->r_ecx, x86_deref(G->r_esp));
+ x86_mov(&G->f, x86_deref(G->r_ecx), G->r_eax);
+ break;
+ case slang_asm_addr_push:
+ /* TODO: use push imm32 */
+ x86_mov_reg_imm(&G->f, G->r_eax, (GLint) a->param[0]);
+ x86_push(&G->f, G->r_eax);
+ break;
+ case slang_asm_addr_add:
+ x86_pop(&G->f, G->r_eax);
+ x86_add(&G->f, x86_deref(G->r_esp), G->r_eax);
+ break;
+ case slang_asm_addr_multiply:
+ x86_pop(&G->f, G->r_ecx);
+ x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp));
+ x86_mul(&G->f, G->r_ecx);
+ x86_mov(&G->f, x86_deref(G->r_esp), G->r_eax);
+ break;
+ case slang_asm_vec4_tex1d:
+ x86_call(&G->f, (GLubyte *) _slang_library_tex1d);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 12));
+ break;
+ case slang_asm_vec4_tex2d:
+ x86_call(&G->f, (GLubyte *) _slang_library_tex2d);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16));
+ break;
+ case slang_asm_vec4_tex3d:
+ x86_call(&G->f, (GLubyte *) _slang_library_tex3d);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20));
+ break;
+ case slang_asm_vec4_texcube:
+ x86_call(&G->f, (GLubyte *) _slang_library_texcube);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20));
+ break;
+ case slang_asm_vec4_shad1d:
+ x86_call(&G->f, (GLubyte *) _slang_library_shad1d);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20));
+ break;
+ case slang_asm_vec4_shad2d:
+ x86_call(&G->f, (GLubyte *) _slang_library_shad2d);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20));
+ break;
+ case slang_asm_jump:
+ add_fixup(G, a->param[0], x86_jmp_forward(&G->f));
+ break;
+ case slang_asm_jump_if_zero:
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4));
+ x86_xor(&G->f, G->r_eax, G->r_eax);
+ x86_cmp(&G->f, G->r_eax, x86_make_disp(G->r_esp, -4));
+ {
+ GLubyte *lab0;
+ /* TODO: use jcc rel8 */
+ lab0 = x86_jcc_forward(&G->f, cc_NE);
+ add_fixup(G, a->param[0], x86_jmp_forward(&G->f));
+ x86_fixup_fwd_jump(&G->f, lab0);
+ }
+ break;
+ case slang_asm_enter:
+ /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */
+ assert(a->param[0] != 0);
+ x86_push(&G->f, G->r_ebp);
+ x86_lea(&G->f, G->r_ebp, x86_make_disp(G->r_esp, (GLint) a->param[0]));
+ break;
+ case slang_asm_leave:
+ x86_pop(&G->f, G->r_ebp);
+ break;
+ case slang_asm_local_alloc:
+ /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */
+ assert(a->param[0] != 0);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, -(GLint) a->param[0]));
+ break;
+ case slang_asm_local_free:
+ /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */
+ assert(a->param[0] != 0);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, (GLint) a->param[0]));
+ break;
+ case slang_asm_local_addr:
+ disp = -(GLint) (a->param[0] + a->param[1]) + 4;
+ if (disp != 0) {
+ x86_lea(&G->f, G->r_eax, x86_make_disp(G->r_ebp, disp));
+ x86_push(&G->f, G->r_eax);
+ }
+ else
+ x86_push(&G->f, G->r_ebp);
+ break;
+ case slang_asm_global_addr:
+ /* TODO: use push imm32 */
+ x86_mov_reg_imm(&G->f, G->r_eax, (GLint) & G->mach->mem + a->param[0]);
+ x86_push(&G->f, G->r_eax);
+ break;
+ case slang_asm_call:
+ add_fixup(G, a->param[0], x86_call_forward(&G->f));
+ break;
+ case slang_asm_return:
+ x86_ret(&G->f);
+ break;
+ case slang_asm_discard:
+ x86_jmp(&G->f, G->l_discard);
+ break;
+ case slang_asm_exit:
+ x86_jmp(&G->f, G->l_exit);
+ break;
+ /* GL_MESA_shader_debug */
case slang_asm_float_print:
/* TODO: use push imm32 */
- x86_mov_reg_imm (&G->f, G->r_eax, (GLint) (infolog));
- x86_push (&G->f, G->r_eax);
- x86_call (&G->f, (GLubyte *) (do_print_float));
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
+ x86_mov_reg_imm(&G->f, G->r_eax, (GLint) (infolog));
+ x86_push(&G->f, G->r_eax);
+ x86_call(&G->f, (GLubyte *) (do_print_float));
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4));
break;
- case slang_asm_int_print:
+ case slang_asm_int_print:
/* TODO: use push imm32 */
- x86_mov_reg_imm (&G->f, G->r_eax, (GLint) (infolog));
- x86_push (&G->f, G->r_eax);
- x86_call (&G->f, (GLubyte *) do_print_int);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
- break;
- case slang_asm_bool_print:
+ x86_mov_reg_imm(&G->f, G->r_eax, (GLint) (infolog));
+ x86_push(&G->f, G->r_eax);
+ x86_call(&G->f, (GLubyte *) do_print_int);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4));
+ break;
+ case slang_asm_bool_print:
/* TODO: use push imm32 */
- x86_mov_reg_imm (&G->f, G->r_eax, (GLint) (infolog));
- x86_push (&G->f, G->r_eax);
- x86_call (&G->f, (GLubyte *) do_print_bool);
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
- break;
- /* vec4 */
+ x86_mov_reg_imm(&G->f, G->r_eax, (GLint) (infolog));
+ x86_push(&G->f, G->r_eax);
+ x86_call(&G->f, (GLubyte *) do_print_bool);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4));
+ break;
+ /* vec4 */
case slang_asm_float_to_vec4:
/* [vec4] | float > [vec4] */
- x87_fld (&G->f, x86_deref (G->r_esp));
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
- x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp));
- x87_fst (&G->f, x86_make_disp (G->r_eax, 12));
- x87_fst (&G->f, x86_make_disp (G->r_eax, 8));
- x87_fst (&G->f, x86_make_disp (G->r_eax, 4));
- x87_fstp (&G->f, x86_deref (G->r_eax));
+ x87_fld(&G->f, x86_deref(G->r_esp));
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4));
+ x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp));
+ x87_fst(&G->f, x86_make_disp(G->r_eax, 12));
+ x87_fst(&G->f, x86_make_disp(G->r_eax, 8));
+ x87_fst(&G->f, x86_make_disp(G->r_eax, 4));
+ x87_fstp(&G->f, x86_deref(G->r_eax));
break;
case slang_asm_vec4_add:
/* [vec4] | vec4 > [vec4] */
- x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, 16));
+ x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16));
for (i = 0; i < 4; i++)
- x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4));
+ x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4));
for (i = 0; i < 4; i++)
- x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4));
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16));
+ x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4));
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16));
for (i = 0; i < 4; i++)
- x87_faddp (&G->f, G->r_st4);
+ x87_faddp(&G->f, G->r_st4);
for (i = 0; i < 4; i++)
- x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4));
+ x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4));
break;
case slang_asm_vec4_subtract:
/* [vec4] | vec4 > [vec4] */
- x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, 16));
+ x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16));
for (i = 0; i < 4; i++)
- x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4));
+ x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4));
for (i = 0; i < 4; i++)
- x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4));
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16));
+ x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4));
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16));
for (i = 0; i < 4; i++)
- x87_fsubp (&G->f, G->r_st4);
+ x87_fsubp(&G->f, G->r_st4);
for (i = 0; i < 4; i++)
- x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4));
+ x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4));
break;
case slang_asm_vec4_multiply:
/* [vec4] | vec4 > [vec4] */
- x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, 16));
+ x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16));
for (i = 0; i < 4; i++)
- x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4));
+ x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4));
for (i = 0; i < 4; i++)
- x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4));
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16));
+ x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4));
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16));
for (i = 0; i < 4; i++)
- x87_fmulp (&G->f, G->r_st4);
+ x87_fmulp(&G->f, G->r_st4);
for (i = 0; i < 4; i++)
- x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4));
+ x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4));
break;
case slang_asm_vec4_divide:
/* [vec4] | vec4 > [vec4] */
- x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, 16));
+ x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16));
for (i = 0; i < 4; i++)
- x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4));
+ x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4));
for (i = 0; i < 4; i++)
- x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4));
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16));
+ x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4));
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16));
for (i = 0; i < 4; i++)
- x87_fdivp (&G->f, G->r_st4);
+ x87_fdivp(&G->f, G->r_st4);
for (i = 0; i < 4; i++)
- x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4));
+ x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4));
break;
case slang_asm_vec4_negate:
/* [vec4] > [vec4] */
- x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp));
+ x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp));
for (i = 0; i < 4; i++)
- x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4));
+ x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4));
for (i = 0; i < 4; i++) {
- x87_fchs (&G->f);
- x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4));
+ x87_fchs(&G->f);
+ x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4));
}
break;
case slang_asm_vec4_dot:
/* [vec4] | vec4 > [float] */
for (i = 0; i < 4; i++)
- x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4));
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16));
- x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp));
+ x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4));
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16));
+ x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp));
for (i = 0; i < 4; i++)
- x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4));
+ x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4));
for (i = 0; i < 4; i++)
- x87_fmulp (&G->f, G->r_st4);
+ x87_fmulp(&G->f, G->r_st4);
for (i = 0; i < 3; i++)
- x87_faddp (&G->f, G->r_st1);
- x87_fstp (&G->f, x86_deref (G->r_eax));
+ x87_faddp(&G->f, G->r_st1);
+ x87_fstp(&G->f, x86_deref(G->r_eax));
break;
case slang_asm_vec4_copy:
/* [vec4] | vec4 > [vec4] */
- x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, a->param[0]));
- x86_pop (&G->f, G->r_ecx);
- x86_pop (&G->f, G->r_edx);
- x86_mov (&G->f, x86_make_disp (G->r_eax, a->param[1]), G->r_ecx);
- x86_pop (&G->f, G->r_ebx);
- x86_mov (&G->f, x86_make_disp (G->r_eax, a->param[1] + 4), G->r_edx);
- x86_pop (&G->f, G->r_ecx);
- x86_mov (&G->f, x86_make_disp (G->r_eax, a->param[1] + 8), G->r_ebx);
- x86_mov (&G->f, x86_make_disp (G->r_eax, a->param[1] + 12), G->r_ecx);
+ x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, a->param[0]));
+ x86_pop(&G->f, G->r_ecx);
+ x86_pop(&G->f, G->r_edx);
+ x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1]), G->r_ecx);
+ x86_pop(&G->f, G->r_ebx);
+ x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1] + 4), G->r_edx);
+ x86_pop(&G->f, G->r_ecx);
+ x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1] + 8), G->r_ebx);
+ x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1] + 12), G->r_ecx);
break;
case slang_asm_vec4_deref:
/* [vec4] > vec4 */
- x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp));
- x86_mov (&G->f, G->r_ecx, x86_make_disp (G->r_eax, 12));
- x86_mov (&G->f, G->r_edx, x86_make_disp (G->r_eax, 8));
- x86_mov (&G->f, x86_deref (G->r_esp), G->r_ecx);
- x86_mov (&G->f, G->r_ebx, x86_make_disp (G->r_eax, 4));
- x86_push (&G->f, G->r_edx);
- x86_mov (&G->f, G->r_ecx, x86_deref (G->r_eax));
- x86_push (&G->f, G->r_ebx);
- x86_push (&G->f, G->r_ecx);
+ x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp));
+ x86_mov(&G->f, G->r_ecx, x86_make_disp(G->r_eax, 12));
+ x86_mov(&G->f, G->r_edx, x86_make_disp(G->r_eax, 8));
+ x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx);
+ x86_mov(&G->f, G->r_ebx, x86_make_disp(G->r_eax, 4));
+ x86_push(&G->f, G->r_edx);
+ x86_mov(&G->f, G->r_ecx, x86_deref(G->r_eax));
+ x86_push(&G->f, G->r_ebx);
+ x86_push(&G->f, G->r_ecx);
break;
case slang_asm_vec4_equal_int:
- x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, -4));
- x86_mov_reg_imm (&G->f, G->r_edx, 0x4000);
+ x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, -4));
+ x86_mov_reg_imm(&G->f, G->r_edx, 0x4000);
for (i = 0; i < 4; i++) {
- x87_fld (&G->f, x86_make_disp (G->r_esp, a->param[0] + 4 + i * 4));
- x87_fcomp (&G->f, x86_make_disp (G->r_esp, a->param[1] + 4 + i * 4));
- x87_fnstsw (&G->f, G->r_eax);
- x86_and (&G->f, G->r_edx, G->r_eax);
+ x87_fld(&G->f, x86_make_disp(G->r_esp, a->param[0] + 4 + i * 4));
+ x87_fcomp(&G->f, x86_make_disp(G->r_esp, a->param[1] + 4 + i * 4));
+ x87_fnstsw(&G->f, G->r_eax);
+ x86_and(&G->f, G->r_edx, G->r_eax);
}
/* TODO: use test r8,imm8 */
- x86_mov_reg_imm (&G->f, G->r_ecx, 0x4000);
- x86_test (&G->f, G->r_edx, G->r_ecx);
+ x86_mov_reg_imm(&G->f, G->r_ecx, 0x4000);
+ x86_test(&G->f, G->r_edx, G->r_ecx);
{
GLubyte *lab0, *lab1;
/* TODO: use jcc rel8 */
- lab0 = x86_jcc_forward (&G->f, cc_E);
- x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ONE);
+ lab0 = x86_jcc_forward(&G->f, cc_E);
+ x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE);
/* TODO: use jmp rel8 */
- lab1 = x86_jmp_forward (&G->f);
- x86_fixup_fwd_jump (&G->f, lab0);
- x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ZERO);
- x86_fixup_fwd_jump (&G->f, lab1);
- x86_mov (&G->f, x86_deref (G->r_esp), G->r_ecx);
+ lab1 = x86_jmp_forward(&G->f);
+ x86_fixup_fwd_jump(&G->f, lab0);
+ x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO);
+ x86_fixup_fwd_jump(&G->f, lab1);
+ x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx);
}
break;
default:
- assert (0);
+ _mesa_problem(NULL, "Unexpected switch case in codegen_assem");
}
}
-GLboolean _slang_x86_codegen (slang_machine *mach, slang_assembly_file *file, GLuint start)
+GLboolean
+_slang_x86_codegen(slang_machine * mach, slang_assembly_file * file,
+ GLuint start)
{
- codegen_ctx G;
- GLubyte *j_body, *j_exit;
- GLuint i;
+ codegen_ctx G;
+ GLubyte *j_body, *j_exit;
+ GLuint i;
/* Free the old code - if any.
*/
if (mach->x86.compiled_func != NULL) {
- _mesa_exec_free (mach->x86.compiled_func);
+ _mesa_exec_free(mach->x86.compiled_func);
mach->x86.compiled_func = NULL;
}
- /*
- * We need as much as 1M because *all* assembly, including built-in library, is
- * being translated to x86.
- * The built-in library occupies 450K, so we can be safe for now.
- * It is going to change in the future, when we get assembly analysis running.
- */
- x86_init_func_size (&G.f, 1048576);
- G.r_eax = x86_make_reg (file_REG32, reg_AX);
- G.r_ecx = x86_make_reg (file_REG32, reg_CX);
- G.r_edx = x86_make_reg (file_REG32, reg_DX);
- G.r_ebx = x86_make_reg (file_REG32, reg_BX);
- G.r_esp = x86_make_reg (file_REG32, reg_SP);
- G.r_ebp = x86_make_reg (file_REG32, reg_BP);
- G.r_st0 = x86_make_reg (file_x87, 0);
- G.r_st1 = x86_make_reg (file_x87, 1);
- G.r_st2 = x86_make_reg (file_x87, 2);
- G.r_st3 = x86_make_reg (file_x87, 3);
- G.r_st4 = x86_make_reg (file_x87, 4);
- G.fixups = NULL;
- G.fixup_count = 0;
- G.labels = (GLubyte **) slang_alloc_malloc (file->count * sizeof (GLubyte *));
- G.mach = mach;
- G.fpucntl = RESTORE_FPU;
-
- mach->x86.fpucntl_rnd_neg = RND_NEG_FPU;
- mach->x86.fpucntl_restore = RESTORE_FPU;
-
- /* prepare stack and jump to start */
- x86_push (&G.f, G.r_ebp);
- x86_mov_reg_imm (&G.f, G.r_eax, (GLint) &mach->x86.esp_restore);
- x86_push (&G.f, G.r_esp);
- x86_pop (&G.f, G.r_ecx);
- x86_mov (&G.f, x86_deref (G.r_eax), G.r_ecx);
- j_body = x86_jmp_forward (&G.f);
-
- /* "discard" instructions jump to this label */
- G.l_discard = x86_get_label (&G.f);
- x86_mov_reg_imm (&G.f, G.r_eax, (GLint) &G.mach->kill);
- x86_mov_reg_imm (&G.f, G.r_ecx, 1);
- x86_mov (&G.f, x86_deref (G.r_eax), G.r_ecx);
- G.l_exit = x86_get_label (&G.f);
- j_exit = x86_jmp_forward (&G.f);
-
- for (i = 0; i < file->count; i++)
- {
- G.labels[i] = x86_get_label (&G.f);
- if (i == start)
- x86_fixup_fwd_jump (&G.f, j_body);
- codegen_assem (&G, &file->code[i], &mach->infolog);
- }
-
- /*
- * Restore stack and return.
- * This must be handled this way, because "discard" can be invoked from any
- * place in the code.
- */
- x86_fixup_fwd_jump (&G.f, j_exit);
- x86_mov_reg_imm (&G.f, G.r_eax, (GLint) &mach->x86.esp_restore);
- x86_mov (&G.f, G.r_esp, x86_deref (G.r_eax));
- x86_pop (&G.f, G.r_ebp);
- if (G.fpucntl != RESTORE_FPU)
- {
- x87_fnclex (&G.f);
- x86_mov_reg_imm (&G.f, G.r_eax, (GLint) &G.mach->x86.fpucntl_restore);
- x87_fldcw (&G.f, x86_deref (G.r_eax));
- }
- x86_ret (&G.f);
-
- /* fixup forward labels */
- for (i = 0; i < G.fixup_count; i++)
- {
- G.f.csr = G.labels[G.fixups[i].index];
- x86_fixup_fwd_jump (&G.f, G.fixups[i].csr);
- }
-
- slang_alloc_free (G.fixups);
- slang_alloc_free (G.labels);
-
- /* install new code */
- mach->x86.compiled_func = (GLvoid (*) (slang_machine *)) x86_get_func (&G.f);
-
- return GL_TRUE;
+ /*
+ * We need as much as 1M because *all* assembly, including built-in library, is
+ * being translated to x86.
+ * The built-in library occupies 450K, so we can be safe for now.
+ * It is going to change in the future, when we get assembly analysis running.
+ */
+ x86_init_func_size(&G.f, 1048576);
+ G.r_eax = x86_make_reg(file_REG32, reg_AX);
+ G.r_ecx = x86_make_reg(file_REG32, reg_CX);
+ G.r_edx = x86_make_reg(file_REG32, reg_DX);
+ G.r_ebx = x86_make_reg(file_REG32, reg_BX);
+ G.r_esp = x86_make_reg(file_REG32, reg_SP);
+ G.r_ebp = x86_make_reg(file_REG32, reg_BP);
+ G.r_st0 = x86_make_reg(file_x87, 0);
+ G.r_st1 = x86_make_reg(file_x87, 1);
+ G.r_st2 = x86_make_reg(file_x87, 2);
+ G.r_st3 = x86_make_reg(file_x87, 3);
+ G.r_st4 = x86_make_reg(file_x87, 4);
+ G.fixups = NULL;
+ G.fixup_count = 0;
+ G.labels =
+ (GLubyte **) slang_alloc_malloc(file->count * sizeof(GLubyte *));
+ G.mach = mach;
+ G.fpucntl = RESTORE_FPU;
+
+ mach->x86.fpucntl_rnd_neg = RND_NEG_FPU;
+ mach->x86.fpucntl_restore = RESTORE_FPU;
+
+ /* prepare stack and jump to start */
+ x86_push(&G.f, G.r_ebp);
+ x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & mach->x86.esp_restore);
+ x86_push(&G.f, G.r_esp);
+ x86_pop(&G.f, G.r_ecx);
+ x86_mov(&G.f, x86_deref(G.r_eax), G.r_ecx);
+ j_body = x86_jmp_forward(&G.f);
+
+ /* "discard" instructions jump to this label */
+ G.l_discard = x86_get_label(&G.f);
+ x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & G.mach->kill);
+ x86_mov_reg_imm(&G.f, G.r_ecx, 1);
+ x86_mov(&G.f, x86_deref(G.r_eax), G.r_ecx);
+ G.l_exit = x86_get_label(&G.f);
+ j_exit = x86_jmp_forward(&G.f);
+
+ for (i = 0; i < file->count; i++) {
+ G.labels[i] = x86_get_label(&G.f);
+ if (i == start)
+ x86_fixup_fwd_jump(&G.f, j_body);
+ codegen_assem(&G, &file->code[i], &mach->infolog);
+ }
+
+ /*
+ * Restore stack and return.
+ * This must be handled this way, because "discard" can be invoked from any
+ * place in the code.
+ */
+ x86_fixup_fwd_jump(&G.f, j_exit);
+ x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & mach->x86.esp_restore);
+ x86_mov(&G.f, G.r_esp, x86_deref(G.r_eax));
+ x86_pop(&G.f, G.r_ebp);
+ if (G.fpucntl != RESTORE_FPU) {
+ x87_fnclex(&G.f);
+ x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & G.mach->x86.fpucntl_restore);
+ x87_fldcw(&G.f, x86_deref(G.r_eax));
+ }
+ x86_ret(&G.f);
+
+ /* fixup forward labels */
+ for (i = 0; i < G.fixup_count; i++) {
+ G.f.csr = G.labels[G.fixups[i].index];
+ x86_fixup_fwd_jump(&G.f, G.fixups[i].csr);
+ }
+
+ slang_alloc_free(G.fixups);
+ slang_alloc_free(G.labels);
+
+ /* install new code */
+ mach->x86.compiled_func = (GLvoid(*)(slang_machine *)) x86_get_func(&G.f);
+
+ return GL_TRUE;
}
#endif
-
diff --git a/src/mesa/shader/slang/slang_link.h b/src/mesa/shader/slang/slang_link.h
index 2195ec5bdf..433964223a 100644
--- a/src/mesa/shader/slang/slang_link.h
+++ b/src/mesa/shader/slang/slang_link.h
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.6
+ * Version: 6.5.2
*
* Copyright (C) 2006 Brian Paul All Rights Reserved.
*
@@ -38,13 +38,15 @@ enum
SLANG_SHADER_MAX
};
-/*
+
+/**
* Active variables.
*
- * Active uniforms/attribs can be queried by the application to get a list of
- * uniforms/attribs actually used by shaders (uniforms) or vertex shader only (attribs).
+ * Active uniforms/attribs can be queried by the application to get a
+ * list of uniforms/attribs actually used by shaders (uniforms) or
+ * vertex shader only (attribs).
*/
-
+/*@{*/
typedef struct
{
slang_export_data_quant *quant;
@@ -56,14 +58,17 @@ typedef struct
slang_active_variable *table;
GLuint count;
} slang_active_variables;
+/*@}*/
-/*
+
+/**
* Attrib binding override.
*
- * The application can override GL attrib binding by specifying its preferred index assignment
- * for a given attrib name. Those overrides are taken into account while linking the program.
+ * The application can override GL attrib binding by specifying its
+ * preferred index assignment for a given attrib name. Those overrides
+ * are taken into account while linking the program.
*/
-
+/*@{*/
typedef struct
{
GLuint index;
@@ -75,26 +80,33 @@ typedef struct
slang_attrib_override *table;
GLuint count;
} slang_attrib_overrides;
+/*@}*/
+
extern GLboolean
_slang_attrib_overrides_add (slang_attrib_overrides *, GLuint, const GLchar *);
-/*
+
+/**
* Uniform bindings.
*
- * Each slang_uniform_binding holds an array of addresses to actual memory locations in those
- * shader types that use that uniform. Uniform bindings are held in an array and accessed
- * by array index which is seen to the application as a uniform location.
+ * Each slang_uniform_binding holds an array of addresses to actual
+ * memory locations in those shader types that use that
+ * uniform. Uniform bindings are held in an array and accessed by
+ * array index which is seen to the application as a uniform location.
*
- * When the application writes to a particular uniform, it specifies its location.
- * This location is treated as an array index to slang_uniform_bindings::table and tested
- * against slang_uniform_bindings::count limit. The result is a pointer to slang_uniform_binding.
- * The type of data being written to uniform is tested against slang_uniform_binding::quant.
- * If the types are compatible, the array slang_uniform_binding::address is iterated for
- * each shader type and if the address is valid (i.e. the uniform is used by this shader type),
- * the new uniform value is written at that address.
+ * When the application writes to a particular uniform, it specifies
+ * its location. This location is treated as an array index to
+ * slang_uniform_bindings::table and tested against
+ * slang_uniform_bindings::count limit. The result is a pointer to
+ * slang_uniform_binding. The type of data being written to uniform
+ * is tested against slang_uniform_binding::quant. If the types are
+ * compatible, the array slang_uniform_binding::address is iterated
+ * for each shader type and if the address is valid (i.e. the uniform
+ * is used by this shader type), the new uniform value is written at
+ * that address.
*/
-
+/*@{*/
typedef struct
{
slang_export_data_quant *quant;
@@ -107,16 +119,20 @@ typedef struct
slang_uniform_binding *table;
GLuint count;
} slang_uniform_bindings;
+/*@}*/
-/*
+
+/**
* Attrib bindings.
*
- * There is a fixed number of vertex attrib vectors (attrib slots). The slang_attrib_slot::addr
- * maps vertex attrib index to the actual memory location of the attrib in vertex shader.
- * One vertex attrib can span over many attrib slots (this is the case for matrices). The
- * slang_attrib_binding::first_slot_index holds the first slot index that the attrib is bound to.
+ * There is a fixed number of vertex attrib vectors (attrib
+ * slots). The slang_attrib_slot::addr maps vertex attrib index to the
+ * actual memory location of the attrib in vertex shader. One vertex
+ * attrib can span over many attrib slots (this is the case for
+ * matrices). The slang_attrib_binding::first_slot_index holds the
+ * first slot index that the attrib is bound to.
*/
-
+/*@{*/
typedef struct
{
slang_export_data_quant *quant;
@@ -126,8 +142,8 @@ typedef struct
typedef struct
{
- GLuint addr; /* memory location */
- GLuint fill; /* 1..4, number of components used */
+ GLuint addr; /**< memory location */
+ GLuint fill; /**< 1..4, number of components used */
} slang_attrib_slot;
typedef struct
@@ -136,16 +152,20 @@ typedef struct
GLuint binding_count;
slang_attrib_slot slots[MAX_VERTEX_ATTRIBS];
} slang_attrib_bindings;
+/*@}*/
-/*
+
+
+/**
* Varying bindings.
*
- * There is a fixed number of varying floats (varying slots). The slang_varying_slot::vert_addr
- * maps varying float index to the actual memory location of the output variable in vertex shader.
- * The slang_varying_slot::frag_addr maps varying float index to the actual memory location of
- * the input variable in fragment shader.
+ * There is a fixed number of varying floats (varying slots). The
+ * slang_varying_slot::vert_addr maps varying float index to the
+ * actual memory location of the output variable in vertex shader.
+ * The slang_varying_slot::frag_addr maps varying float index to the
+ * actual memory location of the input variable in fragment shader.
*/
-
+/*@{*/
typedef struct
{
GLuint vert_addr;
@@ -166,20 +186,25 @@ typedef struct
slang_varying_slot slots[MAX_VARYING_FLOATS];
GLuint slot_count;
} slang_varying_bindings;
+/*@}*/
-/*
+
+/**
* Texture usage.
*
- * A slang_texture_usage struct holds indirect information about texture image unit usage. The
- * slang_texture_usages::table is derived from active uniform table by extracting only uniforms
- * that are samplers.
+ * A slang_texture_usage struct holds indirect information about
+ * texture image unit usage. The slang_texture_usages::table is
+ * derived from active uniform table by extracting only uniforms that
+ * are samplers.
*
- * To collect current texture usage one must iterate the slang_texture_usages::table and read
- * uniform at address slang_texture_usage::frag_address to get texture unit index. This
- * index, coupled with texture access type (target) taken from slang_texture_usage::quant
- * forms texture usage for that texture unit.
+ * To collect current texture usage one must iterate the
+ * slang_texture_usages::table and read uniform at address
+ * slang_texture_usage::frag_address to get texture unit index. This
+ * index, coupled with texture access type (target) taken from
+ * slang_texture_usage::quant forms texture usage for that texture
+ * unit.
*/
-
+/*@{*/
typedef struct
{
slang_export_data_quant *quant;
@@ -191,6 +216,8 @@ typedef struct
slang_texture_usage *table;
GLuint count;
} slang_texture_usages;
+/*@}*/
+
extern GLvoid
_slang_texture_usages_ctr (slang_texture_usages *);
diff --git a/src/mesa/shader/slang/slang_preprocess.c b/src/mesa/shader/slang/slang_preprocess.c
index 43aa9a1e95..66a6a98392 100644
--- a/src/mesa/shader/slang/slang_preprocess.c
+++ b/src/mesa/shader/slang/slang_preprocess.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.6
+ * Version: 6.5.2
*
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
*
@@ -32,15 +32,15 @@
#include "grammar_mesa.h"
#include "slang_preprocess.h"
-static const char *slang_pp_directives_syn =
+LONGSTRING static const char *slang_pp_directives_syn =
#include "library/slang_pp_directives_syn.h"
;
-static const char *slang_pp_expression_syn =
+LONGSTRING static const char *slang_pp_expression_syn =
#include "library/slang_pp_expression_syn.h"
;
-static const char *slang_pp_version_syn =
+LONGSTRING static const char *slang_pp_version_syn =
#include "library/slang_pp_version_syn.h"
;
diff --git a/src/mesa/shader/slang/slang_utility.c b/src/mesa/shader/slang/slang_utility.c
index 54fcc8a238..256d52455d 100644
--- a/src/mesa/shader/slang/slang_utility.c
+++ b/src/mesa/shader/slang/slang_utility.c
@@ -131,75 +131,92 @@ slang_string_cstr (slang_string *self)
/* slang_atom_pool */
-void slang_atom_pool_construct (slang_atom_pool *pool)
+void
+slang_atom_pool_construct(slang_atom_pool * pool)
{
- GLuint i;
+ GLuint i;
- for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++)
- pool->entries[i] = NULL;
+ for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++)
+ pool->entries[i] = NULL;
}
-void slang_atom_pool_destruct (slang_atom_pool *pool)
+void
+slang_atom_pool_destruct (slang_atom_pool * pool)
{
- GLuint i;
+ GLuint i;
- for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++)
- {
- slang_atom_entry *entry;
+ for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++) {
+ slang_atom_entry * entry;
- entry = pool->entries[i];
- while (entry != NULL)
- {
- slang_atom_entry *next;
-
- next = entry->next;
- slang_alloc_free (entry->id);
- slang_alloc_free (entry);
- entry = next;
+ entry = pool->entries[i];
+ while (entry != NULL) {
+ slang_atom_entry *next;
+
+ next = entry->next;
+ slang_alloc_free(entry->id);
+ slang_alloc_free(entry);
+ entry = next;
}
}
}
-slang_atom slang_atom_pool_atom (slang_atom_pool *pool, const char *id)
+/*
+ * Search the atom pool for an atom with a given name.
+ * If atom is not found, create and add it to the pool.
+ * Returns ATOM_NULL if the atom was not found and the function failed to create a new atom.
+ */
+slang_atom
+slang_atom_pool_atom(slang_atom_pool * pool, const char * id)
{
- GLuint hash;
- const char *p = id;
- slang_atom_entry **entry;
-
- hash = 0;
- while (*p != '\0')
- {
- GLuint g;
-
- hash = (hash << 4) + (GLuint) *p++;
- g = hash & 0xf0000000;
- if (g != 0)
- hash ^= g >> 24;
- hash &= ~g;
- }
- hash %= SLANG_ATOM_POOL_SIZE;
-
- entry = &pool->entries[hash];
- while (*entry != NULL)
- {
- if (slang_string_compare ((**entry).id, id) == 0)
- return (slang_atom) (**entry).id;
- entry = &(**entry).next;
- }
-
- *entry = (slang_atom_entry *) slang_alloc_malloc (sizeof (slang_atom_entry));
- if (*entry == NULL)
- return SLANG_ATOM_NULL;
+ GLuint hash;
+ const char * p = id;
+ slang_atom_entry ** entry;
+
+ /* Hash a given string to a number in the range [0, ATOM_POOL_SIZE). */
+ hash = 0;
+ while (*p != '\0') {
+ GLuint g;
+
+ hash = (hash << 4) + (GLuint) (*p++);
+ g = hash & 0xf0000000;
+ if (g != 0)
+ hash ^= g >> 24;
+ hash &= ~g;
+ }
+ hash %= SLANG_ATOM_POOL_SIZE;
+
+ /* Now the hash points to a linked list of atoms with names that have the same hash value.
+ * Search the linked list for a given name. */
+ entry = &pool->entries[hash];
+ while (*entry != NULL) {
+ /* If the same, return the associated atom. */
+ if (slang_string_compare((**entry).id, id) == 0)
+ return (slang_atom) (**entry).id;
+ /* Grab the next atom in the linked list. */
+ entry = &(**entry).next;
+ }
- (**entry).next = NULL;
- (**entry).id = slang_string_duplicate (id);
- if ((**entry).id == NULL)
- return SLANG_ATOM_NULL;
- return (slang_atom) (**entry).id;
+ /* Okay, we have not found an atom. Create a new entry for it.
+ * Note that the <entry> points to the last entry's <next> field. */
+ *entry = (slang_atom_entry *) (slang_alloc_malloc(sizeof(slang_atom_entry)));
+ if (*entry == NULL)
+ return SLANG_ATOM_NULL;
+
+ /* Initialize a new entry. Because we'll need the actual name of the atom, we use the pointer
+ * to this string as an actual atom's value. */
+ (**entry).next = NULL;
+ (**entry).id = slang_string_duplicate(id);
+ if ((**entry).id == NULL)
+ return SLANG_ATOM_NULL;
+ return (slang_atom) (**entry).id;
}
-const char *slang_atom_pool_id (slang_atom_pool *pool, slang_atom atom)
+/*
+ * Return the name of a given atom.
+ */
+const char *
+slang_atom_pool_id(slang_atom_pool * pool, slang_atom atom)
{
- return (const char *) atom;
+ return (const char *) (atom);
}
diff --git a/src/mesa/shader/slang/sources b/src/mesa/shader/slang/sources
index f03f1ed187..00d617fa8a 100644
--- a/src/mesa/shader/slang/sources
+++ b/src/mesa/shader/slang/sources
@@ -19,3 +19,26 @@ slang_link.c \
slang_preprocess.c \
slang_storage.c \
slang_utility.c
+
+MESA_SHADER_SLANG_HEADERS = \
+slang_analyse.h \
+slang_assemble.h \
+slang_assemble_assignment.h \
+slang_assemble_conditional.h \
+slang_assemble_constructor.h \
+slang_assemble_typeinfo.h \
+slang_compile.h \
+slang_compile_function.h \
+slang_compile_operation.h \
+slang_compile_struct.h \
+slang_compile_variable.h \
+slang_execute.h \
+slang_export.h \
+slang_library_noise.h \
+slang_library_texsample.h \
+slang_link.h \
+slang_mesa.h \
+slang_preprocess.h \
+slang_storage.h \
+slang_utility.h \
+traverse_wrap.h