intermediate code generator (not finished);
authorMichal Krol <mjkrol@gmail.org>
Thu, 19 May 2005 11:50:53 +0000 (11:50 +0000)
committerMichal Krol <mjkrol@gmail.org>
Thu, 19 May 2005 11:50:53 +0000 (11:50 +0000)
generic back-end interpreter (interprets directly intermediate code)

15 files changed:
src/mesa/shader/slang/slang_assemble.c [new file with mode: 0644]
src/mesa/shader/slang/slang_assemble.h [new file with mode: 0644]
src/mesa/shader/slang/slang_assemble_conditional.c [new file with mode: 0644]
src/mesa/shader/slang/slang_assemble_conditional.h [new file with mode: 0644]
src/mesa/shader/slang/slang_assemble_constructor.c [new file with mode: 0644]
src/mesa/shader/slang/slang_assemble_constructor.h [new file with mode: 0644]
src/mesa/shader/slang/slang_assemble_typeinfo.c [new file with mode: 0644]
src/mesa/shader/slang/slang_assemble_typeinfo.h [new file with mode: 0644]
src/mesa/shader/slang/slang_compile.c
src/mesa/shader/slang/slang_compile.h
src/mesa/shader/slang/slang_execute.c [new file with mode: 0644]
src/mesa/shader/slang/slang_execute.h [new file with mode: 0644]
src/mesa/shader/slang/slang_storage.c [new file with mode: 0644]
src/mesa/shader/slang/slang_storage.h [new file with mode: 0644]
src/mesa/sources

diff --git a/src/mesa/shader/slang/slang_assemble.c b/src/mesa/shader/slang/slang_assemble.c
new file mode 100644 (file)
index 0000000..03672b2
--- /dev/null
@@ -0,0 +1,1385 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  6.3\r
+ *\r
+ * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * \file slang_assemble.c\r
+ * slang intermediate code assembler\r
+ * \author Michal Krol\r
+ */\r
+\r
+#include "imports.h"\r
+#include "slang_utility.h"\r
+#include "slang_assemble.h"\r
+#include "slang_compile.h"\r
+#include "slang_storage.h"\r
+#include "slang_assemble_constructor.h"\r
+#include "slang_assemble_typeinfo.h"\r
+#include "slang_assemble_conditional.h"\r
+\r
+/* slang_assembly */\r
+\r
+static void slang_assembly_construct (slang_assembly *asm)\r
+{\r
+       asm->type = slang_asm_none;\r
+}\r
+\r
+static void slang_assembly_destruct (slang_assembly *asm)\r
+{\r
+}\r
+\r
+/* slang_assembly_file */\r
+\r
+void slang_assembly_file_construct (slang_assembly_file *file)\r
+{\r
+       file->code = NULL;\r
+       file->count = 0;\r
+}\r
+\r
+void slang_assembly_file_destruct (slang_assembly_file *file)\r
+{\r
+       unsigned int i;\r
+\r
+       for (i = 0; i < file->count; i++)\r
+               slang_assembly_destruct (file->code + i);\r
+       slang_alloc_free (file->code);\r
+}\r
+\r
+static int slang_assembly_file_push_new (slang_assembly_file *file)\r
+{\r
+       file->code = (slang_assembly *) slang_alloc_realloc (file->code, file->count * sizeof (\r
+               slang_assembly), (file->count + 1) * sizeof (slang_assembly));\r
+       if (file->code != NULL)\r
+       {\r
+               slang_assembly_construct (file->code + file->count);\r
+               file->count++;\r
+               return 1;\r
+       }\r
+       return 0;\r
+}\r
+\r
+static int slang_assembly_file_push_general (slang_assembly_file *file, slang_assembly_type type,\r
+       GLfloat literal, GLuint label, GLuint size)\r
+{\r
+       slang_assembly *asm;\r
+       if (!slang_assembly_file_push_new (file))\r
+               return 0;\r
+       asm = file->code + file->count - 1;\r
+       asm->type = type;\r
+       asm->literal = literal;\r
+       asm->param[0] = label;\r
+       asm->param[1] = size;\r
+       return 1;\r
+}\r
+\r
+int slang_assembly_file_push (slang_assembly_file *file, slang_assembly_type type)\r
+{\r
+       return slang_assembly_file_push_general (file, type, (GLfloat) 0, 0, 0);\r
+}\r
+\r
+int slang_assembly_file_push_label (slang_assembly_file *file, slang_assembly_type type,\r
+       GLuint label)\r
+{\r
+       return slang_assembly_file_push_general (file, type, (GLfloat) 0, label, 0);\r
+}\r
+\r
+int slang_assembly_file_push_label2 (slang_assembly_file *file, slang_assembly_type type,\r
+       GLuint label1, GLuint label2)\r
+{\r
+       return slang_assembly_file_push_general (file, type, (GLfloat) 0, label1, label2);\r
+}\r
+\r
+int slang_assembly_file_push_literal (slang_assembly_file *file, slang_assembly_type type,\r
+       GLfloat literal)\r
+{\r
+       return slang_assembly_file_push_general (file, type, literal, 0, 0);\r
+}\r
+\r
+/* utility functions */\r
+\r
+static int sizeof_variable (slang_type_specifier *spec, slang_operation *array_size,\r
+       slang_assembly_name_space *space, unsigned int *size)\r
+{\r
+       slang_storage_aggregate agg;\r
+\r
+       slang_storage_aggregate_construct (&agg);\r
+       if (!_slang_aggregate_variable (&agg, spec, array_size, space->funcs, space->structs))\r
+       {\r
+               slang_storage_aggregate_destruct (&agg);\r
+               return 0;\r
+       }\r
+       *size += _slang_sizeof_aggregate (&agg);\r
+       slang_storage_aggregate_destruct (&agg);\r
+       return 1;\r
+}\r
+\r
+static int sizeof_variable2 (slang_variable *var, slang_assembly_name_space *space,\r
+       unsigned int *size)\r
+{\r
+       var->address = *size;\r
+       return sizeof_variable (&var->type.specifier, var->array_size, space, size);\r
+}\r
+\r
+static int sizeof_variables (slang_variable_scope *vars, unsigned int start, unsigned int stop,\r
+       slang_assembly_name_space *space, unsigned int *size)\r
+{\r
+       unsigned int i;\r
+\r
+       for (i = start; i < stop; i++)\r
+               if (!sizeof_variable2 (vars->variables + i, space, size))\r
+                       return 0;\r
+       return 1;\r
+}\r
+\r
+static int collect_locals (slang_operation *op, slang_assembly_name_space *space,\r
+       unsigned int *size)\r
+{\r
+       unsigned int i;\r
+\r
+       if (!sizeof_variables (op->locals, 0, op->locals->num_variables, space, size))\r
+               return 0;\r
+       for (i = 0; i < op->num_children; i++)\r
+               if (!collect_locals (op->children + i, space, size))\r
+                       return 0;\r
+       return 1;\r
+}\r
+\r
+/* _slang_locate_function() */\r
+\r
+slang_function *_slang_locate_function (const char *name, slang_operation *params,\r
+       unsigned int num_params, slang_assembly_name_space *space)\r
+{\r
+       unsigned int i;\r
+\r
+       for (i = 0; i < space->funcs->num_functions; i++)\r
+       {\r
+               unsigned int j;\r
+               slang_function *f = space->funcs->functions + i;\r
+\r
+               if (slang_string_compare (name, f->header.name) != 0)\r
+                       continue;\r
+               if (f->param_count != num_params)\r
+                       continue;\r
+               for (j = 0; j < num_params; j++)\r
+               {\r
+                       slang_assembly_typeinfo ti;\r
+                       slang_assembly_typeinfo_construct (&ti);\r
+                       if (!_slang_typeof_operation (params + j, space, &ti))\r
+                       {\r
+                               slang_assembly_typeinfo_destruct (&ti);\r
+                               return 0;\r
+                       }\r
+                       if (!slang_type_specifier_equal (&ti.spec, &f->parameters->variables[j].type.specifier))\r
+                       {\r
+                               slang_assembly_typeinfo_destruct (&ti);\r
+                               break;\r
+                       }\r
+                       slang_assembly_typeinfo_destruct (&ti);\r
+                       /* "out" and "inout" formal parameter requires the actual parameter to be l-value */\r
+                       if (!ti.can_be_referenced &&\r
+                               f->parameters->variables[j].type.qualifier != slang_qual_out &&\r
+                               f->parameters->variables[j].type.qualifier != slang_qual_inout)\r
+                               break;\r
+               }\r
+               if (j == num_params)\r
+                       return f;\r
+       }\r
+       if (space->funcs->outer_scope != NULL)\r
+       {\r
+               slang_assembly_name_space my_space = *space;\r
+               my_space.funcs = space->funcs->outer_scope;\r
+               return _slang_locate_function (name, params, num_params, &my_space);\r
+       }\r
+       return NULL;\r
+}\r
+\r
+/* _slang_assemble_function() */\r
+\r
+int _slang_assemble_function (slang_assembly_file *file, slang_function *fun,\r
+       slang_assembly_name_space *space)\r
+{\r
+       unsigned int param_size, local_size;\r
+       unsigned int skip, cleanup;\r
+       slang_assembly_flow_control flow;\r
+       slang_assembly_local_info info;\r
+       slang_assembly_stack_info stk;\r
+\r
+       fun->address = file->count;\r
+\r
+       if (fun->body == NULL)\r
+       {\r
+               /* TODO: jump to the actual function body */\r
+               return 1;\r
+       }\r
+\r
+       /* calculate return value and parameters size */\r
+       param_size = 0;\r
+       if (fun->header.type.specifier.type != slang_spec_void)\r
+               if (!sizeof_variable (&fun->header.type.specifier, NULL, space, &param_size))\r
+                       return 0;\r
+       info.ret_size = param_size;\r
+       if (!sizeof_variables (fun->parameters, 0, fun->param_count, space, &param_size))\r
+               return 0;\r
+\r
+       /* calculate local variables size, take into account the four-byte return address and\r
+       temporaries for various tasks */\r
+       info.addr_tmp = param_size + 4;\r
+       info.swizzle_tmp = param_size + 4 + 4;\r
+       local_size = param_size + 4 + 4 + 16;\r
+       if (!sizeof_variables (fun->parameters, fun->param_count, fun->parameters->num_variables, space,\r
+               &local_size))\r
+               return 0;\r
+       if (!collect_locals (fun->body, space, &local_size))\r
+               return 0;\r
+\r
+       /* allocate local variable storage */\r
+       if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, local_size - param_size - 4))\r
+               return 0;\r
+\r
+       /* mark a new frame for function variable storage */\r
+       if (!slang_assembly_file_push_label (file, slang_asm_enter, local_size))\r
+               return 0;\r
+\r
+       /* skip the cleanup jump */\r
+       skip = file->count;\r
+       if (!slang_assembly_file_push_new (file))\r
+               return 0;\r
+       file->code[skip].type = slang_asm_jump;\r
+\r
+       /* all "return" statements will be directed here */\r
+       flow.function_end = file->count;\r
+       cleanup = file->count;\r
+       if (!slang_assembly_file_push_new (file))\r
+               return 0;\r
+       file->code[cleanup].type = slang_asm_jump;\r
+\r
+       /* execute the function body */\r
+       file->code[skip].param[0] = file->count;\r
+       if (!_slang_assemble_operation (file, fun->body, 0, &flow, space, &info, &stk))\r
+               return 0;\r
+\r
+       /* this is the end of the function - restore the old function frame */\r
+       file->code[cleanup].param[0] = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_leave))\r
+               return 0;\r
+\r
+       /* free local variable storage */\r
+       if (!slang_assembly_file_push_label (file, slang_asm_local_free, local_size - param_size - 4))\r
+               return 0;\r
+\r
+       /* jump out of the function */\r
+       if (!slang_assembly_file_push (file, slang_asm_return))\r
+               return 0;\r
+       return 1;\r
+}\r
+\r
+int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int ref,\r
+       slang_assembly_name_space *space)\r
+{\r
+       slang_assembly_typeinfo ti;\r
+       unsigned int size;\r
+\r
+       slang_assembly_typeinfo_construct (&ti);\r
+       if (!_slang_typeof_operation (op, space, &ti))\r
+       {\r
+               slang_assembly_typeinfo_destruct (&ti);\r
+               return 0;\r
+       }\r
+       if (ti.spec.type == slang_spec_void)\r
+               size = 0;\r
+       else if (ref)\r
+               size = 4;\r
+       else\r
+       {\r
+               size = 0;\r
+               if (!sizeof_variable (&ti.spec, NULL, space, &size))\r
+               {\r
+                       slang_assembly_typeinfo_destruct (&ti);\r
+                       return 0;\r
+               }\r
+       }\r
+       slang_assembly_typeinfo_destruct (&ti);\r
+       if (size != 0)\r
+       {\r
+               if (!slang_assembly_file_push_label (file, slang_asm_local_free, size))\r
+                       return 0;\r
+       }\r
+       return 1;\r
+}\r
+\r
+/* _slang_assemble_operation() */\r
+\r
+/* XXX: general swizzle! */\r
+static int dereference_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,\r
+       unsigned int index, unsigned int *size, slang_assembly_local_info *info)\r
+{\r
+       unsigned int i;\r
+\r
+       for (i = agg->count; i > 0; i--)\r
+       {\r
+               const slang_storage_array *arr = agg->arrays + i - 1;\r
+               unsigned int j;\r
+\r
+               for (j = arr->length; j > 0; j--)\r
+               {\r
+                       if (arr->type == slang_stor_aggregate)\r
+                       {\r
+                               if (!dereference_aggregate (file, arr->aggregate, index, size, info))\r
+                                       return 0;\r
+                       }\r
+                       else\r
+                       {\r
+                               *size -= 4;\r
+                               if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp,\r
+                                       4))\r
+                                       return 0;\r
+                               if (!slang_assembly_file_push (file, slang_asm_addr_deref))\r
+                                       return 0;\r
+                               if (!slang_assembly_file_push_label (file, slang_asm_addr_push, *size))\r
+                                       return 0;\r
+                               if (!slang_assembly_file_push (file, slang_asm_addr_add))\r
+                                       return 0;\r
+                               switch (arr->type)\r
+                               {\r
+                               case slang_stor_bool:\r
+                                       if (!slang_assembly_file_push (file, slang_asm_bool_deref))\r
+                                               return 0;\r
+                                       break;\r
+                               case slang_stor_int:\r
+                                       if (!slang_assembly_file_push (file, slang_asm_int_deref))\r
+                                               return 0;\r
+                                       break;\r
+                               case slang_stor_float:\r
+                                       if (!slang_assembly_file_push (file, slang_asm_float_deref))\r
+                                               return 0;\r
+                                       break;\r
+                               }\r
+                               index += 4;\r
+                       }\r
+               }\r
+       }\r
+       return 1;\r
+}\r
+/* XXX: general swizzle! */\r
+static int dereference (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_name_space *space, slang_assembly_local_info *info)\r
+{\r
+       slang_assembly_typeinfo ti;\r
+       int result;\r
+       slang_storage_aggregate agg;\r
+       unsigned int size;\r
+\r
+       slang_assembly_typeinfo_construct (&ti);\r
+       if (!_slang_typeof_operation (op, space, &ti))\r
+       {\r
+               slang_assembly_typeinfo_destruct (&ti);\r
+               return 0;\r
+       }\r
+\r
+       slang_storage_aggregate_construct (&agg);\r
+       if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs))\r
+       {\r
+               slang_storage_aggregate_destruct (&agg);\r
+               slang_assembly_typeinfo_destruct (&ti);\r
+               return 0;\r
+       }\r
+\r
+       size = _slang_sizeof_aggregate (&agg);\r
+       result = dereference_aggregate (file, &agg, 0, &size, info);\r
+\r
+       slang_storage_aggregate_destruct (&agg);\r
+       slang_assembly_typeinfo_destruct (&ti);\r
+       return result;\r
+}\r
+\r
+static int call_function (slang_assembly_file *file, slang_function *fun, slang_operation *params,\r
+       unsigned int param_count, int assignment, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info)\r
+{\r
+       unsigned int ret_size, i;\r
+       slang_assembly_stack_info stk;\r
+\r
+       /* make room for the return value, if any */\r
+       ret_size = 0;\r
+       if (!sizeof_variable (&fun->header.type.specifier, NULL, space, &ret_size))\r
+               return 0;\r
+       if (ret_size > 0)\r
+       {\r
+               if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, ret_size))\r
+                       return 0;\r
+       }\r
+\r
+       /* push the actual parameters on the stack */\r
+       for (i = 0; i < param_count; i++)\r
+       {\r
+               slang_assembly_flow_control flow;\r
+\r
+               if (i == 0 && assignment)\r
+               {\r
+                       if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))\r
+                               return 0;\r
+                       /* TODO: optimize the "out" parameter case */\r
+                       /* TODO: inspect stk */\r
+                       if (!_slang_assemble_operation (file, params, 1, &flow, space, info, &stk))\r
+                               return 0;\r
+                       if (!slang_assembly_file_push (file, slang_asm_addr_copy))\r
+                               return 0;\r
+                       if (!slang_assembly_file_push (file, slang_asm_addr_deref))\r
+                               return 0;\r
+                       if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))\r
+                               return 0;\r
+                       if (!slang_assembly_file_push (file, slang_asm_addr_deref))\r
+                               return 0;\r
+                       if (!dereference (file, params, space, info))\r
+                               return 0;\r
+               }\r
+               else\r
+               {\r
+                       /* TODO: for "out" and "inout" parameters also push the address (first) */\r
+                       /* TODO: optimize the "out" parameter case */\r
+                       /* TODO: inspect stk */\r
+                       if (!_slang_assemble_operation (file, params + i, 0, &flow, space, info, &stk))\r
+                               return 0;\r
+               }\r
+       }\r
+\r
+       /* call the function */\r
+       if (!slang_assembly_file_push_label (file, slang_asm_call, fun->address))\r
+               return 0;\r
+\r
+       /* pop the parameters from the stack */\r
+       for (i = param_count; i > 0; i--)\r
+       {\r
+               /* XXX: copy inout/out params back to the actual variables */\r
+               if (!_slang_cleanup_stack (file, params + i - 1, 0, space))\r
+                       return 0;\r
+       }\r
+\r
+       return 1;\r
+}\r
+\r
+static int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,\r
+       unsigned int param_count, int assignment, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info)\r
+{\r
+       slang_function *fun = _slang_locate_function (name, params, param_count, space);\r
+       if (fun == NULL)\r
+               return 0;\r
+       return call_function (file, fun, params, param_count, assignment, space, info);\r
+}\r
+\r
+static int call_function_name_dummyint (slang_assembly_file *file, const char *name,\r
+       slang_operation *params, slang_assembly_name_space *space, slang_assembly_local_info *info)\r
+{\r
+       slang_operation p2[2];\r
+       int result;\r
+\r
+       p2[0] = *params;\r
+       if (!slang_operation_construct_a (p2 + 1))\r
+               return 0;\r
+       p2[1].type = slang_oper_literal_int;\r
+       result = call_function_name (file, name, p2, 2, 0, space, info);\r
+       slang_operation_destruct (p2 + 1);\r
+       return result;\r
+}\r
+\r
+static int call_asm_instruction (slang_assembly_file *file, const char *name)\r
+{\r
+       const struct\r
+       {\r
+               const char *name;\r
+               slang_assembly_type code1, code2;\r
+       } inst[] = {\r
+               { "float_to_int",   slang_asm_float_to_int,   slang_asm_int_copy },\r
+               { "int_to_float",   slang_asm_int_to_float,   slang_asm_float_copy },\r
+               { "float_copy",     slang_asm_float_copy,     slang_asm_none },\r
+               { "int_copy",       slang_asm_int_copy,       slang_asm_none },\r
+               { "bool_copy",      slang_asm_bool_copy,      slang_asm_none },\r
+               { "float_add",      slang_asm_float_add,      slang_asm_float_copy },\r
+               { "float_multiply", slang_asm_float_multiply, slang_asm_float_copy },\r
+               { "float_divide",   slang_asm_float_divide,   slang_asm_float_copy },\r
+               { "float_negate",   slang_asm_float_negate,   slang_asm_float_copy },\r
+               { "float_less",     slang_asm_float_less,     slang_asm_bool_copy },\r
+               { "float_equal",    slang_asm_float_equal,    slang_asm_bool_copy },\r
+               { NULL,             slang_asm_none,           slang_asm_none }\r
+       };\r
+       unsigned int i;\r
+\r
+       for (i = 0; inst[i].name != NULL; i++)\r
+               if (slang_string_compare (name, inst[i].name) == 0)\r
+                       break;\r
+       if (inst[i].name == NULL)\r
+               return 0;\r
+\r
+       if (!slang_assembly_file_push_label2 (file, inst[i].code1, 4, 0))\r
+               return 0;\r
+       if (inst[i].code2 != slang_asm_none)\r
+               if (!slang_assembly_file_push_label2 (file, inst[i].code2, 4, 0))\r
+                       return 0;\r
+\r
+       /* clean-up the stack from the remaining dst address */\r
+       if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
+               return 0;\r
+\r
+       return 1;\r
+}\r
+/* XXX: general swizzle! */\r
+static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,\r
+       unsigned int *index, unsigned int size, slang_assembly_local_info *info)\r
+{\r
+       unsigned int i;\r
+\r
+       for (i = 0; i < agg->count; i++)\r
+       {\r
+               const slang_storage_array *arr = agg->arrays + i;\r
+               unsigned int j;\r
+\r
+               for (j = 0; j < arr->length; j++)\r
+               {\r
+                       if (arr->type == slang_stor_aggregate)\r
+                       {\r
+                               if (!assign_aggregate (file, arr->aggregate, index, size, info))\r
+                                       return 0;\r
+                       }\r
+                       else\r
+                       {\r
+                               switch (arr->type)\r
+                               {\r
+                               case slang_stor_bool:\r
+                                       if (!slang_assembly_file_push_label2 (file, slang_asm_bool_copy,\r
+                                               size - *index, *index))\r
+                                               return 0;\r
+                                       break;\r
+                               case slang_stor_int:\r
+                                       if (!slang_assembly_file_push_label2 (file, slang_asm_int_copy,\r
+                                               size - *index, *index))\r
+                                               return 0;\r
+                                       break;\r
+                               case slang_stor_float:\r
+                                       if (!slang_assembly_file_push_label2 (file, slang_asm_float_copy,\r
+                                               size - *index, *index))\r
+                                               return 0;\r
+                                       break;\r
+                               }\r
+                               *index += 4;\r
+                       }\r
+               }\r
+       }\r
+       return 1;\r
+}\r
+/* XXX: general swizzle! */\r
+static int assignment (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_name_space *space, slang_assembly_local_info *info)\r
+{\r
+       slang_assembly_typeinfo ti;\r
+       int result;\r
+       slang_storage_aggregate agg;\r
+       unsigned int index, size;\r
+\r
+       slang_assembly_typeinfo_construct (&ti);\r
+       if (!_slang_typeof_operation (op, space, &ti))\r
+       {\r
+               slang_assembly_typeinfo_destruct (&ti);\r
+               return 0;\r
+       }\r
+\r
+       slang_storage_aggregate_construct (&agg);\r
+       if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs))\r
+       {\r
+               slang_storage_aggregate_destruct (&agg);\r
+               slang_assembly_typeinfo_destruct (&ti);\r
+               return 0;\r
+       }\r
+\r
+       index = 0;\r
+       size = _slang_sizeof_aggregate (&agg);\r
+       result = assign_aggregate (file, &agg, &index, size, info);\r
+\r
+       slang_storage_aggregate_destruct (&agg);\r
+       slang_assembly_typeinfo_destruct (&ti);\r
+       return result;\r
+}\r
+/* XXX: general swizzle! */\r
+static int equality_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,\r
+       unsigned int *index, unsigned int size, slang_assembly_local_info *info, unsigned int z_label)\r
+{\r
+       unsigned int i;\r
+\r
+       for (i = 0; i < agg->count; i++)\r
+       {\r
+               const slang_storage_array *arr = agg->arrays + i;\r
+               unsigned int j;\r
+\r
+               for (j = 0; j < arr->length; j++)\r
+               {\r
+                       if (arr->type == slang_stor_aggregate)\r
+                       {\r
+                               if (!equality_aggregate (file, arr->aggregate, index, size, info, z_label))\r
+                                       return 0;\r
+                       }\r
+                       else\r
+                       {\r
+                               if (!slang_assembly_file_push_label2 (file, slang_asm_float_equal, size + *index,\r
+                                       *index))\r
+                                       return 0;\r
+                               *index += 4;\r
+                               if (!slang_assembly_file_push_label (file, slang_asm_jump_if_zero, z_label))\r
+                                       return 0;\r
+                       }\r
+               }\r
+       }\r
+       return 1;\r
+}\r
+/* XXX: general swizzle! */\r
+static int equality (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_name_space *space, slang_assembly_local_info *info, int equal)\r
+{\r
+       slang_assembly_typeinfo ti;\r
+       int result;\r
+       slang_storage_aggregate agg;\r
+       unsigned int index, size;\r
+       unsigned int skip_jump, true_label, true_jump, false_label, false_jump;\r
+\r
+       /* get type of operation */\r
+       slang_assembly_typeinfo_construct (&ti);\r
+       if (!_slang_typeof_operation (op, space, &ti))\r
+       {\r
+               slang_assembly_typeinfo_destruct (&ti);\r
+               return 0;\r
+       }\r
+\r
+       /* convert it to an aggregate */\r
+       slang_storage_aggregate_construct (&agg);\r
+       if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)))\r
+               goto end;\r
+\r
+       /* compute the size of the agregate - there are two such aggregates on the stack */\r
+       size = _slang_sizeof_aggregate (&agg);\r
+\r
+       /* jump to the actual data-comparison code */\r
+       skip_jump = file->count;\r
+       if (!(result = slang_assembly_file_push (file, slang_asm_jump)))\r
+               goto end;\r
+\r
+       /* pop off the stack the compared data and push 1 */\r
+       true_label = file->count;\r
+       if (!(result = slang_assembly_file_push_label (file, slang_asm_local_free, size * 2)))\r
+               goto end;\r
+       if (!(result = slang_assembly_file_push_literal (file, slang_asm_bool_push, 1.0f)))\r
+               goto end;\r
+       true_jump = file->count;\r
+       if (!(result = slang_assembly_file_push (file, slang_asm_jump)))\r
+               goto end;\r
+\r
+       false_label = file->count;\r
+       if (!(result = slang_assembly_file_push_label (file, slang_asm_local_free, size * 2)))\r
+               goto end;\r
+       if (!(result = slang_assembly_file_push_literal (file, slang_asm_bool_push, 0.0f)))\r
+               goto end;\r
+       false_jump = file->count;\r
+       if (!(result = slang_assembly_file_push (file, slang_asm_jump)))\r
+               goto end;\r
+\r
+       file->code[skip_jump].param[0] = file->count;\r
+\r
+       /* compare the data on stack, it will eventually jump either to true or false label */\r
+       index = 0;\r
+       if (!(result = equality_aggregate (file, &agg, &index, size, info,\r
+               equal ? false_label : true_label)))\r
+               goto end;\r
+       if (!(result = slang_assembly_file_push_label (file, slang_asm_jump,\r
+               equal ? true_label : false_label)))\r
+               goto end;\r
+\r
+       file->code[true_jump].param[0] = file->count;\r
+       file->code[false_jump].param[0] = file->count;\r
+\r
+       result = 1;\r
+end:\r
+       slang_storage_aggregate_destruct (&agg);\r
+       slang_assembly_typeinfo_destruct (&ti);\r
+       return result;\r
+}\r
+\r
+int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, int reference,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info, slang_assembly_stack_info *stk)\r
+{\r
+       unsigned int asm;\r
+\r
+       stk->swizzle_mask = 0;\r
+\r
+       asm = file->count;\r
+       if (!slang_assembly_file_push_new (file))\r
+               return 0;\r
+\r
+       switch (op->type)\r
+       {\r
+       case slang_oper_block_no_new_scope:\r
+       case slang_oper_block_new_scope:\r
+               {\r
+                       unsigned int i;\r
+                       for (i = 0; i < op->num_children; i++)\r
+                       {\r
+                               slang_assembly_stack_info stk;\r
+                               if (!_slang_assemble_operation (file, op->children + i, 0, flow, space, info, &stk))\r
+                                       return 0;\r
+                               /* TODO: pass-in stk to cleanup */\r
+                               if (!_slang_cleanup_stack (file, op->children + i, 0, space))\r
+                                       return 0;\r
+                       }\r
+               }\r
+               break;\r
+       case slang_oper_variable_decl:\r
+               {\r
+                       unsigned int i;\r
+\r
+                       for (i = 0; i < op->num_children; i++)\r
+                       {\r
+                               /* TODO: perform initialization of op->children[i] */\r
+                               /* TODO: clean-up stack */\r
+                       }\r
+               }\r
+               break;\r
+       case slang_oper_asm:\r
+               {\r
+                       unsigned int i;\r
+                       for (i = 0; i < op->num_children; i++)\r
+                       {\r
+                               slang_assembly_stack_info stk;\r
+                               if (!_slang_assemble_operation (file, op->children + i, i == 0, flow, space, info,\r
+                                       &stk))\r
+                                       return 0;\r
+                               /* TODO: inspect stk */\r
+                       }\r
+                       if (!call_asm_instruction (file, op->identifier))\r
+                               return 0;\r
+               }\r
+               break;\r
+       case slang_oper_break:\r
+               file->code[asm].type = slang_asm_jump;\r
+               file->code[asm].param[0] = flow->loop_end;\r
+               break;\r
+       case slang_oper_continue:\r
+               file->code[asm].type = slang_asm_jump;\r
+               file->code[asm].param[0] = flow->loop_start;\r
+               break;\r
+       case slang_oper_discard:\r
+               file->code[asm].type = slang_asm_discard;\r
+               if (!slang_assembly_file_push (file, slang_asm_exit))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_return:\r
+               if (info->ret_size != 0)\r
+               {\r
+                       slang_assembly_stack_info stk;\r
+                       if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, 0, info->ret_size))\r
+                               return 0;\r
+                       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+                               return 0;\r
+                       /* TODO: inspect stk */\r
+                       if (!assignment (file, op->children, space, info))\r
+                               return 0;\r
+                       if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
+                               return 0;\r
+               }\r
+               if (!slang_assembly_file_push_label (file, slang_asm_jump, flow->function_end))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_expression:\r
+               {\r
+                       slang_assembly_stack_info stk;\r
+                       if (!_slang_assemble_operation (file, op->children, reference, flow, space, info, &stk))\r
+                               return 0;\r
+                       /* TODO: inspect stk */\r
+               }\r
+               break;\r
+       case slang_oper_if:\r
+               if (!_slang_assemble_if (file, op, flow, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_while:\r
+               if (!_slang_assemble_while (file, op, flow, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_do:\r
+               if (!_slang_assemble_do (file, op, flow, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_for:\r
+               if (!_slang_assemble_for (file, op, flow, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_void:\r
+               break;\r
+       case slang_oper_literal_bool:\r
+               file->code[asm].type = slang_asm_bool_push;\r
+               file->code[asm].literal = op->literal;\r
+               break;\r
+       case slang_oper_literal_int:\r
+               file->code[asm].type = slang_asm_int_push;\r
+               file->code[asm].literal = op->literal;\r
+               break;\r
+       case slang_oper_literal_float:\r
+               file->code[asm].type = slang_asm_float_push;\r
+               file->code[asm].literal = op->literal;\r
+               break;\r
+       case slang_oper_identifier:\r
+               {\r
+                       slang_variable *var;\r
+                       unsigned int size;\r
+                       var = _slang_locate_variable (op->locals, op->identifier, 1);\r
+                       if (var == NULL)\r
+                               return 0;\r
+                       size = 0;\r
+                       if (!sizeof_variable (&var->type.specifier, var->array_size, space, &size))\r
+                               return 0;\r
+                       if (var->initializer != NULL)\r
+                       {\r
+                               assert (!"var->initializer, oper_identifier");\r
+                       }\r
+                       else\r
+                       {\r
+                               if (!reference)\r
+                               {\r
+                                       if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,\r
+                                               info->addr_tmp, 4))\r
+                                               return 0;\r
+                               }\r
+                               /* XXX: globals! */\r
+                               if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, var->address,\r
+                                       size))\r
+                                       return 0;\r
+                               if (!reference)\r
+                               {\r
+                                       if (!slang_assembly_file_push (file, slang_asm_addr_copy))\r
+                                               return 0;\r
+                                       if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
+                                               return 0;\r
+                                       if (!dereference (file, op, space, info))\r
+                                               return 0;\r
+                               }\r
+                       }\r
+               }\r
+               break;\r
+       case slang_oper_sequence:\r
+               {\r
+                       slang_assembly_stack_info stk;\r
+                       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+                               return 0;\r
+                       /* TODO: pass-in stk to cleanup */\r
+                       if (!_slang_cleanup_stack (file, op->children, 0, space))\r
+                               return 0;\r
+                       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info,\r
+                               &stk))\r
+                               return 0;\r
+                       /* TODO: inspect stk */\r
+               }\r
+               break;\r
+       case slang_oper_assign:\r
+               {\r
+                       slang_assembly_stack_info stk;\r
+                       if (!reference)\r
+                               if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp,\r
+                                       4))\r
+                                       return 0;\r
+                       if (!_slang_assemble_operation (file, op->children, 1, flow, space, info, &stk))\r
+                               return 0;\r
+                       /* TODO: inspect stk */\r
+                       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+                               return 0;\r
+                       /* TODO: inspect stk */\r
+                       if (!assignment (file, op->children, space, info))\r
+                               return 0;\r
+                       if (!reference)\r
+                       {\r
+                               if (!slang_assembly_file_push (file, slang_asm_addr_copy))\r
+                                       return 0;\r
+                               if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
+                                       return 0;\r
+                               if (!dereference (file, op->children, space, info))\r
+                                       return 0;\r
+                       }\r
+               }\r
+               break;\r
+       case slang_oper_addassign:\r
+               /* TODO: posprawdzaj czy zadzia³a dereferencja */\r
+               if (!call_function_name (file, "+=", op->children, 2, 1, space, info))\r
+                       return 0;\r
+               if (reference)\r
+               {\r
+                       /* TODO: stack is address */\r
+               }\r
+               else\r
+               {\r
+                       if (!dereference (file, op->children, space, info))\r
+                               return 0;\r
+                       /* TODO: stack is operation type */\r
+               }\r
+               break;\r
+       case slang_oper_subassign:\r
+               /* TODO: posprawdzaj czy zadzia³a dereferencja */\r
+               if (!call_function_name (file, "-=", op->children, 2, 1, space, info))\r
+                       return 0;\r
+               if (reference)\r
+               {\r
+                       /* TODO: stack is address */\r
+               }\r
+               else\r
+               {\r
+                       if (!dereference (file, op->children, space, info))\r
+                               return 0;\r
+                       /* TODO: stack is operation type */\r
+               }\r
+               break;\r
+       case slang_oper_mulassign:\r
+               /* TODO: posprawdzaj czy zadzia³a dereferencja */\r
+               if (!call_function_name (file, "*=", op->children, 2, 1, space, info))\r
+                       return 0;\r
+               if (reference)\r
+               {\r
+                       /* TODO: stack is address */\r
+               }\r
+               else\r
+               {\r
+                       if (!dereference (file, op->children, space, info))\r
+                               return 0;\r
+                       /* TODO: stack is operation type */\r
+               }\r
+               break;\r
+       /*case slang_oper_modassign:*/\r
+       /*case slang_oper_lshassign:*/\r
+       /*case slang_oper_rshassign:*/\r
+       /*case slang_oper_orassign:*/\r
+       /*case slang_oper_xorassign:*/\r
+       /*case slang_oper_andassign:*/\r
+       case slang_oper_divassign:\r
+               /* TODO: posprawdzaj czy zadzia³a dereferencja */\r
+               if (!call_function_name (file, "/=", op->children, 2, 1, space, info))\r
+                       return 0;\r
+               if (reference)\r
+               {\r
+                       /* TODO: stack is address */\r
+               }\r
+               else\r
+               {\r
+                       if (!dereference (file, op->children, space, info))\r
+                               return 0;\r
+                       /* TODO: stack is operation type */\r
+               }\r
+               break;\r
+       case slang_oper_select:\r
+               if (!_slang_assemble_select (file, op, flow, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_logicalor:\r
+               if (!_slang_assemble_logicalor (file, op, flow, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_logicaland:\r
+               if (!_slang_assemble_logicaland (file, op, flow, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_logicalxor:\r
+               if (!call_function_name (file, "^^", op->children, 2, 0, space, info))\r
+                       return 0;\r
+               break;\r
+       /*case slang_oper_bitor:*/\r
+       /*case slang_oper_bitxor:*/\r
+       /*case slang_oper_bitand:*/\r
+       case slang_oper_less:\r
+               if (!call_function_name (file, "<", op->children, 2, 0, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_greater:\r
+               if (!call_function_name (file, ">", op->children, 2, 0, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_lessequal:\r
+               if (!call_function_name (file, "<=", op->children, 2, 0, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_greaterequal:\r
+               if (!call_function_name (file, ">=", op->children, 2, 0, space, info))\r
+                       return 0;\r
+               break;\r
+       /*case slang_oper_lshift:*/\r
+       /*case slang_oper_rshift:*/\r
+       case slang_oper_add:\r
+               if (!call_function_name (file, "+", op->children, 2, 0, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_subtract:\r
+               if (!call_function_name (file, "-", op->children, 2, 0, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_multiply:\r
+               if (!call_function_name (file, "*", op->children, 2, 0, space, info))\r
+                       return 0;\r
+               break;\r
+       /*case slang_oper_modulus:*/\r
+       case slang_oper_divide:\r
+               if (!call_function_name (file, "/", op->children, 2, 0, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_equal:\r
+               {\r
+                       slang_assembly_stack_info stk;\r
+                       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+                               return 0;\r
+                       /* TODO: inspect stk */\r
+                       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+                               return 0;\r
+                       /* TODO: inspect stk */\r
+                       if (!equality (file, op->children, space, info, 1))\r
+                               return 0;\r
+               }\r
+               break;\r
+       case slang_oper_notequal:\r
+               {\r
+                       slang_assembly_stack_info stk;\r
+                       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+                               return 0;\r
+                       /* TODO: inspect stk */\r
+                       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+                               return 0;\r
+                       /* TODO: inspect stk */\r
+                       if (!equality (file, op->children, space, info, 0))\r
+                               return 0;\r
+               }\r
+               break;\r
+       case slang_oper_preincrement:\r
+               /* TODO: posprawdzaj czy zadzia³a dereferencja */\r
+               if (!call_function_name (file, "++", op->children, 1, 1, space, info))\r
+                       return 0;\r
+               if (reference)\r
+               {\r
+                       /* TODO: stack is address */\r
+               }\r
+               else\r
+               {\r
+                       /* TODO: dereference */\r
+                       /* TODO: stack is operation type */\r
+               }\r
+               break;\r
+       case slang_oper_predecrement:\r
+               /* TODO: posprawdzaj czy zadzia³a dereferencja */\r
+               if (!call_function_name (file, "--", op->children, 1, 1, space, info))\r
+                       return 0;\r
+               if (reference)\r
+               {\r
+                       /* TODO: stack is address */\r
+               }\r
+               else\r
+               {\r
+                       /* TODO: dereference */\r
+                       /* TODO: stack is operation type */\r
+               }\r
+               break;\r
+       case slang_oper_plus:\r
+               if (!call_function_name (file, "+", op->children, 1, 0, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_minus:\r
+               if (!call_function_name (file, "-", op->children, 1, 0, space, info))\r
+                       return 0;\r
+               break;\r
+       /*case slang_oper_complement:*/\r
+       case slang_oper_not:\r
+               if (!call_function_name (file, "!", op->children, 1, 0, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_subscript:\r
+               {\r
+                       slang_assembly_stack_info _stk;\r
+                       slang_assembly_typeinfo ti_arr, ti_elem;\r
+                       unsigned int arr_size = 0, elem_size = 0;\r
+                       if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,\r
+                               &_stk))\r
+                               return 0;\r
+                       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &_stk))\r
+                               return 0;\r
+                       slang_assembly_typeinfo_construct (&ti_arr);\r
+                       if (!_slang_typeof_operation (op->children, space, &ti_arr))\r
+                       {\r
+                               slang_assembly_typeinfo_destruct (&ti_arr);\r
+                               return 0;\r
+                       }\r
+                       if (!sizeof_variable (&ti_arr.spec, NULL, space, &arr_size))\r
+                       {\r
+                               slang_assembly_typeinfo_destruct (&ti_arr);\r
+                               return 0;\r
+                       }\r
+                       slang_assembly_typeinfo_construct (&ti_elem);\r
+                       if (!_slang_typeof_operation (op, space, &ti_elem))\r
+                       {\r
+                               slang_assembly_typeinfo_destruct (&ti_arr);\r
+                               slang_assembly_typeinfo_destruct (&ti_elem);\r
+                               return 0;\r
+                       }\r
+                       if (!sizeof_variable (&ti_elem.spec, NULL, space, &elem_size))\r
+                       {\r
+                               slang_assembly_typeinfo_destruct (&ti_arr);\r
+                               slang_assembly_typeinfo_destruct (&ti_elem);\r
+                               return 0;\r
+                       }\r
+                       if (!slang_assembly_file_push (file, slang_asm_int_to_addr))\r
+                       {\r
+                               slang_assembly_typeinfo_destruct (&ti_arr);\r
+                               slang_assembly_typeinfo_destruct (&ti_elem);\r
+                               return 0;\r
+                       }\r
+                       if (!slang_assembly_file_push_label (file, slang_asm_addr_push, elem_size))\r
+                       {\r
+                               slang_assembly_typeinfo_destruct (&ti_arr);\r
+                               slang_assembly_typeinfo_destruct (&ti_elem);\r
+                               return 0;\r
+                       }\r
+                       if (!slang_assembly_file_push (file, slang_asm_addr_multiply))\r
+                       {\r
+                               slang_assembly_typeinfo_destruct (&ti_arr);\r
+                               slang_assembly_typeinfo_destruct (&ti_elem);\r
+                               return 0;\r
+                       }\r
+                       if (reference)\r
+                       {\r
+                               if (!slang_assembly_file_push (file, slang_asm_addr_add))\r
+                               {\r
+                                       slang_assembly_typeinfo_destruct (&ti_arr);\r
+                                       slang_assembly_typeinfo_destruct (&ti_elem);\r
+                                       return 0;\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               unsigned int i;\r
+                               for (i = 0; i < elem_size; i += 4)\r
+                               {\r
+                                       if (!slang_assembly_file_push_label2 (file, slang_asm_float_move,\r
+                                               arr_size - elem_size + i + 4, i + 4))\r
+                                       {\r
+                                               slang_assembly_typeinfo_destruct (&ti_arr);\r
+                                               slang_assembly_typeinfo_destruct (&ti_elem);\r
+                                               return 0;\r
+                                       }\r
+                               }\r
+                               if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
+                               {\r
+                                       slang_assembly_typeinfo_destruct (&ti_arr);\r
+                                       slang_assembly_typeinfo_destruct (&ti_elem);\r
+                                       return 0;\r
+                               }\r
+                               if (!slang_assembly_file_push_label (file, slang_asm_local_free,\r
+                                       arr_size - elem_size))\r
+                               {\r
+                                       slang_assembly_typeinfo_destruct (&ti_arr);\r
+                                       slang_assembly_typeinfo_destruct (&ti_elem);\r
+                                       return 0;\r
+                               }\r
+                       }\r
+                       slang_assembly_typeinfo_destruct (&ti_arr);\r
+                       slang_assembly_typeinfo_destruct (&ti_elem);\r
+               }\r
+               break;\r
+       case slang_oper_call:\r
+               {\r
+                       slang_function *fun = _slang_locate_function (op->identifier, op->children,\r
+                               op->num_children, space);\r
+                       if (fun == NULL)\r
+                       {\r
+                               if (!_slang_assemble_constructor (file, op, flow, space, info))\r
+                                       return 0;\r
+                       }\r
+                       else\r
+                       {\r
+                               if (!call_function (file, fun, op->children, op->num_children, 0, space, info))\r
+                                       return 0;\r
+                       }\r
+               }\r
+               break;\r
+       case slang_oper_field:\r
+               {\r
+                       slang_assembly_typeinfo ti_after, ti_before;\r
+                       slang_assembly_stack_info _stk;\r
+                       slang_assembly_typeinfo_construct (&ti_after);\r
+                       if (!_slang_typeof_operation (op, space, &ti_after))\r
+                       {\r
+                               slang_assembly_typeinfo_destruct (&ti_after);\r
+                               return 0;\r
+                       }\r
+                       slang_assembly_typeinfo_construct (&ti_before);\r
+                       if (!_slang_typeof_operation (op->children, space, &ti_before))\r
+                       {\r
+                               slang_assembly_typeinfo_destruct (&ti_after);\r
+                               slang_assembly_typeinfo_destruct (&ti_before);\r
+                               return 0;\r
+                       }\r
+                       if (!reference && ti_after.is_swizzled)\r
+                       {\r
+                               if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,\r
+                                       info->swizzle_tmp, 16))\r
+                               {\r
+                                       slang_assembly_typeinfo_destruct (&ti_after);\r
+                                       slang_assembly_typeinfo_destruct (&ti_before);\r
+                                       return 0;\r
+                               }\r
+                       }\r
+                       if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,\r
+                               &_stk))\r
+                       {\r
+                               slang_assembly_typeinfo_destruct (&ti_after);\r
+                               slang_assembly_typeinfo_destruct (&ti_before);\r
+                               return 0;\r
+                       }\r
+                       /* TODO: inspect stk */\r
+                       if (ti_after.is_swizzled)\r
+                       {\r
+                               if (reference)\r
+                               {\r
+                                       if (ti_after.swz.num_components == 1)\r
+                                       {\r
+                                               if (!slang_assembly_file_push_label (file, slang_asm_addr_push,\r
+                                                       ti_after.swz.swizzle[0] * 4))\r
+                                               {\r
+                                                       slang_assembly_typeinfo_destruct (&ti_after);\r
+                                                       slang_assembly_typeinfo_destruct (&ti_before);\r
+                                                       return 0;\r
+                                               }\r
+                                               if (!slang_assembly_file_push (file, slang_asm_addr_add))\r
+                                               {\r
+                                                       slang_assembly_typeinfo_destruct (&ti_after);\r
+                                                       slang_assembly_typeinfo_destruct (&ti_before);\r
+                                                       return 0;\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               unsigned int i;\r
+                                               for (i = 0; i < ti_after.swz.num_components; i++)\r
+                                                       stk->swizzle_mask |= 1 << ti_after.swz.swizzle[i];\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       if (!_slang_assemble_constructor_from_swizzle (file, &ti_after.swz,\r
+                                               &ti_after.spec, &ti_before.spec, info))\r
+                                       {\r
+                                               slang_assembly_typeinfo_destruct (&ti_after);\r
+                                               slang_assembly_typeinfo_destruct (&ti_before);\r
+                                               return 0;\r
+                                       }\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               if (reference)\r
+                               {\r
+                                       /* TODO: struct field address */\r
+                               }\r
+                               else\r
+                               {\r
+                                       /* TODO: struct field value */\r
+                               }\r
+                       }\r
+                       slang_assembly_typeinfo_destruct (&ti_after);\r
+                       slang_assembly_typeinfo_destruct (&ti_before);\r
+               }\r
+               break;\r
+       case slang_oper_postincrement:\r
+               if (!call_function_name_dummyint (file, "++", op->children, space, info))\r
+                       return 0;\r
+               if (!dereference (file, op, space, info))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_postdecrement:\r
+               if (!call_function_name_dummyint (file, "--", op->children, space, info))\r
+                       return 0;\r
+               if (!dereference (file, op, space, info))\r
+                       return 0;\r
+               break;\r
+       default:\r
+               return 0;\r
+       }\r
+       return 1;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+void xxx_first (slang_assembly_file *file)\r
+{\r
+       slang_assembly_file_push (file, slang_asm_jump);\r
+}\r
+\r
+void xxx_prolog (slang_assembly_file *file)\r
+{\r
+       file->code[0].param[0] = file->count;\r
+\r
+       /* allocate local storage for inout/out params */\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_label (file, slang_asm_enter, 4);\r
+\r
+/*     slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);*/\r
+       slang_assembly_file_push_literal (file, slang_asm_int_push, 777.777f);\r
+/*     slang_assembly_file_push_literal (file, slang_asm_float_push, 16.16f);\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 15.15f);\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 14.14f);\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 13.13f);\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 12.12f);\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 11.11f);\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 10.10f);\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 9.9f);\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 8.8f);\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 7.7f);\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 6.6f);\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 5.5f);\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 4.4f);\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 3.3f);\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 2.2f);*/\r
+       slang_assembly_file_push_literal (file, slang_asm_float_push, 1.1f);\r
+\r
+       slang_assembly_file_push_label (file, slang_asm_call, file->count + 3);\r
+       slang_assembly_file_push_label (file, slang_asm_local_free, 4);\r
+\r
+       slang_assembly_file_push (file, slang_asm_exit);\r
+}\r
+\r
diff --git a/src/mesa/shader/slang/slang_assemble.h b/src/mesa/shader/slang/slang_assemble.h
new file mode 100644 (file)
index 0000000..21721c4
--- /dev/null
@@ -0,0 +1,145 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  6.3\r
+ *\r
+ * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+#if !defined SLANG_ASSEMBLE_H\r
+#define SLANG_ASSEMBLE_H\r
+\r
+#include "slang_compile.h"\r
+\r
+#if defined __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+typedef enum slang_assembly_type_\r
+{\r
+       /* core */\r
+       slang_asm_none,\r
+       slang_asm_float_copy,\r
+       slang_asm_float_move,\r
+       slang_asm_float_push,\r
+       slang_asm_float_deref,\r
+       slang_asm_float_add,\r
+       slang_asm_float_multiply,\r
+       slang_asm_float_divide,\r
+       slang_asm_float_negate,\r
+       slang_asm_float_less,\r
+       slang_asm_float_equal,\r
+       slang_asm_float_to_int,\r
+       slang_asm_int_copy,\r
+       slang_asm_int_move,\r
+       slang_asm_int_push,\r
+       slang_asm_int_deref,\r
+       slang_asm_int_to_float,\r
+       slang_asm_int_to_addr,\r
+       slang_asm_bool_copy,\r
+       slang_asm_bool_move,\r
+       slang_asm_bool_push,\r
+       slang_asm_bool_deref,\r
+       slang_asm_addr_copy,\r
+       slang_asm_addr_push,\r
+       slang_asm_addr_deref,\r
+       slang_asm_addr_add,\r
+       slang_asm_addr_multiply,\r
+       slang_asm_jump,\r
+       slang_asm_jump_if_zero,\r
+       slang_asm_enter,\r
+       slang_asm_leave,\r
+       slang_asm_local_alloc,\r
+       slang_asm_local_free,\r
+       slang_asm_local_addr,\r
+       slang_asm_call,\r
+       slang_asm_return,\r
+       slang_asm_discard,\r
+       slang_asm_exit,\r
+       slang_asm__last\r
+} slang_assembly_type;\r
+\r
+typedef struct slang_assembly_\r
+{\r
+       slang_assembly_type type;\r
+       GLfloat literal;\r
+       GLuint param[2];\r
+} slang_assembly;\r
+\r
+typedef struct slang_assembly_file_\r
+{\r
+       slang_assembly *code;\r
+       unsigned int count;\r
+} slang_assembly_file;\r
+\r
+void slang_assembly_file_construct (slang_assembly_file *);\r
+void slang_assembly_file_destruct (slang_assembly_file *);\r
+int slang_assembly_file_push (slang_assembly_file *, slang_assembly_type);\r
+int slang_assembly_file_push_label (slang_assembly_file *, slang_assembly_type, GLuint);\r
+int slang_assembly_file_push_label2 (slang_assembly_file *, slang_assembly_type, GLuint, GLuint);\r
+int slang_assembly_file_push_literal (slang_assembly_file *, slang_assembly_type, GLfloat);\r
+\r
+typedef struct slang_assembly_flow_control_\r
+{\r
+       unsigned int loop_start;                        /* for "continue" statement */\r
+       unsigned int loop_end;                          /* for "break" statement */\r
+       unsigned int function_end;                      /* for "return" statement */\r
+} slang_assembly_flow_control;\r
+\r
+typedef struct slang_assembly_name_space_\r
+{\r
+       struct slang_function_scope_ *funcs;\r
+       struct slang_struct_scope_ *structs;\r
+       struct slang_variable_scope_ *vars;\r
+} slang_assembly_name_space;\r
+\r
+slang_function *_slang_locate_function (const char *name, slang_operation *params,\r
+       unsigned int num_params, slang_assembly_name_space *space);\r
+\r
+int _slang_assemble_function (slang_assembly_file *, struct slang_function_ *,\r
+       slang_assembly_name_space *);\r
+\r
+typedef struct slang_assembly_stack_info_\r
+{\r
+       unsigned int swizzle_mask;\r
+} slang_assembly_stack_info;\r
+\r
+int _slang_cleanup_stack (slang_assembly_file *, slang_operation *, int ref,\r
+       slang_assembly_name_space *);\r
+\r
+typedef struct slang_assembly_local_info_\r
+{\r
+       unsigned int ret_size;\r
+       unsigned int addr_tmp;\r
+       unsigned int swizzle_tmp;\r
+} slang_assembly_local_info;\r
+\r
+int _slang_assemble_operation (slang_assembly_file *, struct slang_operation_ *, int reference,\r
+       slang_assembly_flow_control *, slang_assembly_name_space *, slang_assembly_local_info *,\r
+       slang_assembly_stack_info *);\r
+\r
+void xxx_first (slang_assembly_file *);\r
+void xxx_prolog (slang_assembly_file *);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
diff --git a/src/mesa/shader/slang/slang_assemble_conditional.c b/src/mesa/shader/slang/slang_assemble_conditional.c
new file mode 100644 (file)
index 0000000..498938b
--- /dev/null
@@ -0,0 +1,485 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  6.3\r
+ *\r
+ * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * \file slang_assemble_conditional.c\r
+ * slang condtional expressions assembler\r
+ * \author Michal Krol\r
+ */\r
+\r
+#include "imports.h"\r
+#include "slang_utility.h"\r
+#include "slang_assemble_conditional.h"\r
+#include "slang_assemble.h"\r
+\r
+/* _slang_assemble_logicaland() */\r
+\r
+int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info)\r
+{\r
+       /*\r
+               and:\r
+                       <left-expression>\r
+                       jumpz zero\r
+                       <right-expression>\r
+                       jump end\r
+               zero:\r
+                       push 0\r
+               end:\r
+       */\r
+\r
+       unsigned int zero_jump, end_jump;\r
+       slang_assembly_stack_info stk;\r
+\r
+       /* evaluate left expression */\r
+       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: inspect stk */\r
+\r
+       /* jump to pushing 0 if not true */\r
+       zero_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))\r
+               return 0;\r
+\r
+       /* evaluate right expression */\r
+       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: inspect stk */\r
+\r
+       /* jump to the end of the expression */\r
+       end_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump))\r
+               return 0;\r
+\r
+       /* push 0 on stack */\r
+       file->code[zero_jump].param[0] = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_bool_push))\r
+               return 0;\r
+\r
+       /* the end of the expression */\r
+       file->code[end_jump].param[0] = file->count;\r
+\r
+       return 1;\r
+}\r
+\r
+/* _slang_assemble_logicalor() */\r
+\r
+int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info)\r
+{\r
+       /*\r
+               or:\r
+                       <left-expression>\r
+                       jumpz right\r
+                       push 1\r
+                       jump end\r
+               right:\r
+                       <right-expression>\r
+               end:\r
+       */\r
+\r
+       unsigned int right_jump, end_jump;\r
+       slang_assembly_stack_info stk;\r
+\r
+       /* evaluate left expression */\r
+       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: inspect stk */\r
+\r
+       /* jump to evaluation of right expression if not true */\r
+       right_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))\r
+               return 0;\r
+\r
+       /* push 1 on stack */\r
+       if (!slang_assembly_file_push_literal (file, slang_asm_bool_push, 1.0f))\r
+               return 0;\r
+\r
+       /* jump to the end of the expression */\r
+       end_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump))\r
+               return 0;\r
+\r
+       /* evaluate right expression */\r
+       file->code[right_jump].param[0] = file->count;\r
+       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: inspect stk */\r
+\r
+       /* the end of the expression */\r
+       file->code[end_jump].param[0] = file->count;\r
+\r
+       return 1;\r
+}\r
+\r
+/* _slang_assemble_select() */\r
+\r
+int _slang_assemble_select (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info)\r
+{\r
+       /*\r
+               select:\r
+                       <condition-expression>\r
+                       jumpz false\r
+                       <true-expression>\r
+                       jump end\r
+               false:\r
+                       <false-expression>\r
+               end:\r
+       */\r
+\r
+       unsigned int cond_jump, end_jump;\r
+       slang_assembly_stack_info stk;\r
+\r
+       /* execute condition expression */\r
+       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: inspect stk */\r
+\r
+       /* jump to false expression if not true */\r
+       cond_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))\r
+               return 0;\r
+\r
+       /* execute true expression */\r
+       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: inspect stk */\r
+\r
+       /* jump to the end of the expression */\r
+       end_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump))\r
+               return 0;\r
+\r
+       /* resolve false point */\r
+       file->code[cond_jump].param[0] = file->count;\r
+\r
+       /* execute false expression */\r
+       if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: inspect stk */\r
+\r
+       /* resolve the end of the expression */\r
+       file->code[end_jump].param[0] = file->count;\r
+\r
+       return 1;\r
+}\r
+\r
+/* _slang_assemble_for() */\r
+\r
+int _slang_assemble_for (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info)\r
+{\r
+       /*\r
+               for:\r
+                       <init-statement>\r
+                       jump start\r
+               break:\r
+                       jump end\r
+               continue:\r
+                       <loop-increment>\r
+               start:\r
+                       <condition-statement>\r
+                       jumpz end\r
+                       <loop-body>\r
+                       jump continue\r
+               end:\r
+       */\r
+\r
+       unsigned int start_jump, end_jump, cond_jump;\r
+       unsigned int break_label, cont_label;\r
+       slang_assembly_flow_control loop_flow = *flow;\r
+       slang_assembly_stack_info stk;\r
+\r
+       /* execute initialization statement */\r
+       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: pass-in stk to cleanup */\r
+       if (!_slang_cleanup_stack (file, op->children, 0, space))\r
+               return 0;\r
+\r
+       /* skip the "go to the end of the loop" and loop-increment statements */\r
+       start_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump))\r
+               return 0;\r
+\r
+       /* go to the end of the loop - break statements are directed here */\r
+       break_label = file->count;\r
+       end_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump))\r
+               return 0;\r
+\r
+       /* resolve the beginning of the loop - continue statements are directed here */\r
+       cont_label = file->count;\r
+\r
+       /* execute loop-increment statement */\r
+       if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: pass-in stk to cleanup */\r
+       if (!_slang_cleanup_stack (file, op->children + 2, 0, space))\r
+               return 0;\r
+\r
+       /* resolve the condition point */\r
+       file->code[start_jump].param[0] = file->count;\r
+\r
+       /* execute condition statement */\r
+       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: inspect stk */\r
+\r
+       /* jump to the end of the loop if not true */\r
+       cond_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))\r
+               return 0;\r
+\r
+       /* execute loop body */\r
+       loop_flow.loop_start = cont_label;\r
+       loop_flow.loop_end = break_label;\r
+       if (!_slang_assemble_operation (file, op->children + 3, 0, &loop_flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: pass-in stk to cleanup */\r
+       if (!_slang_cleanup_stack (file, op->children + 3, 0, space))\r
+               return 0;\r
+\r
+       /* go to the beginning of the loop */\r
+       if (!slang_assembly_file_push_label (file, slang_asm_jump, cont_label))\r
+               return 0;\r
+\r
+       /* resolve the end of the loop */\r
+       file->code[end_jump].param[0] = file->count;\r
+       file->code[cond_jump].param[0] = file->count;\r
+\r
+       return 1;\r
+}\r
+\r
+/* _slang_assemble_do() */\r
+\r
+int _slang_assemble_do (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info)\r
+{\r
+       /*\r
+               do:\r
+                       jump start\r
+               break:\r
+                       jump end\r
+               continue:\r
+                       jump condition\r
+               start:\r
+                       <loop-body>\r
+               condition:\r
+                       <condition-statement>\r
+                       jumpz end\r
+                       jump start\r
+               end:\r
+       */\r
+\r
+       unsigned int skip_jump, end_jump, cont_jump, cond_jump;\r
+       unsigned int break_label, cont_label;\r
+       slang_assembly_flow_control loop_flow = *flow;\r
+       slang_assembly_stack_info stk;\r
+\r
+       /* skip the "go to the end of the loop" and "go to condition" statements */\r
+       skip_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump))\r
+               return 0;\r
+\r
+       /* go to the end of the loop - break statements are directed here */\r
+       break_label = file->count;\r
+       end_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump))\r
+               return 0;\r
+\r
+       /* go to condition - continue statements are directed here */\r
+       cont_label = file->count;\r
+       cont_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump))\r
+               return 0;\r
+\r
+       /* resolve the beginning of the loop */\r
+       file->code[skip_jump].param[0] = file->count;\r
+\r
+       /* execute loop body */\r
+       loop_flow.loop_start = cont_label;\r
+       loop_flow.loop_end = break_label;\r
+       if (!_slang_assemble_operation (file, op->children, 0, &loop_flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: pass-in stk to cleanup */\r
+       if (!_slang_cleanup_stack (file, op->children, 0, space))\r
+               return 0;\r
+\r
+       /* resolve condition point */\r
+       file->code[cont_jump].param[0] = file->count;\r
+\r
+       /* execute condition statement */\r
+       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: pass-in stk to cleanup */\r
+\r
+       /* jump to the end of the loop if not true */\r
+       cond_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))\r
+               return 0;\r
+\r
+       /* jump to the beginning of the loop */\r
+       if (!slang_assembly_file_push_label (file, slang_asm_jump, file->code[skip_jump].param[0]))\r
+               return 0;\r
+\r
+       /* resolve the end of the loop */\r
+       file->code[end_jump].param[0] = file->count;\r
+       file->code[cond_jump].param[0] = file->count;\r
+\r
+       return 1;\r
+}\r
+\r
+/* _slang_assemble_while() */\r
+\r
+int _slang_assemble_while (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info)\r
+{\r
+       /*\r
+               while:\r
+                       jump continue\r
+               break:\r
+                       jump end\r
+               continue:\r
+                       <condition-statement>\r
+                       jumpz end\r
+                       <loop-body>\r
+                       jump continue\r
+               end:\r
+       */\r
+\r
+       unsigned int skip_jump, end_jump, cond_jump;\r
+       unsigned int break_label;\r
+       slang_assembly_flow_control loop_flow = *flow;\r
+       slang_assembly_stack_info stk;\r
+\r
+       /* skip the "go to the end of the loop" statement */\r
+       skip_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump))\r
+               return 0;\r
+\r
+       /* go to the end of the loop - break statements are directed here */\r
+       break_label = file->count;\r
+       end_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump))\r
+               return 0;\r
+\r
+       /* resolve the beginning of the loop - continue statements are directed here */\r
+       file->code[skip_jump].param[0] = file->count;\r
+\r
+       /* execute condition statement */\r
+       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: pass-in stk to cleanup */\r
+\r
+       /* jump to the end of the loop if not true */\r
+       cond_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))\r
+               return 0;\r
+\r
+       /* execute loop body */\r
+       loop_flow.loop_start = file->code[skip_jump].param[0];\r
+       loop_flow.loop_end = break_label;\r
+       if (!_slang_assemble_operation (file, op->children + 1, 0, &loop_flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: pass-in stk to cleanup */\r
+       if (!_slang_cleanup_stack (file, op->children + 1, 0, space))\r
+               return 0;\r
+\r
+       /* jump to the beginning of the loop */\r
+       if (!slang_assembly_file_push_label (file, slang_asm_jump, file->code[skip_jump].param[0]))\r
+               return 0;\r
+\r
+       /* resolve the end of the loop */\r
+       file->code[end_jump].param[0] = file->count;\r
+       file->code[cond_jump].param[0] = file->count;\r
+\r
+       return 1;\r
+}\r
+\r
+/* _slang_assemble_if() */\r
+\r
+int _slang_assemble_if (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info)\r
+{\r
+       /*\r
+               if:\r
+                       <condition-statement>\r
+                       jumpz else\r
+                       <true-statement>\r
+                       jump end\r
+               else:\r
+                       <false-statement>\r
+               end:\r
+       */\r
+\r
+       unsigned int cond_jump, else_jump;\r
+       slang_assembly_stack_info stk;\r
+\r
+       /* execute condition statement */\r
+       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: pass-in stk to cleanup */\r
+\r
+       /* jump to false-statement if not true */\r
+       cond_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))\r
+               return 0;\r
+\r
+       /* execute true-statement */\r
+       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: pass-in stk to cleanup */\r
+       if (!_slang_cleanup_stack (file, op->children + 1, 0, space))\r
+               return 0;\r
+\r
+       /* skip if-false statement */\r
+       else_jump = file->count;\r
+       if (!slang_assembly_file_push (file, slang_asm_jump))\r
+               return 0;\r
+\r
+       /* resolve start of false-statement */\r
+       file->code[cond_jump].param[0] = file->count;\r
+\r
+       /* execute false-statement */\r
+       if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))\r
+               return 0;\r
+       /* TODO: pass-in stk to cleanup */\r
+       if (!_slang_cleanup_stack (file, op->children + 2, 0, space))\r
+               return 0;\r
+\r
+       /* resolve end of if-false statement */\r
+       file->code[else_jump].param[0] = file->count;\r
+\r
+       return 1;\r
+}\r
+\r
diff --git a/src/mesa/shader/slang/slang_assemble_conditional.h b/src/mesa/shader/slang/slang_assemble_conditional.h
new file mode 100644 (file)
index 0000000..9ae2c62
--- /dev/null
@@ -0,0 +1,66 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  6.3\r
+ *\r
+ * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+#if !defined SLANG_ASSEMBLE_CONDITIONAL_H\r
+#define SLANG_ASSEMBLE_CONDITIONAL_H\r
+\r
+#include "slang_assemble.h"\r
+\r
+#if defined __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info);\r
+\r
+int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info);\r
+\r
+int _slang_assemble_select (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info);\r
+\r
+int _slang_assemble_for (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info);\r
+\r
+int _slang_assemble_do (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info);\r
+\r
+int _slang_assemble_while (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info);\r
+\r
+int _slang_assemble_if (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info);\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
diff --git a/src/mesa/shader/slang/slang_assemble_constructor.c b/src/mesa/shader/slang/slang_assemble_constructor.c
new file mode 100644 (file)
index 0000000..976e2a0
--- /dev/null
@@ -0,0 +1,333 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  6.3\r
+ *\r
+ * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * \file slang_assemble_constructor.c\r
+ * slang constructor and vector swizzle assembler\r
+ * \author Michal Krol\r
+ */\r
+\r
+#include "imports.h"\r
+#include "slang_utility.h"\r
+#include "slang_assemble_constructor.h"\r
+#include "slang_assemble_typeinfo.h"\r
+#include "slang_storage.h"\r
+\r
+/* _slang_is_swizzle() */\r
+\r
+int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz)\r
+{\r
+       unsigned int i;\r
+       int xyzw = 0, rgba = 0, stpq = 0;\r
+\r
+       /* the swizzle can be at most 4-component long */\r
+       swz->num_components = slang_string_length (field);\r
+       if (swz->num_components > 4)\r
+               return 0;\r
+\r
+       for (i = 0; i < swz->num_components; i++)\r
+       {\r
+               /* mark which swizzle group is used */\r
+               switch (field[i])\r
+               {\r
+               case 'x':\r
+               case 'y':\r
+               case 'z':\r
+               case 'w':\r
+                       xyzw = 1;\r
+                       break;\r
+               case 'r':\r
+               case 'g':\r
+               case 'b':\r
+               case 'a':\r
+                       rgba = 1;\r
+                       break;\r
+               case 's':\r
+               case 't':\r
+               case 'p':\r
+               case 'q':\r
+                       stpq = 1;\r
+                       break;\r
+               default:\r
+                       return 0;\r
+               }\r
+\r
+               /* collect swizzle component */\r
+               switch (field[i])\r
+               {\r
+               case 'x':\r
+               case 'r':\r
+               case 's':\r
+                       swz->swizzle[i] = 0;\r
+                       break;\r
+               case 'y':\r
+               case 'g':\r
+               case 't':\r
+                       if (rows < 2)\r
+                               return 0;\r
+                       swz->swizzle[i] = 1;\r
+                       break;\r
+               case 'z':\r
+               case 'b':\r
+               case 'p':\r
+                       if (rows < 3)\r
+                               return 0;\r
+                       swz->swizzle[i] = 2;\r
+                       break;\r
+               case 'w':\r
+               case 'a':\r
+               case 'q':\r
+                       if (rows < 4)\r
+                               return 0;\r
+                       swz->swizzle[i] = 3;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       /* only one swizzle group can be used */\r
+       if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq))\r
+               return 0;\r
+\r
+       return 1;\r
+}\r
+\r
+/* _slang_is_swizzle_mask() */\r
+\r
+int _slang_is_swizzle_mask (const slang_swizzle *swz, unsigned int rows)\r
+{\r
+       unsigned int c, i;\r
+\r
+       if (swz->num_components > rows)\r
+               return 0;\r
+       c = swz->swizzle[0];\r
+       for (i = 1; i < swz->num_components; i++)\r
+       {\r
+               if (swz->swizzle[i] <= c)\r
+                       return 0;\r
+               c = swz->swizzle[i];\r
+       }\r
+       return 1;\r
+}\r
+\r
+/* _slang_multiply_swizzles() */\r
+\r
+void _slang_multiply_swizzles (slang_swizzle *dst, const slang_swizzle *left,\r
+       const slang_swizzle *right)\r
+{\r
+       unsigned int i;\r
+       dst->num_components = right->num_components;\r
+       for (i = 0; i < right->num_components; i++)\r
+               dst->swizzle[i] = left->swizzle[right->swizzle[i]];\r
+}\r
+\r
+/* _slang_assemble_constructor() */\r
+\r
+static int constructor_aggregate (slang_assembly_file *file, const slang_storage_aggregate *flat,\r
+       unsigned int *index, slang_operation *op, unsigned int size, slang_assembly_flow_control *flow,\r
+       slang_assembly_name_space *space, slang_assembly_local_info *info)\r
+{\r
+       slang_assembly_typeinfo ti;\r
+       int result;\r
+       slang_storage_aggregate agg, flat_agg;\r
+       slang_assembly_stack_info stk;\r
+       unsigned int i;\r
+\r
+       slang_assembly_typeinfo_construct (&ti);\r
+       if (!(result = _slang_typeof_operation (op, space, &ti)))\r
+               goto end1;\r
+\r
+       slang_storage_aggregate_construct (&agg);\r
+       if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)))\r
+               goto end2;\r
+\r
+       slang_storage_aggregate_construct (&flat_agg);\r
+       if (!(result = _slang_flatten_aggregate (&flat_agg, &agg)))\r
+               goto end;\r
+\r
+       if (!(result = _slang_assemble_operation (file, op, 0, flow, space, info, &stk)))\r
+               goto end;\r
+\r
+       for (i = 0; i < flat_agg.count; i++)\r
+       {\r
+               const slang_storage_array *arr1 = flat_agg.arrays + i;\r
+               const slang_storage_array *arr2 = flat->arrays + *index;\r
+\r
+               if (arr1->type != arr2->type)\r
+               {\r
+                       /* TODO: convert (generic) from arr1 to arr2 */\r
+               }\r
+               (*index)++;\r
+               /* TODO: watch the index, if it reaches the size, pop off the stack subsequent values */\r
+       }\r
+\r
+       result = 1;\r
+end:\r
+       slang_storage_aggregate_destruct (&flat_agg);\r
+end2:\r
+       slang_storage_aggregate_destruct (&agg);\r
+end1:\r
+       slang_assembly_typeinfo_destruct (&ti);\r
+       return result;\r
+}\r
+/* XXX: general swizzle! */\r
+int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info)\r
+{\r
+       slang_assembly_typeinfo ti;\r
+       int result;\r
+       slang_storage_aggregate agg, flat;\r
+       unsigned int size, index, i;\r
+\r
+       slang_assembly_typeinfo_construct (&ti);\r
+       if (!(result = _slang_typeof_operation (op, space, &ti)))\r
+               goto end1;\r
+\r
+       slang_storage_aggregate_construct (&agg);\r
+       if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)))\r
+               goto end2;\r
+\r
+       size = _slang_sizeof_aggregate (&agg);\r
+\r
+       slang_storage_aggregate_construct (&flat);\r
+       if (!(result = _slang_flatten_aggregate (&flat, &agg)))\r
+               goto end;\r
+\r
+       index = 0;\r
+       for (i = 0; i < op->num_children; i++)\r
+       {\r
+               if (!(result = constructor_aggregate (file, &flat, &index, op->children + i, size, flow,\r
+                       space, info)))\r
+                       goto end;\r
+               /* TODO: watch the index, if it reaches the size, raise an error */\r
+       }\r
+\r
+       result = 1;\r
+end:\r
+       slang_storage_aggregate_destruct (&flat);\r
+end2:\r
+       slang_storage_aggregate_destruct (&agg);\r
+end1:\r
+       slang_assembly_typeinfo_destruct (&ti);\r
+       return result;\r
+}\r
+\r
+/* _slang_assemble_constructor_from_swizzle() */\r
+/* XXX: wrong */\r
+int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const slang_swizzle *swz,\r
+       slang_type_specifier *spec, slang_type_specifier *master_spec, slang_assembly_local_info *info)\r
+{\r
+       unsigned int master_rows, i;\r
+       switch (master_spec->type)\r
+       {\r
+       case slang_spec_bool:\r
+       case slang_spec_int:\r
+       case slang_spec_float:\r
+               master_rows = 1;\r
+               break;\r
+       case slang_spec_bvec2:\r
+       case slang_spec_ivec2:\r
+       case slang_spec_vec2:\r
+               master_rows = 2;\r
+               break;\r
+       case slang_spec_bvec3:\r
+       case slang_spec_ivec3:\r
+       case slang_spec_vec3:\r
+               master_rows = 3;\r
+               break;\r
+       case slang_spec_bvec4:\r
+       case slang_spec_ivec4:\r
+       case slang_spec_vec4:\r
+               master_rows = 4;\r
+               break;\r
+       }\r
+       for (i = 0; i < master_rows; i++)\r
+       {\r
+               switch (master_spec->type)\r
+               {\r
+               case slang_spec_bool:\r
+               case slang_spec_bvec2:\r
+               case slang_spec_bvec3:\r
+               case slang_spec_bvec4:\r
+                       if (!slang_assembly_file_push_label2 (file, slang_asm_bool_copy, (master_rows - i) * 4,\r
+                               i * 4))\r
+                               return 0;\r
+                       break;\r
+               case slang_spec_int:\r
+               case slang_spec_ivec2:\r
+               case slang_spec_ivec3:\r
+               case slang_spec_ivec4:\r
+                       if (!slang_assembly_file_push_label2 (file, slang_asm_int_copy, (master_rows - i) * 4,\r
+                               i * 4))\r
+                               return 0;\r
+                       break;\r
+               case slang_spec_float:\r
+               case slang_spec_vec2:\r
+               case slang_spec_vec3:\r
+               case slang_spec_vec4:\r
+                       if (!slang_assembly_file_push_label2 (file, slang_asm_float_copy,\r
+                               (master_rows - i) * 4, i * 4))\r
+                               return 0;\r
+                       break;\r
+               }\r
+       }\r
+       if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
+               return 0;\r
+       for (i = swz->num_components; i > 0; i--)\r
+       {\r
+               unsigned int n = i - 1;\r
+               if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))\r
+                       return 0;\r
+               if (!slang_assembly_file_push_label (file, slang_asm_addr_push, swz->swizzle[n] * 4))\r
+                       return 0;\r
+               if (!slang_assembly_file_push (file, slang_asm_addr_add))\r
+                       return 0;\r
+               switch (master_spec->type)\r
+               {\r
+               case slang_spec_bool:\r
+               case slang_spec_bvec2:\r
+               case slang_spec_bvec3:\r
+               case slang_spec_bvec4:\r
+                       if (!slang_assembly_file_push (file, slang_asm_bool_deref))\r
+                               return 0;\r
+                       break;\r
+               case slang_spec_int:\r
+               case slang_spec_ivec2:\r
+               case slang_spec_ivec3:\r
+               case slang_spec_ivec4:\r
+                       if (!slang_assembly_file_push (file, slang_asm_int_deref))\r
+                               return 0;\r
+                       break;\r
+               case slang_spec_float:\r
+               case slang_spec_vec2:\r
+               case slang_spec_vec3:\r
+               case slang_spec_vec4:\r
+                       if (!slang_assembly_file_push (file, slang_asm_float_deref))\r
+                               return 0;\r
+                       break;\r
+               }\r
+       }\r
+       return 1;\r
+}\r
+\r
diff --git a/src/mesa/shader/slang/slang_assemble_constructor.h b/src/mesa/shader/slang/slang_assemble_constructor.h
new file mode 100644 (file)
index 0000000..f8a0fea
--- /dev/null
@@ -0,0 +1,80 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  6.3\r
+ *\r
+ * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+#if !defined SLANG_ASSEMBLE_CONSTRUCTOR_H\r
+#define SLANG_ASSEMBLE_CONSTRUCTOR_H\r
+\r
+#include "slang_assemble.h"\r
+#include "slang_compile.h"\r
+\r
+#if defined __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*\r
+       holds a complete information about vector swizzle - the <swizzle> array contains\r
+       vector component sources indices, where 0 is "x", 1 is "y", ...\r
+       example: "xwz" --> { 3, { 0, 3, 2, n/u } }\r
+*/\r
+typedef struct slang_swizzle_\r
+{\r
+       unsigned int num_components;\r
+       unsigned int swizzle[4];\r
+} slang_swizzle;\r
+\r
+/*\r
+       checks if a field selector is a general swizzle (an r-value swizzle with replicated\r
+       components or an l-value swizzle mask) for a vector\r
+       returns 1 if this is the case, <swz> is filled with swizzle information\r
+       returns 0 otherwise\r
+*/\r
+int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz);\r
+\r
+/*\r
+       checks if a general swizzle is an l-value swizzle - these swizzles do not have\r
+       duplicated fields and they are specified in order\r
+       returns 1 if this is a swizzle mask\r
+       returns 0 otherwise\r
+*/\r
+int _slang_is_swizzle_mask (const slang_swizzle *swz, unsigned int rows);\r
+\r
+/*\r
+       combines two swizzles to form single swizzle\r
+       example: "wzyx.yx" --> "zw"\r
+*/\r
+void _slang_multiply_swizzles (slang_swizzle *, const slang_swizzle *, const slang_swizzle *);\r
+\r
+int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
+       slang_assembly_local_info *info);\r
+\r
+int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const slang_swizzle *swz,\r
+       slang_type_specifier *spec, slang_type_specifier *master_spec, slang_assembly_local_info *info);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
diff --git a/src/mesa/shader/slang/slang_assemble_typeinfo.c b/src/mesa/shader/slang/slang_assemble_typeinfo.c
new file mode 100644 (file)
index 0000000..92af52a
--- /dev/null
@@ -0,0 +1,428 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  6.3\r
+ *\r
+ * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * \file slang_assemble_typeinfo.c\r
+ * slang type info\r
+ * \author Michal Krol\r
+ */\r
+\r
+#include "imports.h"\r
+#include "slang_utility.h"\r
+#include "slang_assemble_typeinfo.h"\r
+\r
+/* slang_assembly_typeinfo */\r
+\r
+void slang_assembly_typeinfo_construct (slang_assembly_typeinfo *ti)\r
+{\r
+       slang_type_specifier_construct (&ti->spec);\r
+}\r
+\r
+void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *ti)\r
+{\r
+       slang_type_specifier_destruct (&ti->spec);\r
+}\r
+\r
+/* _slang_typeof_operation() */\r
+\r
+int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *space,\r
+       slang_assembly_typeinfo *ti)\r
+{\r
+       ti->can_be_referenced = 0;\r
+       ti->is_swizzled = 0;\r
+\r
+       switch (op->type)\r
+       {\r
+       case slang_oper_block_no_new_scope:\r
+       case slang_oper_block_new_scope:\r
+       case slang_oper_variable_decl:\r
+       case slang_oper_asm:\r
+       case slang_oper_break:\r
+       case slang_oper_continue:\r
+       case slang_oper_discard:\r
+       case slang_oper_return:\r
+       case slang_oper_if:\r
+       case slang_oper_while:\r
+       case slang_oper_do:\r
+       case slang_oper_for:\r
+       case slang_oper_void:\r
+               ti->spec.type = slang_spec_void;\r
+               break;\r
+       case slang_oper_expression:\r
+       case slang_oper_assign:\r
+       case slang_oper_addassign:\r
+       case slang_oper_subassign:\r
+       case slang_oper_mulassign:\r
+       case slang_oper_divassign:\r
+       case slang_oper_preincrement:\r
+       case slang_oper_predecrement:\r
+               if (!_slang_typeof_operation (op->children, space, ti))\r
+                       return 0;\r
+               break;\r
+       case slang_oper_literal_bool:\r
+       case slang_oper_logicalor:\r
+       case slang_oper_logicalxor:\r
+       case slang_oper_logicaland:\r
+       case slang_oper_equal:\r
+       case slang_oper_notequal:\r
+       case slang_oper_less:\r
+       case slang_oper_greater:\r
+       case slang_oper_lessequal:\r
+       case slang_oper_greaterequal:\r
+       case slang_oper_not:\r
+               ti->spec.type = slang_spec_bool;\r
+               break;\r
+       case slang_oper_literal_int:\r
+               ti->spec.type = slang_spec_int;\r
+               break;\r
+       case slang_oper_literal_float:\r
+               ti->spec.type = slang_spec_float;\r
+               break;\r
+       case slang_oper_identifier:\r
+               {\r
+                       slang_variable *var;\r
+\r
+                       var = _slang_locate_variable (op->locals, op->identifier, 1);\r
+                       if (var == NULL)\r
+                               return 0;\r
+                       if (!slang_type_specifier_copy (&ti->spec, &var->type.specifier))\r
+                               return 0;\r
+                       ti->can_be_referenced = 1;\r
+               }\r
+               break;\r
+       case slang_oper_sequence:\r
+               /* TODO: check [0] and [1] if they match */\r
+               if (!_slang_typeof_operation (op->children + 1, space, ti))\r
+                       return 0;\r
+               ti->can_be_referenced = 0;\r
+               ti->is_swizzled = 0;\r
+               break;\r
+       /*case slang_oper_modassign:*/\r
+       /*case slang_oper_lshassign:*/\r
+       /*case slang_oper_rshassign:*/\r
+       /*case slang_oper_orassign:*/\r
+       /*case slang_oper_xorassign:*/\r
+       /*case slang_oper_andassign:*/\r
+       case slang_oper_select:\r
+               /* TODO: check [1] and [2] if they match */\r
+               if (!_slang_typeof_operation (op->children + 1, space, ti))\r
+                       return 0;\r
+               ti->can_be_referenced = 0;\r
+               ti->is_swizzled = 0;\r
+               break;\r
+       /*case slang_oper_bitor:*/\r
+       /*case slang_oper_bitxor:*/\r
+       /*case slang_oper_bitand:*/\r
+       /*case slang_oper_lshift:*/\r
+       /*case slang_oper_rshift:*/\r
+       case slang_oper_add:\r
+               {\r
+                       int exists;\r
+                       if (!_slang_typeof_function ("+", op->children, 2, space, &ti->spec, &exists))\r
+                               return 0;\r
+                       if (!exists)\r
+                               return 0;\r
+               }\r
+               break;\r
+       case slang_oper_subtract:\r
+               {\r
+                       int exists;\r
+                       if (!_slang_typeof_function ("-", op->children, 2, space, &ti->spec, &exists))\r
+                               return 0;\r
+                       if (!exists)\r
+                               return 0;\r
+               }\r
+               break;\r
+       case slang_oper_multiply:\r
+               {\r
+                       int exists;\r
+                       if (!_slang_typeof_function ("*", op->children, 2, space, &ti->spec, &exists))\r
+                               return 0;\r
+                       if (!exists)\r
+                               return 0;\r
+               }\r
+               break;\r
+       case slang_oper_divide:\r
+               {\r
+                       int exists;\r
+                       if (!_slang_typeof_function ("/", op->children, 2, space, &ti->spec, &exists))\r
+                               return 0;\r
+                       if (!exists)\r
+                               return 0;\r
+               }\r
+               break;\r
+       /*case slang_oper_modulus:*/\r
+       case slang_oper_plus:\r
+               {\r
+                       int exists;\r
+                       if (!_slang_typeof_function ("+", op->children, 1, space, &ti->spec, &exists))\r
+                               return 0;\r
+                       if (!exists)\r
+                               return 0;\r
+               }\r
+               break;\r
+       case slang_oper_minus:\r
+               {\r
+                       int exists;\r
+                       if (!_slang_typeof_function ("-", op->children, 1, space, &ti->spec, &exists))\r
+                               return 0;\r
+                       if (!exists)\r
+                               return 0;\r
+               }\r
+               break;\r
+       /*case slang_oper_complement:*/\r
+       case slang_oper_subscript:\r
+               {\r
+                       slang_assembly_typeinfo _ti;\r
+                       slang_assembly_typeinfo_construct (&_ti);\r
+                       if (!_slang_typeof_operation (op->children, space, &_ti))\r
+                       {\r
+                               slang_assembly_typeinfo_destruct (&_ti);\r
+                               return 0;\r
+                       }\r
+                       ti->can_be_referenced = _ti.can_be_referenced;\r
+                       switch (_ti.spec.type)\r
+                       {\r
+                       case slang_spec_bvec2:\r
+                       case slang_spec_bvec3:\r
+                       case slang_spec_bvec4:\r
+                               ti->spec.type = slang_spec_bool;\r
+                               break;\r
+                       case slang_spec_ivec2:\r
+                       case slang_spec_ivec3:\r
+                       case slang_spec_ivec4:\r
+                               ti->spec.type = slang_spec_int;\r
+                               break;\r
+                       case slang_spec_vec2:\r
+                       case slang_spec_vec3:\r
+                       case slang_spec_vec4:\r
+                               ti->spec.type = slang_spec_float;\r
+                               break;\r
+                       case slang_spec_mat2:\r
+                               ti->spec.type = slang_spec_vec2;\r
+                               break;\r
+                       case slang_spec_mat3:\r
+                               ti->spec.type = slang_spec_vec3;\r
+                               break;\r
+                       case slang_spec_mat4:\r
+                               ti->spec.type = slang_spec_vec4;\r
+                               break;\r
+                       case slang_spec_array:\r
+                               if (!slang_type_specifier_copy (&ti->spec, _ti.spec._array))\r
+                               {\r
+                                       slang_assembly_typeinfo_destruct (&_ti);\r
+                                       return 0;\r
+                               }\r
+                               break;\r
+                       default:\r
+                               slang_assembly_typeinfo_destruct (&_ti);\r
+                               return 0;\r
+                       }\r
+                       slang_assembly_typeinfo_destruct (&_ti);\r
+               }\r
+               break;\r
+       case slang_oper_call:\r
+               {\r
+                       int exists;\r
+                       if (!_slang_typeof_function (op->identifier, op->children, op->num_children, space,\r
+                               &ti->spec, &exists))\r
+                               return 0;\r
+                       if (!exists)\r
+                       {\r
+                               slang_struct *s = slang_struct_scope_find (space->structs, op->identifier, 1);\r
+                               if (s != NULL)\r
+                               {\r
+                                       ti->spec.type = slang_spec_struct;\r
+                                       ti->spec._struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));\r
+                                       if (ti->spec._struct == NULL)\r
+                                               return 0;\r
+                                       if (!slang_struct_construct_a (ti->spec._struct))\r
+                                       {\r
+                                               slang_alloc_free (ti->spec._struct);\r
+                                               ti->spec._struct = NULL;\r
+                                               return 0;\r
+                                       }\r
+                                       if (!slang_struct_copy (ti->spec._struct, s))\r
+                                               return 0;\r
+                               }\r
+                               else\r
+                               {\r
+                                       slang_type_specifier_type type = slang_type_specifier_type_from_string (\r
+                                               op->identifier);\r
+                                       if (type == slang_spec_void)\r
+                                               return 0;\r
+                                       ti->spec.type = type;\r
+                               }\r
+                       }\r
+               }\r
+               break;\r
+       case slang_oper_field:\r
+               {\r
+                       slang_assembly_typeinfo _ti;\r
+                       slang_assembly_typeinfo_construct (&_ti);\r
+                       if (!_slang_typeof_operation (op->children, space, &_ti))\r
+                       {\r
+                               slang_assembly_typeinfo_destruct (&_ti);\r
+                               return 0;\r
+                       }\r
+                       if (_ti.spec.type == slang_spec_struct)\r
+                       {\r
+                               slang_variable *field = _slang_locate_variable (_ti.spec._struct->fields,\r
+                                       op->identifier, 0);\r
+                               if (field == NULL)\r
+                               {\r
+                                       slang_assembly_typeinfo_destruct (&_ti);\r
+                                       return 0;\r
+                               }\r
+                               if (!slang_type_specifier_copy (&ti->spec, &field->type.specifier))\r
+                               {\r
+                                       slang_assembly_typeinfo_destruct (&_ti);\r
+                                       return 0;\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               unsigned int rows;\r
+                               switch (_ti.spec.type)\r
+                               {\r
+                               case slang_spec_vec2:\r
+                               case slang_spec_ivec2:\r
+                               case slang_spec_bvec2:\r
+                                       rows = 2;\r
+                                       break;\r
+                               case slang_spec_vec3:\r
+                               case slang_spec_ivec3:\r
+                               case slang_spec_bvec3:\r
+                                       rows = 3;\r
+                                       break;\r
+                               case slang_spec_vec4:\r
+                               case slang_spec_ivec4:\r
+                               case slang_spec_bvec4:\r
+                                       rows = 4;\r
+                                       break;\r
+                               default:\r
+                                       slang_assembly_typeinfo_destruct (&_ti);\r
+                                       return 0;\r
+                               }\r
+                               if (!_slang_is_swizzle (op->identifier, rows, &ti->swz))\r
+                                       return 0;\r
+                               ti->is_swizzled = 1;\r
+                               ti->can_be_referenced = _ti.can_be_referenced && _slang_is_swizzle_mask (&ti->swz,\r
+                                       rows);\r
+                               if (_ti.is_swizzled)\r
+                               {\r
+                                       slang_swizzle swz;\r
+                                       _slang_multiply_swizzles (&swz, &_ti.swz, &ti->swz);\r
+                                       ti->swz = swz;\r
+                               }\r
+                               switch (_ti.spec.type)\r
+                               {\r
+                               case slang_spec_vec2:\r
+                               case slang_spec_vec3:\r
+                               case slang_spec_vec4:\r
+                                       switch (ti->swz.num_components)\r
+                                       {\r
+                                       case 1:\r
+                                               ti->spec.type = slang_spec_float;\r
+                                               break;\r
+                                       case 2:\r
+                                               ti->spec.type = slang_spec_vec2;\r
+                                               break;\r
+                                       case 3:\r
+                                               ti->spec.type = slang_spec_vec3;\r
+                                               break;\r
+                                       case 4:\r
+                                               ti->spec.type = slang_spec_vec4;\r
+                                               break;\r
+                                       }\r
+                                       break;\r
+                               case slang_spec_ivec2:\r
+                               case slang_spec_ivec3:\r
+                               case slang_spec_ivec4:\r
+                                       switch (ti->swz.num_components)\r
+                                       {\r
+                                       case 1:\r
+                                               ti->spec.type = slang_spec_int;\r
+                                               break;\r
+                                       case 2:\r
+                                               ti->spec.type = slang_spec_ivec2;\r
+                                               break;\r
+                                       case 3:\r
+                                               ti->spec.type = slang_spec_ivec3;\r
+                                               break;\r
+                                       case 4:\r
+                                               ti->spec.type = slang_spec_ivec4;\r
+                                               break;\r
+                                       }\r
+                                       break;\r
+                               case slang_spec_bvec2:\r
+                               case slang_spec_bvec3:\r
+                               case slang_spec_bvec4:\r
+                                       switch (ti->swz.num_components)\r
+                                       {\r
+                                       case 1:\r
+                                               ti->spec.type = slang_spec_bool;\r
+                                               break;\r
+                                       case 2:\r
+                                               ti->spec.type = slang_spec_bvec2;\r
+                                               break;\r
+                                       case 3:\r
+                                               ti->spec.type = slang_spec_bvec3;\r
+                                               break;\r
+                                       case 4:\r
+                                               ti->spec.type = slang_spec_bvec4;\r
+                                               break;\r
+                                       }\r
+                                       break;\r
+                               }\r
+                       }\r
+                       slang_assembly_typeinfo_destruct (&_ti);\r
+                       return 1;\r
+               }\r
+               break;\r
+       case slang_oper_postincrement:\r
+       case slang_oper_postdecrement:\r
+               if (!_slang_typeof_operation (op->children, space, ti))\r
+                       return 0;\r
+               ti->can_be_referenced = 0;\r
+               ti->is_swizzled = 0;\r
+               break;\r
+       default:\r
+               return 0;\r
+       }\r
+       return 1;\r
+}\r
+\r
+/* _slang_typeof_function() */\r
+\r
+int _slang_typeof_function (const char *name, slang_operation *params, unsigned int num_params,\r
+       slang_assembly_name_space *space, slang_type_specifier *spec, int *exists)\r
+{\r
+       slang_function *fun = _slang_locate_function (name, params, num_params, space);\r
+       *exists = fun != NULL;\r
+       if (fun == NULL)\r
+               return 1;\r
+       return slang_type_specifier_copy (spec, &fun->header.type.specifier);\r
+}\r
+\r
diff --git a/src/mesa/shader/slang/slang_assemble_typeinfo.h b/src/mesa/shader/slang/slang_assemble_typeinfo.h
new file mode 100644 (file)
index 0000000..1c18394
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  6.3\r
+ *\r
+ * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+#if !defined SLANG_ASSEMBLE_TYPEINFO_H\r
+#define SLANG_ASSEMBLE_TYPEINFO_H\r
+\r
+#include "slang_assemble_constructor.h"\r
+#include "slang_compile.h"\r
+\r
+#if defined __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+typedef struct slang_assembly_typeinfo_\r
+{\r
+       int can_be_referenced;\r
+       int is_swizzled;\r
+       slang_swizzle swz;\r
+       slang_type_specifier spec;\r
+} slang_assembly_typeinfo;\r
+\r
+void slang_assembly_typeinfo_construct (slang_assembly_typeinfo *);\r
+void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *);\r
+\r
+/*\r
+       retrieves type information about an operation\r
+       returns 1 on success\r
+       returns 0 otherwise\r
+*/\r
+int _slang_typeof_operation (slang_operation *, slang_assembly_name_space *,\r
+       slang_assembly_typeinfo *);\r
+\r
+/*\r
+       retrieves type of a function prototype, if one exists\r
+       returns 1 on success, even if the function was not found\r
+       returns 0 otherwise\r
+*/\r
+int _slang_typeof_function (const char *name, slang_operation *params, unsigned int num_params,\r
+       slang_assembly_name_space *space, slang_type_specifier *spec, int *exists);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
index 06dc7df..6835ade 100644 (file)
@@ -33,6 +33,9 @@
 #include "slang_utility.h"
 #include "slang_compile.h"
 #include "slang_preprocess.h"
+#include "slang_storage.h"
+#include "slang_assemble.h"
+#include "slang_execute.h"
 
 /*
        This is a straightforward implementation of the slang front-end compiler.
 
 static void slang_variable_construct (slang_variable *);
 static int slang_variable_copy (slang_variable *, const slang_variable *);
-static void slang_struct_construct (slang_struct *);
 static void slang_struct_destruct (slang_struct *);
-static int slang_struct_copy (slang_struct *, const slang_struct *);
 static int slang_struct_equal (const slang_struct *, const slang_struct *);
 static void slang_variable_destruct (slang_variable *);
 
+/* slang_type_specifier_type */
+
+/* these must match with slang_type_specifier_type enum */
+static const char *type_specifier_type_names[] = {
+       "void",
+       "bool",
+       "bvec2",
+       "bvec3",
+       "bvec4",
+       "int",
+       "ivec2",
+       "ivec3",
+       "ivec4",
+       "float",
+       "vec2",
+       "vec3",
+       "vec4",
+       "mat2",
+       "mat3",
+       "mat4",
+       "sampler1D",
+       "sampler2D",
+       "sampler3D",
+       "samplerCube",
+       "sampler1DShadow",
+       "sampler2DShadow",
+       NULL
+};
+
+slang_type_specifier_type slang_type_specifier_type_from_string (const char *name)
+{
+       const char **p = type_specifier_type_names;
+       while (*p != NULL)
+       {
+               if (slang_string_compare (*p, name) == 0)
+                       return (slang_type_specifier_type) (p - type_specifier_type_names);
+               p++;
+       }
+       return slang_spec_void;
+}
+
 /* slang_type_specifier */
 
-static void slang_type_specifier_construct (slang_type_specifier *spec)
+void slang_type_specifier_construct (slang_type_specifier *spec)
 {
        spec->type = slang_spec_void;
        spec->_struct = NULL;
        spec->_array = NULL;
 }
 
-static void slang_type_specifier_destruct (slang_type_specifier *spec)
+void slang_type_specifier_destruct (slang_type_specifier *spec)
 {
        if (spec->_struct != NULL)
        {
@@ -72,7 +114,7 @@ static void slang_type_specifier_destruct (slang_type_specifier *spec)
        }
 }
 
-static int slang_type_specifier_copy (slang_type_specifier *x, const slang_type_specifier *y)
+int slang_type_specifier_copy (slang_type_specifier *x, const slang_type_specifier *y)
 {
        slang_type_specifier_destruct (x);
        slang_type_specifier_construct (x);
@@ -80,19 +122,28 @@ static int slang_type_specifier_copy (slang_type_specifier *x, const slang_type_
        if (x->type == slang_spec_struct)
        {
                x->_struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
-               slang_struct_construct (x->_struct);
+               if (x->_struct == NULL)
+                       return 0;
+               if (!slang_struct_construct_a (x->_struct))
+               {
+                       slang_alloc_free (x->_struct);
+                       x->_struct = NULL;
+                       return 0;
+               }
                return slang_struct_copy (x->_struct, y->_struct);
        }
        if (x->type == slang_spec_array)
        {
                x->_array = (slang_type_specifier *) slang_alloc_malloc (sizeof (slang_type_specifier));
+               if (x->_array == NULL)
+                       return 0;
                slang_type_specifier_construct (x->_array);
                return slang_type_specifier_copy (x->_array, y->_array);
        }
        return 1;
 }
 
-static int slang_type_specifier_equal (const slang_type_specifier *x, const slang_type_specifier *y)
+int slang_type_specifier_equal (const slang_type_specifier *x, const slang_type_specifier *y)
 {
        if (x->type != y->type)
                return 0;
@@ -162,8 +213,8 @@ static int slang_variable_scope_copy (slang_variable_scope *x, const slang_varia
 }
 
 /* slang_operation */
-/* XXX mem! */
-static void slang_operation_construct (slang_operation *oper)
+
+int slang_operation_construct_a (slang_operation *oper)
 {
        oper->type = slang_oper_none;
        oper->children = NULL;
@@ -171,10 +222,13 @@ static void slang_operation_construct (slang_operation *oper)
        oper->literal = (float) 0;
        oper->identifier = NULL;
        oper->locals = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
+       if (oper->locals == NULL)
+               return 0;
        slang_variable_scope_construct (oper->locals);
+       return 1;
 }
 
-static void slang_operation_destruct (slang_operation *oper)
+void slang_operation_destruct (slang_operation *oper)
 {
        unsigned int i;
        for (i = 0; i < oper->num_children; i++)
@@ -188,17 +242,32 @@ static void slang_operation_destruct (slang_operation *oper)
 static int slang_operation_copy (slang_operation *x, const slang_operation *y)
 {
        unsigned int i;
-       slang_operation_destruct (x);
-       slang_operation_construct (x);
+       for (i = 0; i < x->num_children; i++)
+               slang_operation_destruct (x->children + i);
+       slang_alloc_free (x->children);
+       x->num_children = 0;
+       slang_alloc_free (x->identifier);
+       x->identifier = NULL;
+       slang_variable_scope_destruct (x->locals);
+       slang_variable_scope_construct (x->locals);
+
        x->type = y->type;
        x->children = (slang_operation *) slang_alloc_malloc (y->num_children * sizeof (
                slang_operation));
        if (x->children == NULL)
                return 0;
+       for (i = 0; i < y->num_children; i++)
+               if (!slang_operation_construct_a (x->children + i))
+               {
+                       unsigned int j;
+                       for (j = 0; j < i; j++)
+                               slang_operation_destruct (x->children + j);
+                       slang_alloc_free (x->children);
+                       x->children = NULL;
+                       return 0;
+               }
        x->num_children = y->num_children;
        for (i = 0; i < x->num_children; i++)
-               slang_operation_construct (x->children + i);
-       for (i = 0; i < x->num_children; i++)
                if (!slang_operation_copy (x->children + i, y->children + i))
                        return 0;
        x->literal = y->literal;
@@ -221,6 +290,7 @@ static void slang_variable_construct (slang_variable *var)
        var->name = NULL;
        var->array_size = NULL;
        var->initializer = NULL;
+       var->address = ~0;
 }
 
 static void slang_variable_destruct (slang_variable *var)
@@ -256,7 +326,12 @@ static int slang_variable_copy (slang_variable *x, const slang_variable *y)
                x->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
                if (x->array_size == NULL)
                        return 0;
-               slang_operation_construct (x->array_size);
+               if (!slang_operation_construct_a (x->array_size))
+               {
+                       slang_alloc_free (x->array_size);
+                       x->array_size = NULL;
+                       return 0;
+               }
                if (!slang_operation_copy (x->array_size, y->array_size))
                        return 0;
        }
@@ -265,13 +340,29 @@ static int slang_variable_copy (slang_variable *x, const slang_variable *y)
                x->initializer = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
                if (x->initializer == NULL)
                        return 0;
-               slang_operation_construct (x->initializer);
+               if (!slang_operation_construct_a (x->initializer))
+               {
+                       slang_alloc_free (x->initializer);
+                       x->initializer = NULL;
+                       return 0;
+               }
                if (!slang_operation_copy (x->initializer, y->initializer))
                        return 0;
        }
        return 1;
 }
 
+slang_variable *_slang_locate_variable (slang_variable_scope *scope, const char *name, int all)
+{
+       unsigned int i;
+       for (i = 0; i < scope->num_variables; i++)
+               if (slang_string_compare (name, scope->variables[i].name) == 0)
+                       return scope->variables + i;
+       if (all && scope->outer_scope != NULL)
+               return _slang_locate_variable (scope->outer_scope, name, 1);
+       return NULL;
+}
+
 /* slang_struct_scope */
 
 static void slang_struct_scope_construct (slang_struct_scope *scope)
@@ -299,7 +390,17 @@ static int slang_struct_scope_copy (slang_struct_scope *x, const slang_struct_sc
                return 0;
        x->num_structs = y->num_structs;
        for (i = 0; i < x->num_structs; i++)
-               slang_struct_construct (x->structs + i);
+       {
+               unsigned int j;
+               if (!slang_struct_construct_a (x->structs + i))
+               {
+                       for (j = 0; j < i; j++)
+                               slang_struct_destruct (x->structs + j);
+                       slang_alloc_free (x->structs);
+                       x->structs = NULL;
+                       return 0;
+               }
+       }
        for (i = 0; i < x->num_structs; i++)
                if (!slang_struct_copy (x->structs + i, y->structs + i))
                        return 0;
@@ -307,8 +408,7 @@ static int slang_struct_scope_copy (slang_struct_scope *x, const slang_struct_sc
        return 1;
 }
 
-static slang_struct *slang_struct_scope_find (slang_struct_scope *stru, const char *name,
-       int all_scopes)
+slang_struct *slang_struct_scope_find (slang_struct_scope *stru, const char *name, int all_scopes)
 {
        unsigned int i;
        for (i = 0; i < stru->num_structs; i++)
@@ -320,14 +420,23 @@ static slang_struct *slang_struct_scope_find (slang_struct_scope *stru, const ch
 }
 
 /* slang_struct */
-/* XXX mem! */
-static void slang_struct_construct (slang_struct *stru)
+
+int slang_struct_construct_a (slang_struct *stru)
 {
        stru->name = NULL;
        stru->fields = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
+       if (stru->fields == NULL)
+               return 0;
        slang_variable_scope_construct (stru->fields);
        stru->structs = (slang_struct_scope *) slang_alloc_malloc (sizeof (slang_struct_scope));
+       if (stru->structs == NULL)
+       {
+               slang_variable_scope_destruct (stru->fields);
+               slang_alloc_free (stru->fields);
+               return 0;
+       }
        slang_struct_scope_construct (stru->structs);
+       return 1;
 }
 
 static void slang_struct_destruct (slang_struct *stru)
@@ -339,10 +448,14 @@ static void slang_struct_destruct (slang_struct *stru)
        slang_alloc_free (stru->structs);
 }
 
-static int slang_struct_copy (slang_struct *x, const slang_struct *y)
+int slang_struct_copy (slang_struct *x, const slang_struct *y)
 {
-       slang_struct_destruct (x);
-       slang_struct_construct (x);
+       slang_alloc_free (x->name);
+       x->name = NULL;
+       slang_variable_scope_destruct (x->fields);
+       slang_variable_scope_construct (x->fields);
+       slang_struct_scope_destruct (x->structs);
+       slang_struct_scope_construct (x->structs);
        if (y->name != NULL)
        {
                x->name = slang_string_duplicate (y->name);
@@ -386,6 +499,7 @@ static void slang_function_construct (slang_function *func)
        func->parameters = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
        slang_variable_scope_construct (func->parameters);
        func->body = NULL;
+       func->address = ~0;
 }
 
 static void slang_function_destruct (slang_function *func)
@@ -561,7 +675,7 @@ typedef struct slang_parse_ctx_
        int parsing_builtin;
 } slang_parse_ctx;
 
-/* --- */
+/* _slang_compile() */
 
 static int parse_identifier (slang_parse_ctx *C, char **id)
 {
@@ -826,7 +940,14 @@ static int parse_type_specifier (slang_parse_ctx *C, slang_type_specifier *spec,
                                slang_info_log_memory (C->L);
                                return 0;
                        }
-                       slang_struct_construct (spec->_struct);
+                       if (!slang_struct_construct_a (spec->_struct))
+                       {
+                               slang_alloc_free (spec->_struct);
+                               spec->_struct = NULL;
+                               slang_alloc_free (name);
+                               slang_info_log_memory (C->L);
+                               return 0;
+                       }
                        spec->_struct->name = name;
                        spec->_struct->structs->outer_scope = structs;
                }
@@ -878,7 +999,14 @@ static int parse_type_specifier (slang_parse_ctx *C, slang_type_specifier *spec,
                                                slang_info_log_memory (C->L);
                                                return 0;
                                        }
-                                       slang_operation_construct (var->array_size);
+                                       if (!slang_operation_construct_a (var->array_size))
+                                       {
+                                               slang_alloc_free (var->array_size);
+                                               var->array_size = NULL;
+                                               slang_type_specifier_destruct (&sp);
+                                               slang_info_log_memory (C->L);
+                                               return 0;
+                                       }
                                        if (!parse_expression (C, var->array_size, scope, structs, funcs))
                                        {
                                                slang_type_specifier_destruct (&sp);
@@ -904,8 +1032,9 @@ static int parse_type_specifier (slang_parse_ctx *C, slang_type_specifier *spec,
                                return 0;
                        }
                        s = structs->structs + structs->num_structs;
+                       if (!slang_struct_construct_a (s))
+                               return 0;
                        structs->num_structs++;
-                       slang_struct_construct (s);
                        if (!slang_struct_copy (s, spec->_struct))
                                return 0;
                }
@@ -931,7 +1060,12 @@ static int parse_type_specifier (slang_parse_ctx *C, slang_type_specifier *spec,
                                slang_info_log_memory (C->L);
                                return 0;
                        }
-                       slang_struct_construct (spec->_struct);
+                       if (!slang_struct_construct_a (spec->_struct))
+                       {
+                               slang_alloc_free (spec->_struct);
+                               spec->_struct = NULL;
+                               return 0;
+                       }
                        if (!slang_struct_copy (spec->_struct, stru))
                                return 0;
                }
@@ -1025,7 +1159,11 @@ static int parse_child_operation (slang_parse_ctx *C, slang_operation *oper, int
                slang_info_log_memory (C->L);
                return 0;
        }
-       slang_operation_construct (oper->children + oper->num_children);
+       if (!slang_operation_construct_a (oper->children + oper->num_children))
+       {
+               slang_info_log_memory (C->L);
+               return 0;
+       }
        oper->num_children++;
        if (statement)
                return parse_statement (C, oper->children + oper->num_children - 1, scope, structs, funcs);
@@ -1073,7 +1211,16 @@ static int parse_statement (slang_parse_ctx *C, slang_operation *oper, slang_var
                                        return 0;
                                }
                                for (i = 0; i < num_vars; i++)
-                                       slang_operation_construct (oper->children + i);
+                                       if (!slang_operation_construct_a (oper->children + i))
+                                       {
+                                               unsigned int j;
+                                               for (j = 0; j < i; j++)
+                                                       slang_operation_destruct (oper->children + j);
+                                               slang_alloc_free (oper->children);
+                                               oper->children = NULL;
+                                               slang_info_log_memory (C->L);
+                                               return 0;
+                                       }
                                oper->num_children = num_vars;
                                for (i = first_var; i < scope->num_variables; i++)
                                {
@@ -1230,39 +1377,10 @@ static int handle_unary_expression (slang_parse_ctx *C, slang_operation *op,
        return 1;
 }
 
-/* these must match with slang_type_specifier_type enum */
-static const char *builtin_constructor_names[] = {
-       "void",
-       "bool",
-       "bvec2",
-       "bvec3",
-       "bvec4",
-       "int",
-       "ivec2",
-       "ivec3",
-       "ivec4",
-       "float",
-       "vec2",
-       "vec3",
-       "vec4",
-       "mat2",
-       "mat3",
-       "mat4",
-       "sampler1D",
-       "sampler2D",
-       "sampler3D",
-       "samplerCube",
-       "sampler1DShadow",
-       "sampler2DShadow",
-       NULL
-};
-
 static int is_constructor_name (const char *name, slang_struct_scope *structs)
 {
-       const char **p = &builtin_constructor_names[1];
-       while (*p != NULL)
-               if (slang_string_compare (*p++, name) == 0)
-                       return 1;
+       if (slang_type_specifier_type_from_string (name) != slang_spec_void)
+               return 1;
        return slang_struct_scope_find (structs, name, 1) != NULL;
 }
 
@@ -1285,8 +1403,12 @@ static int parse_expression (slang_parse_ctx *C, slang_operation *oper, slang_va
                        return 0;
                }
                op = ops + num_ops;
+               if (!slang_operation_construct_a (op))
+               {
+                       slang_info_log_memory (C->L);
+                       return 0;
+               }
                num_ops++;
-               slang_operation_construct (op);
                op->locals->outer_scope = scope;
                switch (op_code)
                {
@@ -1513,6 +1635,7 @@ static int parse_expression (slang_parse_ctx *C, slang_operation *oper, slang_va
 static int parse_parameter_declaration (slang_parse_ctx *C, slang_variable *param,
        slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs)
 {
+       slang_storage_aggregate agg;
        if (!parse_type_qualifier (C, &param->type.qualifier))
                return 0;
        switch (*C->I++)
@@ -1557,10 +1680,24 @@ static int parse_parameter_declaration (slang_parse_ctx *C, slang_variable *para
                        slang_info_log_memory (C->L);
                        return 0;
                }
-               slang_operation_construct (param->array_size);
+               if (!slang_operation_construct_a (param->array_size))
+               {
+                       slang_alloc_free (param->array_size);
+                       param->array_size = NULL;
+                       slang_info_log_memory (C->L);
+                       return 0;
+               }
                if (!parse_expression (C, param->array_size, scope, structs, funcs))
                        return 0;
        }
+       slang_storage_aggregate_construct (&agg);
+       if (!_slang_aggregate_variable (&agg, &param->type.specifier, param->array_size, funcs,
+               structs))
+       {
+               slang_storage_aggregate_destruct (&agg);
+               return 0;
+       }
+       slang_storage_aggregate_destruct (&agg);
        return 1;
 }
 
@@ -1680,7 +1817,7 @@ static int parse_function_prototype (slang_parse_ctx *C, slang_function *func,
                if (func->header.type.specifier.type == slang_spec_struct)
                        return 0;
                func->header.name = slang_string_duplicate (
-                       builtin_constructor_names[func->header.type.specifier.type]);
+                       type_specifier_type_names[func->header.type.specifier.type]);
                if (func->header.name == NULL)
                {
                        slang_info_log_memory (C->L);
@@ -1728,7 +1865,13 @@ static int parse_function_definition (slang_parse_ctx *C, slang_function *func,
                slang_info_log_memory (C->L);
                return 0;
        }
-       slang_operation_construct (func->body);
+       if (!slang_operation_construct_a (func->body))
+       {
+               slang_alloc_free (func->body);
+               func->body = NULL;
+               slang_info_log_memory (C->L);
+               return 0;
+       }
        if (!parse_statement (C, func->body, func->parameters, structs, funcs))
                return 0;
        return 1;
@@ -1781,7 +1924,13 @@ static int parse_init_declarator (slang_parse_ctx *C, const slang_fully_specifie
                        slang_info_log_memory (C->L);
                        return 0;
                }
-               slang_operation_construct (var->initializer);
+               if (!slang_operation_construct_a (var->initializer))
+               {
+                       slang_alloc_free (var->initializer);
+                       var->initializer = NULL;
+                       slang_info_log_memory (C->L);
+                       return 0;
+               }
                if (!parse_expression (C, var->initializer, vars, structs, funcs))
                        return 0;
                break;
@@ -1816,13 +1965,32 @@ static int parse_init_declarator (slang_parse_ctx *C, const slang_fully_specifie
                        slang_info_log_memory (C->L);
                        return 0;
                }
-               slang_operation_construct (var->array_size);
+               if (!slang_operation_construct_a (var->array_size))
+               {
+                       slang_alloc_free (var->array_size);
+                       var->array_size = NULL;
+                       slang_info_log_memory (C->L);
+                       return 0;
+               }
                if (!parse_expression (C, var->array_size, vars, structs, funcs))
                        return 0;
                break;
        default:
                return 0;
        }
+       if (!(var->type.specifier.type == slang_spec_array && var->array_size == NULL))
+       {
+               slang_storage_aggregate agg;
+
+               slang_storage_aggregate_construct (&agg);
+               if (!_slang_aggregate_variable (&agg, &var->type.specifier, var->array_size, funcs,
+                       structs))
+               {
+                       slang_storage_aggregate_destruct (&agg);
+                       return 0;
+               }
+               slang_storage_aggregate_destruct (&agg);
+       }
        return 1;
 }
 
@@ -1874,7 +2042,8 @@ static int parse_function (slang_parse_ctx *C, int definition, slang_struct_scop
                }
        }
 
-       /* find a function with a prototype matching the parsed one */
+       /* 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 (funcs, &parsed_func, 0);
        if (found_func == NULL)
        {
@@ -1919,6 +2088,37 @@ static int parse_function (slang_parse_ctx *C, int definition, slang_struct_scop
                /* return the found function */
                *parsed_func_ret = found_func;
        }
+
+       /* assemble the parsed function */
+       if (definition)
+       {
+static int x = 0;
+const int y = 61;      /* core 437 */
+static
+               slang_assembly_file file;
+               slang_assembly_name_space space;
+x++;
+if (x == 1)
+               slang_assembly_file_construct (&file);
+               space.funcs = funcs;
+               space.structs = structs;
+               space.vars = scope;
+if (x == 1)
+       xxx_first (&file);
+if (x == y)
+       xxx_prolog (&file);
+               if (!_slang_assemble_function (&file, *parsed_func_ret, &space))
+               {
+                       slang_assembly_file_destruct (&file);
+                       return 0;
+               }
+if (x == y)
+{
+_slang_execute (&file);
+slang_assembly_file_destruct (&file);
+exit (0);
+}
+       }
        return 1;
 }
 
index 25a0ef8..a9a075c 100644 (file)
@@ -68,14 +68,21 @@ typedef enum slang_type_specifier_type_
        slang_spec_sampler2DShadow,
        slang_spec_struct,
        slang_spec_array
-} slang_type_specifier_type;
+} slang_type_specifier_type;\r
+\r
+slang_type_specifier_type slang_type_specifier_type_from_string (const char *);
 
 typedef struct slang_type_specifier_
 {
        slang_type_specifier_type type;
        struct slang_struct_ *_struct;          /* spec_struct */
        struct slang_type_specifier_ *_array;   /* spec_array */
-} slang_type_specifier;
+} slang_type_specifier;\r
+\r
+void slang_type_specifier_construct (slang_type_specifier *);\r
+void slang_type_specifier_destruct (slang_type_specifier *);\r
+int slang_type_specifier_copy (slang_type_specifier *, const slang_type_specifier *);\r
+int slang_type_specifier_equal (const slang_type_specifier *, const slang_type_specifier *);
 
 typedef struct slang_fully_specified_type_
 {
@@ -164,29 +171,40 @@ typedef struct slang_operation_
        float literal;          /* bool, literal_int, literal_float */
        char *identifier;       /* asm, identifier, call, field */
        slang_variable_scope *locals;
-} slang_operation;
+} slang_operation;\r
+\r
+int slang_operation_construct_a (slang_operation *);\r
+void slang_operation_destruct (slang_operation *);
 
 typedef struct slang_variable_
 {
        slang_fully_specified_type type;
        char *name;
        slang_operation *array_size;    /* spec_array */
-       slang_operation *initializer;
-} slang_variable;
+       slang_operation *initializer;\r
+       unsigned int address;
+} slang_variable;\r
+\r
+slang_variable *_slang_locate_variable (slang_variable_scope *scope, const char *name, int all);
 
 typedef struct slang_struct_scope_
 {
        struct slang_struct_ *structs;
        unsigned int num_structs;
        struct slang_struct_scope_ *outer_scope;
-} slang_struct_scope;
+} slang_struct_scope;\r
+\r
+struct slang_struct_ *slang_struct_scope_find (slang_struct_scope *, const char *, int);
 
 typedef struct slang_struct_
 {
        char *name;
        slang_variable_scope *fields;
        slang_struct_scope *structs;
-} slang_struct;
+} slang_struct;\r
+\r
+int slang_struct_construct_a (slang_struct *);\r
+int slang_struct_copy (slang_struct *, const slang_struct *);
 
 typedef enum slang_function_kind_
 {
@@ -201,7 +219,8 @@ typedef struct slang_function_
        slang_variable header;
        slang_variable_scope *parameters;
        unsigned int param_count;
-       slang_operation *body;
+       slang_operation *body;\r
+       unsigned int address;
 } slang_function;
 
 typedef struct slang_function_scope_
diff --git a/src/mesa/shader/slang/slang_execute.c b/src/mesa/shader/slang/slang_execute.c
new file mode 100644 (file)
index 0000000..1bcc418
--- /dev/null
@@ -0,0 +1,347 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  6.3\r
+ *\r
+ * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * \file slang_execute.c\r
+ * intermediate code interpreter\r
+ * \author Michal Krol\r
+ */\r
+\r
+#include "imports.h"\r
+#include "slang_utility.h"\r
+#include "slang_assemble.h"\r
+#include "slang_storage.h"\r
+#include "slang_execute.h"\r
+\r
+static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i)\r
+{\r
+       fprintf (f, "%.5u:\t", i);\r
+       \r
+       switch (a->type)\r
+       {\r
+       case slang_asm_none:\r
+               fprintf (f, "none");\r
+               break;\r
+       case slang_asm_float_copy:\r
+               fprintf (f, "float_copy\t%d, %d", a->param[0], a->param[1]);\r
+               break;\r
+       case slang_asm_float_move:\r
+               fprintf (f, "float_move\t%d, %d", a->param[0], a->param[1]);\r
+               break;\r
+       case slang_asm_float_push:\r
+               fprintf (f, "float_push\t%f", a->literal);\r
+               break;\r
+       case slang_asm_float_deref:\r
+               fprintf (f, "float_deref");\r
+               break;\r
+       case slang_asm_float_add:\r
+               fprintf (f, "float_add");\r
+               break;\r
+       case slang_asm_float_multiply:\r
+               fprintf (f, "float_multiply");\r
+               break;\r
+       case slang_asm_float_divide:\r
+               fprintf (f, "float_divide");\r
+               break;\r
+       case slang_asm_float_negate:\r
+               fprintf (f, "float_negate");\r
+               break;\r
+       case slang_asm_float_less:\r
+               fprintf (f, "float_less");\r
+               break;\r
+       case slang_asm_float_equal:\r
+               fprintf (f, "float_equal\t%d, %d", a->param[0], a->param[1]);\r
+               break;\r
+       case slang_asm_float_to_int:\r
+               fprintf (f, "float_to_int");\r
+               break;\r
+       case slang_asm_int_copy:\r
+               fprintf (f, "int_copy\t%d, %d", a->param[0], a->param[1]);\r
+               break;\r
+       case slang_asm_int_move:\r
+               fprintf (f, "int_move\t%d, %d", a->param[0], a->param[1]);\r
+               break;\r
+       case slang_asm_int_push:\r
+               fprintf (f, "int_push\t%d", (GLint) a->literal);\r
+               break;\r
+       case slang_asm_int_deref:\r
+               fprintf (f, "int_deref");\r
+               break;\r
+       case slang_asm_int_to_float:\r
+               fprintf (f, "int_to_float");\r
+               break;\r
+       case slang_asm_int_to_addr:\r
+               fprintf (f, "int_to_addr");\r
+               break;\r
+       case slang_asm_bool_copy:\r
+               fprintf (f, "bool_copy\t%d, %d", a->param[0], a->param[1]);\r
+               break;\r
+       case slang_asm_bool_move:\r
+               fprintf (f, "bool_move\t%d, %d", a->param[0], a->param[1]);\r
+               break;\r
+       case slang_asm_bool_push:\r
+               fprintf (f, "bool_push\t%d", a->literal != 0.0f);\r
+               break;\r
+       case slang_asm_bool_deref:\r
+               fprintf (f, "bool_deref");\r
+               break;\r
+       case slang_asm_addr_copy:\r
+               fprintf (f, "addr_copy");\r
+               break;\r
+       case slang_asm_addr_push:\r
+               fprintf (f, "addr_push\t%u", a->param[0]);\r
+               break;\r
+       case slang_asm_addr_deref:\r
+               fprintf (f, "addr_deref");\r
+               break;\r
+       case slang_asm_addr_add:\r
+               fprintf (f, "address_add");\r
+               break;\r
+       case slang_asm_addr_multiply:\r
+               fprintf (f, "address_multiply");\r
+               break;\r
+       case slang_asm_jump:\r
+               fprintf (f, "jump\t%u", a->param[0]);\r
+               break;\r
+       case slang_asm_jump_if_zero:\r
+               fprintf (f, "jump_if_zero\t%u", a->param[0]);\r
+               break;\r
+       case slang_asm_enter:\r
+               fprintf (f, "enter\t%u", a->param[0]);\r
+               break;\r
+       case slang_asm_leave:\r
+               fprintf (f, "leave");\r
+               break;\r
+       case slang_asm_local_alloc:\r
+               fprintf (f, "local_alloc\t%u", a->param[0]);\r
+               break;\r
+       case slang_asm_local_free:\r
+               fprintf (f, "local_free\t%u", a->param[0]);\r
+               break;\r
+       case slang_asm_local_addr:\r
+               fprintf (f, "local_addr\t%u, %u", a->param[0], a->param[1]);\r
+               break;\r
+       case slang_asm_call:\r
+               fprintf (f, "call\t%u", a->param[0]);\r
+               break;\r
+       case slang_asm_return:\r
+               fprintf (f, "return");\r
+               break;\r
+       case slang_asm_discard:\r
+               fprintf (f, "discard");\r
+               break;\r
+       case slang_asm_exit:\r
+               fprintf (f, "exit");\r
+               break;\r
+       }\r
+\r
+       fprintf (f, "\n");\r
+}\r
+\r
+static void dump (const slang_assembly_file *file)\r
+{\r
+       unsigned int i;\r
+       static unsigned int counter = 0;\r
+       FILE *f;\r
+       char filename[256];\r
+\r
+       counter++;\r
+       sprintf (filename, "~mesa-slang-assembly-dump-(%u).txt", counter);\r
+       f = fopen (filename, "w");\r
+       if (f == NULL)\r
+               return;\r
+\r
+       for (i = 0; i < file->count; i++)\r
+               dump_instruction (f, file->code + i, i);\r
+\r
+       fclose (f);\r
+}\r
+\r
+int _slang_execute (const slang_assembly_file *file)\r
+{\r
+       slang_machine mach;\r
+FILE *f;\r
+\r
+       mach.ip = 0;\r
+       mach.sp = SLANG_MACHINE_STACK_SIZE;\r
+       mach.bp = 0;\r
+       mach.kill = 0;\r
+       mach.exit = 0;\r
+\r
+       /* assume 32-bit machine */\r
+       static_assert(sizeof (GLfloat) == 4);\r
+       static_assert(sizeof (GLfloat *) == 4);\r
+       static_assert(sizeof (GLuint) == 4);\r
+       static_assert(sizeof (GLuint *) == 4);\r
+\r
+dump (file);\r
+\r
+f = fopen ("~mesa-slang-assembly-execution.txt", "w");\r
+\r
+       while (!mach.exit)\r
+       {\r
+               slang_assembly *a = file->code + mach.ip;\r
+if (f != NULL)\r
+{\r
+unsigned int i;\r
+dump_instruction (f, a, mach.ip);\r
+fprintf (f, "\t\tsp=%u bp=%u\n", mach.sp, mach.bp);\r
+for (i = mach.sp; i < SLANG_MACHINE_STACK_SIZE; i++)\r
+fprintf (f, "\t%.5u\t%6f\t%u\n", i, mach.stack._float[i], mach.stack._addr[i]);\r
+fflush (f);\r
+}\r
+               mach.ip++;\r
+\r
+               switch (a->type)\r
+               {\r
+               case slang_asm_none:\r
+                       break;\r
+               case slang_asm_float_copy:\r
+               case slang_asm_int_copy:\r
+               case slang_asm_bool_copy:\r
+                       *(mach.stack._floatp[mach.sp + a->param[0] / 4] + a->param[1] / 4) =\r
+                               mach.stack._float[mach.sp];\r
+                       mach.sp++;\r
+                       break;\r
+               case slang_asm_float_move:\r
+               case slang_asm_int_move:\r
+               case slang_asm_bool_move:\r
+                       mach.stack._float[mach.sp + a->param[0] / 4] =\r
+                               mach.stack._float[mach.sp + (mach.stack._addr[mach.sp] + a->param[1]) / 4];\r
+                       break;\r
+               case slang_asm_float_push:\r
+               case slang_asm_int_push:\r
+               case slang_asm_bool_push:\r
+                       mach.sp--;\r
+                       mach.stack._float[mach.sp] = a->literal;\r
+                       break;\r
+               case slang_asm_float_deref:\r
+               case slang_asm_int_deref:\r
+               case slang_asm_bool_deref:\r
+                       mach.stack._float[mach.sp] = *mach.stack._floatp[mach.sp];\r
+                       break;\r
+               case slang_asm_float_add:\r
+                       mach.stack._float[mach.sp + 1] += mach.stack._float[mach.sp];\r
+                       mach.sp++;\r
+                       break;\r
+               case slang_asm_float_multiply:\r
+                       mach.stack._float[mach.sp + 1] *= mach.stack._float[mach.sp];\r
+                       mach.sp++;\r
+                       break;\r
+               case slang_asm_float_divide:\r
+                       mach.stack._float[mach.sp + 1] /= mach.stack._float[mach.sp];\r
+                       mach.sp++;\r
+                       break;\r
+               case slang_asm_float_negate:\r
+                       mach.stack._float[mach.sp] = -mach.stack._float[mach.sp];\r
+                       break;\r
+               case slang_asm_float_less:\r
+                       mach.stack._float[mach.sp + 1] =\r
+                               mach.stack._float[mach.sp + 1] < mach.stack._float[mach.sp] ? 1.0f : 0.0f;\r
+                       mach.sp++;\r
+                       break;\r
+               case slang_asm_float_equal:\r
+                       mach.sp--;\r
+                       mach.stack._float[mach.sp] = mach.stack._float[mach.sp + 1 + a->param[0] / 4] ==\r
+                               mach.stack._float[mach.sp + 1 + a->param[1] / 4] ? 1.0f : 0.0f;\r
+                       break;\r
+               case slang_asm_float_to_int:\r
+                       mach.stack._float[mach.sp] = (GLfloat) (GLint) mach.stack._float[mach.sp];\r
+                       break;\r
+               case slang_asm_int_to_float:\r
+                       break;\r
+               case slang_asm_int_to_addr:\r
+                       mach.stack._addr[mach.sp] = (GLuint) (GLint) mach.stack._float[mach.sp];\r
+                       break;\r
+               case slang_asm_addr_copy:\r
+                       *mach.stack._addrp[mach.sp + 1] = mach.stack._addr[mach.sp];\r
+                       mach.sp++;\r
+                       break;\r
+               case slang_asm_addr_push:\r
+                       mach.sp--;\r
+                       mach.stack._addr[mach.sp] = a->param[0];\r
+                       break;\r
+               case slang_asm_addr_deref:\r
+                       mach.stack._addr[mach.sp] = *mach.stack._addrp[mach.sp];\r
+                       break;\r
+               case slang_asm_addr_add:\r
+                       mach.stack._addr[mach.sp + 1] += mach.stack._addr[mach.sp];\r
+                       mach.sp++;\r
+                       break;\r
+               case slang_asm_addr_multiply:\r
+                       mach.stack._addr[mach.sp + 1] *= mach.stack._addr[mach.sp];\r
+                       mach.sp++;\r
+                       break;\r
+               case slang_asm_jump:\r
+                       mach.ip = a->param[0];\r
+                       break;\r
+               case slang_asm_jump_if_zero:\r
+                       if (mach.stack._float[mach.sp] == 0.0f)\r
+                               mach.ip = a->param[0];\r
+                       mach.sp++;\r
+                       break;\r
+               case slang_asm_enter:\r
+                       mach.sp--;\r
+                       mach.stack._addr[mach.sp] = mach.bp;\r
+                       mach.bp = mach.sp + a->param[0] / 4 + 1;\r
+                       break;\r
+               case slang_asm_leave:\r
+                       mach.bp = mach.stack._addr[mach.sp];\r
+                       mach.sp++;\r
+                       break;\r
+               case slang_asm_local_alloc:\r
+                       mach.sp -= a->param[0] / 4;\r
+                       break;\r
+               case slang_asm_local_free:\r
+                       mach.sp += a->param[0] / 4;\r
+                       break;\r
+               case slang_asm_local_addr:\r
+                       mach.sp--;\r
+                       mach.stack._addr[mach.sp] = (GLuint) mach.stack._addr + mach.bp * 4 -\r
+                               (a->param[0] + a->param[1]);\r
+                       break;\r
+               case slang_asm_call:\r
+                       mach.sp--;\r
+                       mach.stack._addr[mach.sp] = mach.ip;\r
+                       mach.ip = a->param[0];\r
+                       break;\r
+               case slang_asm_return:\r
+                       mach.ip = mach.stack._addr[mach.sp];\r
+                       mach.sp++;\r
+                       break;\r
+               case slang_asm_discard:\r
+                       mach.kill = 1;\r
+                       break;\r
+               case slang_asm_exit:\r
+                       mach.exit = 1;\r
+                       break;\r
+               }\r
+       }\r
+\r
+if (f != NULL)\r
+fclose (f);\r
+\r
+       return 0;\r
+}\r
+\r
diff --git a/src/mesa/shader/slang/slang_execute.h b/src/mesa/shader/slang/slang_execute.h
new file mode 100644 (file)
index 0000000..119fd51
--- /dev/null
@@ -0,0 +1,57 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  6.3\r
+ *\r
+ * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+#if !defined SLANG_EXECUTE_H\r
+#define SLANG_EXECUTE_H\r
+\r
+#if defined __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define SLANG_MACHINE_STACK_SIZE 64\r
+\r
+typedef struct slang_machine_\r
+{\r
+       GLuint ip;                                      /* instruction pointer, for flow control */\r
+       GLuint sp;                                      /* stack pointer, for stack access */\r
+       GLuint bp;                                      /* base pointer, for local variable access */\r
+       GLuint kill;                            /* discard the fragment */\r
+       GLuint exit;                            /* terminate the shader */\r
+       union stack_\r
+       {\r
+               GLfloat _float[SLANG_MACHINE_STACK_SIZE];\r
+               GLfloat *_floatp[SLANG_MACHINE_STACK_SIZE];\r
+               GLuint _addr[SLANG_MACHINE_STACK_SIZE];\r
+               GLuint *_addrp[SLANG_MACHINE_STACK_SIZE];\r
+       } stack;\r
+} slang_machine;\r
+\r
+int _slang_execute (const slang_assembly_file *);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
diff --git a/src/mesa/shader/slang/slang_storage.c b/src/mesa/shader/slang/slang_storage.c
new file mode 100644 (file)
index 0000000..84af8d5
--- /dev/null
@@ -0,0 +1,255 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  6.3\r
+ *\r
+ * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * \file slang_storage.c\r
+ * slang variable storage\r
+ * \author Michal Krol\r
+ */\r
+\r
+#include "imports.h"\r
+#include "slang_utility.h"\r
+#include "slang_storage.h"\r
+#include "slang_assemble.h"\r
+\r
+/* slang_storage_array */\r
+\r
+void slang_storage_array_construct (slang_storage_array *arr)\r
+{\r
+       arr->type = slang_stor_aggregate;\r
+       arr->aggregate = NULL;\r
+       arr->length = 0;\r
+}\r
+\r
+void slang_storage_array_destruct (slang_storage_array *arr)\r
+{\r
+       if (arr->aggregate != NULL)\r
+       {\r
+               slang_storage_aggregate_destruct (arr->aggregate);\r
+               slang_alloc_free (arr->aggregate);\r
+       }\r
+}\r
+\r
+/* slang_storage_aggregate */\r
+\r
+void slang_storage_aggregate_construct (slang_storage_aggregate *agg)\r
+{\r
+       agg->arrays = NULL;\r
+       agg->count = 0;\r
+}\r
+\r
+void slang_storage_aggregate_destruct (slang_storage_aggregate *agg)\r
+{\r
+       unsigned int i;\r
+       for (i = 0; i < agg->count; i++)\r
+               slang_storage_array_destruct (agg->arrays + i);\r
+       slang_alloc_free (agg->arrays);\r
+}\r
+\r
+static slang_storage_array *slang_storage_aggregate_push_new (slang_storage_aggregate *agg)\r
+{\r
+       slang_storage_array *arr = NULL;\r
+       agg->arrays = (slang_storage_array *) slang_alloc_realloc (agg->arrays, agg->count * sizeof (\r
+               slang_storage_array), (agg->count + 1) * sizeof (slang_storage_array));\r
+       if (agg->arrays != NULL)\r
+       {\r
+               arr = agg->arrays + agg->count;\r
+               slang_storage_array_construct (arr);\r
+               agg->count++;\r
+       }\r
+       return arr;\r
+}\r
+\r
+/* _slang_aggregate_variable() */\r
+\r
+static int aggregate_vector (slang_storage_aggregate *agg, slang_storage_type basic_type,\r
+       unsigned int row_count)\r
+{\r
+       slang_storage_array *arr = slang_storage_aggregate_push_new (agg);\r
+       if (arr == NULL)\r
+               return 0;\r
+       arr->type = basic_type;\r
+       arr->length = row_count;\r
+       return 1;\r
+}\r
+\r
+static int aggregate_matrix (slang_storage_aggregate *agg, slang_storage_type basic_type,\r
+       unsigned int order)\r
+{\r
+       slang_storage_array *arr = slang_storage_aggregate_push_new (agg);\r
+       if (arr == NULL)\r
+               return 0;\r
+       arr->type = slang_stor_aggregate;\r
+       arr->length = order;\r
+       arr->aggregate = (slang_storage_aggregate *) slang_alloc_malloc (sizeof (\r
+               slang_storage_aggregate));\r
+       if (arr->aggregate == NULL)\r
+               return 0;\r
+       slang_storage_aggregate_construct (arr->aggregate);\r
+       if (!aggregate_vector (arr->aggregate, basic_type, order))\r
+               return 0;\r
+       return 1;\r
+}\r
+\r
+static int aggregate_variables (slang_storage_aggregate *agg, const slang_variable_scope *vars,\r
+       slang_function_scope *funcs, slang_struct_scope *structs)\r
+{\r
+       unsigned int i;\r
+       for (i = 0; i < vars->num_variables; i++)\r
+               if (!_slang_aggregate_variable (agg, &vars->variables[i].type.specifier,\r
+                       vars->variables[i].array_size, funcs, structs))\r
+                       return 0;\r
+       return 1;\r
+}\r
+\r
+int _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_specifier *spec,\r
+       slang_operation *array_size, slang_function_scope *funcs, slang_struct_scope *structs)\r
+{\r
+       switch (spec->type)\r
+       {\r
+       case slang_spec_bool:\r
+               return aggregate_vector (agg, slang_stor_bool, 1);\r
+       case slang_spec_bvec2:\r
+               return aggregate_vector (agg, slang_stor_bool, 2);\r
+       case slang_spec_bvec3:\r
+               return aggregate_vector (agg, slang_stor_bool, 3);\r
+       case slang_spec_bvec4:\r
+               return aggregate_vector (agg, slang_stor_bool, 4);\r
+       case slang_spec_int:\r
+               return aggregate_vector (agg, slang_stor_int, 1);\r
+       case slang_spec_ivec2:\r
+               return aggregate_vector (agg, slang_stor_int, 2);\r
+       case slang_spec_ivec3:\r
+               return aggregate_vector (agg, slang_stor_int, 3);\r
+       case slang_spec_ivec4:\r
+               return aggregate_vector (agg, slang_stor_int, 4);\r
+       case slang_spec_float:\r
+               return aggregate_vector (agg, slang_stor_float, 1);\r
+       case slang_spec_vec2:\r
+               return aggregate_vector (agg, slang_stor_float, 2);\r
+       case slang_spec_vec3:\r
+               return aggregate_vector (agg, slang_stor_float, 3);\r
+       case slang_spec_vec4:\r
+               return aggregate_vector (agg, slang_stor_float, 4);\r
+       case slang_spec_mat2:\r
+               return aggregate_matrix (agg, slang_stor_float, 2);\r
+       case slang_spec_mat3:\r
+               return aggregate_matrix (agg, slang_stor_float, 3);\r
+       case slang_spec_mat4:\r
+               return aggregate_matrix (agg, slang_stor_float, 4);\r
+       case slang_spec_sampler1D:\r
+       case slang_spec_sampler2D:\r
+       case slang_spec_sampler3D:\r
+       case slang_spec_samplerCube:\r
+       case slang_spec_sampler1DShadow:\r
+       case slang_spec_sampler2DShadow:\r
+               return aggregate_vector (agg, slang_stor_int, 1);\r
+       case slang_spec_struct:\r
+               return aggregate_variables (agg, spec->_struct->fields, funcs, structs);\r
+       case slang_spec_array:\r
+               {\r
+                       slang_storage_array *arr;\r
+                       slang_assembly_file file;\r
+                       slang_assembly_flow_control flow;\r
+                       slang_assembly_name_space space;\r
+                       slang_assembly_local_info info;\r
+                       slang_assembly_stack_info stk;\r
+\r
+                       arr = slang_storage_aggregate_push_new (agg);\r
+                       if (arr == NULL)\r
+                               return 0;\r
+                       arr->type = slang_stor_aggregate;\r
+                       arr->aggregate = (slang_storage_aggregate *) slang_alloc_malloc (sizeof (\r
+                               slang_storage_aggregate));\r
+                       if (arr->aggregate == NULL)\r
+                               return 0;\r
+                       slang_storage_aggregate_construct (arr->aggregate);\r
+                       if (!_slang_aggregate_variable (arr->aggregate, spec->_array, NULL, funcs, structs))\r
+                               return 0;\r
+                       slang_assembly_file_construct (&file);\r
+                       space.funcs = funcs;\r
+                       space.structs = structs;\r
+                       /* XXX: vars! */\r
+                       space.vars = NULL;\r
+                       if (!_slang_assemble_operation (&file, array_size, 0, &flow, &space, &info, &stk))\r
+                       {\r
+                               slang_assembly_file_destruct (&file);\r
+                               return 0;\r
+                       }\r
+                       /* TODO: evaluate array size */\r
+                       slang_assembly_file_destruct (&file);\r
+                       arr->length = 256;\r
+               }\r
+               return 1;\r
+       default:\r
+               return 0;\r
+       }\r
+}\r
+\r
+/* _slang_sizeof_aggregate() */\r
+\r
+unsigned int _slang_sizeof_aggregate (const slang_storage_aggregate *agg)\r
+{\r
+       unsigned int i, size = 0;\r
+       for (i = 0; i < agg->count; i++)\r
+       {\r
+               unsigned int element_size;\r
+               if (agg->arrays[i].type == slang_stor_aggregate)\r
+                       element_size = _slang_sizeof_aggregate (agg->arrays[i].aggregate);\r
+               else\r
+                       element_size = sizeof (GLfloat);\r
+               size += element_size * agg->arrays[i].length;\r
+       }\r
+       return size;\r
+}\r
+\r
+/* _slang_flatten_aggregate () */\r
+\r
+int _slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage_aggregate *agg)\r
+{\r
+       unsigned int i;\r
+       for (i = 0; i < agg->count; i++)\r
+       {\r
+               unsigned int j;\r
+               for (j = 0; j < agg->arrays[i].length; j++)\r
+               {\r
+                       if (agg->arrays[i].type == slang_stor_aggregate)\r
+                       {\r
+                               if (!_slang_flatten_aggregate (flat, agg->arrays[i].aggregate))\r
+                                       return 0;\r
+                       }\r
+                       else\r
+                       {\r
+                               slang_storage_array *arr;\r
+                               arr = slang_storage_aggregate_push_new (flat);\r
+                               if (arr == NULL)\r
+                                       return 0;\r
+                               arr->type = agg->arrays[i].type;\r
+                               arr->length = 1;\r
+                       }\r
+               }\r
+       }\r
+       return 1;\r
+}\r
+\r
diff --git a/src/mesa/shader/slang/slang_storage.h b/src/mesa/shader/slang/slang_storage.h
new file mode 100644 (file)
index 0000000..c1b123f
--- /dev/null
@@ -0,0 +1,109 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  6.3\r
+ *\r
+ * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+#if !defined SLANG_STORAGE_H\r
+#define SLANG_STORAGE_H\r
+\r
+#include "slang_compile.h"\r
+\r
+#if defined __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*\r
+       Program variable data storage is kept completely transparent to the front-end compiler. It is\r
+       up to the back-end how the data is actually allocated. The slang_storage_type enum\r
+       provides the basic information about how the memory is interpreted. This abstract piece\r
+       of memory is called a data slot. A data slot of a particular type has a fixed size.\r
+\r
+       For now, only the three basic types are supported, that is bool, int and float. Other built-in\r
+       types like vector or matrix can easily be decomposed into a series of basic types.\r
+*/\r
+typedef enum slang_storage_type_\r
+{\r
+       slang_stor_aggregate,\r
+       slang_stor_bool,\r
+       slang_stor_int,\r
+       slang_stor_float\r
+} slang_storage_type;\r
+\r
+/*\r
+       The slang_storage_array structure groups data slots of the same type into an array. This\r
+       array has a fixed length. Arrays are required to have a size equal to the sum of sizes of its\r
+       elements. They are also required to support indirect addressing. That is, if B references\r
+       first data slot in the array, S is the size of the data slot and I is the integral index that\r
+       is not known at compile time, B+I*S references I-th data slot.\r
+\r
+       This structure is also used to break down built-in data types that are not supported directly.\r
+       Vectors, like vec3, are constructed from arrays of their basic types. Matrices are formed of\r
+       an array of column vectors, which are in turn processed as other vectors.\r
+*/\r
+typedef struct slang_storage_array_\r
+{\r
+       slang_storage_type type;\r
+       struct slang_storage_aggregate_ *aggregate;     /* slang_stor_aggregate */\r
+       unsigned int length;\r
+} slang_storage_array;\r
+\r
+void slang_storage_array_construct (slang_storage_array *);\r
+void slang_storage_array_destruct (slang_storage_array *);\r
+\r
+/*\r
+       The slang_storage_aggregate structure relaxes the indirect addressing requirement for\r
+       slang_storage_array structure. Aggregates are always accessed statically - its member\r
+       addresses are well-known at compile time. For example, user-defined types are implemented as\r
+       aggregates. Aggregates can collect data of a different type.\r
+*/\r
+typedef struct slang_storage_aggregate_\r
+{\r
+       slang_storage_array *arrays;\r
+       unsigned int count;\r
+} slang_storage_aggregate;\r
+\r
+void slang_storage_aggregate_construct (slang_storage_aggregate *);\r
+void slang_storage_aggregate_destruct (slang_storage_aggregate *);\r
+\r
+int _slang_aggregate_variable (slang_storage_aggregate *, struct slang_type_specifier_ *,\r
+       struct slang_operation_ *, struct slang_function_scope_ *, slang_struct_scope *);\r
+\r
+/*\r
+       returns total size (in machine units) of the given aggregate\r
+       returns 0 on error\r
+*/\r
+unsigned int _slang_sizeof_aggregate (const slang_storage_aggregate *);\r
+\r
+/*\r
+       converts structured aggregate to a flat one, with arrays of generic type being\r
+       one-element long\r
+       returns 1 on success\r
+       returns 0 otherwise\r
+*/\r
+int _slang_flatten_aggregate (slang_storage_aggregate *, const slang_storage_aggregate *);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
index c316559..ab0ae48 100644 (file)
@@ -187,8 +187,14 @@ SLANG_CPP_SOURCES = \
        shader/slang/OSDependent/Linux/ossource.cpp
        
 SLANG_SOURCES =        \
+       shader/slang/slang_assemble.c   \
+       shader/slang/slang_assemble_conditional.c       \
+       shader/slang/slang_assemble_constructor.c       \
+       shader/slang/slang_assemble_typeinfo.c  \
        shader/slang/slang_compile.c    \
+       shader/slang/slang_execute.c    \
        shader/slang/slang_preprocess.c \
+       shader/slang/slang_storage.c    \
        shader/slang/slang_utility.c
 
 ASM_C_SOURCES =        \