--- /dev/null
+/*\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, ¶m_size))\r
+ return 0;\r
+ info.ret_size = param_size;\r
+ if (!sizeof_variables (fun->parameters, 0, fun->param_count, space, ¶m_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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
#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)
{
}
}
-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);
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;
}
/* 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;
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++)
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;
var->name = NULL;
var->array_size = NULL;
var->initializer = NULL;
+ var->address = ~0;
}
static void slang_variable_destruct (slang_variable *var)
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;
}
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)
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;
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++)
}
/* 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)
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);
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)
int parsing_builtin;
} slang_parse_ctx;
-/* --- */
+/* _slang_compile() */
static int parse_identifier (slang_parse_ctx *C, char **id)
{
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;
}
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);
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;
}
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;
}
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);
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++)
{
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;
}
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)
{
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, ¶m->type.qualifier))
return 0;
switch (*C->I++)
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, ¶m->type.specifier, param->array_size, funcs,
+ structs))
+ {
+ slang_storage_aggregate_destruct (&agg);
+ return 0;
+ }
+ slang_storage_aggregate_destruct (&agg);
return 1;
}
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);
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;
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;
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;
}
}
}
- /* 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)
{
/* 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;
}
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_
{
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_
{
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_
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
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 = \