More GLSL code.
[mesa.git] / src / mesa / shader / slang / slang_assemble_assignment.c
index 551f5d9b110dc4681f102fabefc249e7309187d7..186c4886f7030e7ed5d27ecfe261113239f4fcc3 100644 (file)
@@ -1,8 +1,8 @@
 /*\r
  * Mesa 3-D graphics library\r
- * Version:  6.3\r
+ * Version:  6.5\r
  *\r
- * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ * Copyright (C) 2005-2006  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
  */\r
 \r
 #include "imports.h"\r
+#include "slang_utility.h"\r
 #include "slang_assemble_assignment.h"\r
 #include "slang_assemble_typeinfo.h"\r
 #include "slang_storage.h"\r
-#include "slang_utility.h"\r
+#include "slang_execute.h"\r
 \r
 /*\r
      _slang_assemble_assignment()\r
-\r
      copies values on the stack (<component 0> to <component N-1>) to a memory\r
-       location pointed by <addr of variable>;\r
-\r
      in:\r
              +------------------+\r
              | addr of variable |\r
              +------------------+\r
              | component N-1    |\r
              | ...              |\r
              | component 0      |\r
              +------------------+\r
-\r
      out:\r
              +------------------+\r
              | addr of variable |\r
              +------------------+\r
-*/\r
-/* TODO: add support for swizzle mask */\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
* _slang_assemble_assignment()\r
+ *\r
* Copies values on the stack (<component 0> to <component N-1>) to a memory\r
+ * location pointed by <addr of variable>.\r
+ *\r
* in:\r
*      +------------------+\r
*      | addr of variable |\r
*      +------------------+\r
*      | component N-1    |\r
*      | ...              |\r
*      | component 0      |\r
*      +------------------+\r
+ *\r
* out:\r
*      +------------------+\r
*      | addr of variable |\r
*      +------------------+\r
+ */\r
+\r
+static GLboolean assign_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg,\r
+       GLuint *index, GLuint size)\r
 {\r
-       unsigned int i;\r
+       GLuint 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
+               const slang_storage_array *arr = &agg->arrays[i];\r
+               GLuint 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
+                               if (!assign_aggregate (A, arr->aggregate, index, size))\r
+                                       return GL_FALSE;\r
                        }\r
                        else\r
                        {\r
+                               GLuint dst_addr_loc, dst_offset;\r
                                slang_assembly_type ty;\r
 \r
+                               /* calculate the distance from top of the stack to the destination address */\r
+                               dst_addr_loc = size - *index;\r
+\r
+                               /* calculate the offset within destination variable to write */\r
+                               if (A->swz.num_components != 0)\r
+                               {\r
+                                       /* swizzle the index to get the actual offset */\r
+                                       dst_offset = A->swz.swizzle[*index / 4] * 4;\r
+                               }\r
+                               else\r
+                               {\r
+                                       /* no swizzling - write sequentially */\r
+                                       dst_offset = *index;\r
+                               }\r
+\r
                                switch (arr->type)\r
                                {\r
                                case slang_stor_bool:\r
@@ -90,98 +107,91 @@ static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggr
                                default:\r
                                        break;\r
                                }\r
-                               if (!slang_assembly_file_push_label2 (file, ty, size - *index, *index))\r
-                                       return 0;\r
+                               if (!slang_assembly_file_push_label2 (A->file, ty, dst_addr_loc, dst_offset))\r
+                                       return GL_FALSE;\r
+\r
                                *index += 4;\r
                        }\r
                }\r
        }\r
-       return 1;\r
+\r
+       return GL_TRUE;\r
 }\r
 \r
-int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,\r
-       slang_assembly_name_space *space, slang_assembly_local_info *info)\r
+GLboolean _slang_assemble_assignment (slang_assemble_ctx *A, slang_operation *op)\r
 {\r
        slang_assembly_typeinfo ti;\r
-       int result;\r
+       GLboolean result = GL_FALSE;\r
        slang_storage_aggregate agg;\r
-       unsigned int index, size;\r
+       GLuint 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
+       if (!slang_assembly_typeinfo_construct (&ti))\r
+               return GL_FALSE;\r
+       if (!_slang_typeof_operation (op, &A->space, &ti, A->atoms))\r
+               goto end1;\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
+       if (!slang_storage_aggregate_construct (&agg))\r
+               goto end1;\r
+       if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, A->space.funcs, A->space.structs,\r
+                       A->space.vars, A->mach, A->file, A->atoms))\r
+               goto end;\r
 \r
        index = 0;\r
        size = _slang_sizeof_aggregate (&agg);\r
-       result = assign_aggregate (file, &agg, &index, size, info);\r
+       result = assign_aggregate (A, &agg, &index, size);\r
 \r
+end1:\r
        slang_storage_aggregate_destruct (&agg);\r
+end:\r
        slang_assembly_typeinfo_destruct (&ti);\r
        return result;\r
 }\r
 \r
 /*\r
-       _slang_assemble_assign()\r
-\r
-       performs unary (pre ++ and --) or binary (=, +=, -=, *=, /=) assignment on the operation's\r
-       children\r
-*/\r
-\r
-int dereference (slang_assembly_file *file, slang_operation *op,\r
-       slang_assembly_name_space *space, slang_assembly_local_info *info);\r
-\r
-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
+ * _slang_assemble_assign()\r
+ *\r
+ * Performs unary (pre ++ and --) or binary (=, +=, -=, *=, /=) assignment on the operation's\r
+ * children.\r
+ */\r
 \r
-int _slang_assemble_assign (slang_assembly_file *file, slang_operation *op, const char *oper,\r
-       int ref, slang_assembly_name_space *space, slang_assembly_local_info *info)\r
+GLboolean _slang_assemble_assign (slang_assemble_ctx *A, slang_operation *op, const char *oper,\r
+       slang_ref_type ref)\r
 {\r
-       slang_assembly_stack_info stk;\r
-       slang_assembly_flow_control flow;\r
+       slang_swizzle swz;\r
 \r
-       if (!ref)\r
+       if (ref == slang_ref_forbid)\r
        {\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_label2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))\r
+                       return GL_FALSE;\r
        }\r
 \r
        if (slang_string_compare ("=", oper) == 0)\r
        {\r
-               if (!_slang_assemble_operation (file, op->children, 1, &flow, space, info, &stk))\r
-                       return 0;\r
-               if (!_slang_assemble_operation (file, op->children + 1, 0, &flow, space, info, &stk))\r
-                       return 0;\r
-               if (!_slang_assemble_assignment (file, op->children, space, info))\r
-                       return 0;\r
+               if (!_slang_assemble_operation_ (A, &op->children[0], slang_ref_force))\r
+                       return GL_FALSE;\r
+               swz = A->swz;\r
+               if (!_slang_assemble_operation_ (A, &op->children[1], slang_ref_forbid))\r
+                       return GL_FALSE;\r
+               A->swz = swz;\r
+               if (!_slang_assemble_assignment (A, op->children))\r
+                       return GL_FALSE;\r
        }\r
        else\r
        {\r
-               if (!call_function_name (file, oper, op->children, op->num_children, 1, space, info))\r
-                       return 0;\r
+               if (!_slang_assemble_function_call_name (A, oper, op->children, op->num_children, GL_TRUE))\r
+                       return GL_FALSE;\r
        }\r
 \r
-       if (!ref)\r
+       if (ref == slang_ref_forbid)\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
+               if (!slang_assembly_file_push (A->file, slang_asm_addr_copy))\r
+                       return GL_FALSE;\r
+               if (!slang_assembly_file_push_label (A->file, slang_asm_local_free, 4))\r
+                       return GL_FALSE;\r
+               if (!_slang_dereference (A, op->children))\r
+                       return GL_FALSE;\r
        }\r
 \r
-       return 1;\r
+       return GL_TRUE;\r
 }\r
 \r