Lots of assorted changes.
authorBrian <brian@yutani.localnet.net>
Fri, 15 Dec 2006 22:35:57 +0000 (15:35 -0700)
committerBrian <brian@yutani.localnet.net>
Fri, 15 Dec 2006 22:35:57 +0000 (15:35 -0700)
Implement assignment/move for types larger than 4 floats.
Fix codegen bug for "return expr" in inlined functions.
More clean-up of storage allocation code (slang_resolve_storage).

src/mesa/shader/slang/slang_assemble.h
src/mesa/shader/slang/slang_codegen.c
src/mesa/shader/slang/slang_compile_operation.c
src/mesa/shader/slang/slang_compile_operation.h
src/mesa/shader/slang/slang_emit.c
src/mesa/shader/slang/slang_emit.h
src/mesa/shader/slang/slang_link2.c

index d507fc0..1225ee4 100644 (file)
@@ -242,6 +242,12 @@ typedef struct slang_assembly_name_space_
    struct slang_variable_scope_ *vars;
 } slang_assembly_name_space;
 
+
+typedef struct {
+   GLboolean TempUsed[MAX_PROGRAM_TEMPS];
+} slang_gen_context;
+
+
 typedef struct slang_assemble_ctx_
 {
    slang_assembly_file *file;
@@ -253,6 +259,7 @@ typedef struct slang_assemble_ctx_
    slang_ref_type ref;
    slang_swizzle swz;
    struct gl_program *program;
+   slang_gen_context *codegen;
 } slang_assemble_ctx;
 
 extern struct slang_function_ *
index af543ad..acca05d 100644 (file)
@@ -53,37 +53,6 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper);
 
 
 
-/**
- * Allocate storage for given variable, attach it to 'ir'.
- */
-static GLboolean
-slang_alloc_var_storage(slang_variable *variable, slang_ir_node *ir)
-{
-   slang_ir_storage *store;
-
-   assert(variable);
-
-   /*assert(!variable->aux);*/
-
-   if (variable->aux) {
-      store = (slang_ir_storage *) variable->aux;
-      ir->Store = store;
-      if (store)
-         store->Size = -12;
-   }
-   else {
-      /* alloc storage */
-      store = (slang_ir_storage *) _mesa_calloc(sizeof(*store));
-      store->File = PROGRAM_TEMPORARY;
-      store->Index = -1;
-      store->Size = -10;
-      variable->aux = store;
-      ir->Store = store;
-   }
-   return GL_TRUE;
-}
-
-
 static slang_ir_node *
 new_node(slang_ir_opcode op, slang_ir_node *left, slang_ir_node *right)
 {
@@ -180,7 +149,7 @@ new_var(slang_assemble_ctx *A, slang_operation *oper,
    oper->var = v;
    n->Swizzle = swizzle;
    n->Var = v;
-   slang_resolve_storage(NULL, n, A->program);
+   slang_resolve_storage(A->codegen/**NULL**/, n, A->program);
    return n;
 }
 
@@ -221,15 +190,30 @@ slang_is_writemask(const char *field, GLuint *mask)
 }
 
 
+/**
+ * Assemble a "return" statement.
+ */
 static slang_ir_node *
 slang_assemble_return(slang_assemble_ctx * A, slang_operation *oper)
 {
-   if (oper->num_children == 0) {
-      /* Convert to:
+   if (oper->num_children == 0 ||
+       (oper->num_children == 1 &&
+        oper->children[0].type == slang_oper_void)) {
+      /* Convert from:
+       *   return;
+       * To:
        *   goto __endOfFunction;
        */
-      oper->type = slang_oper_goto;
-      oper->a_id = slang_atom_pool_atom(A->atoms, CurFunction->end_label);
+      slang_ir_node *n;
+      slang_operation gotoOp;
+      slang_operation_construct(&gotoOp);
+      gotoOp.type = slang_oper_goto;
+      gotoOp.a_id = slang_atom_pool_atom(A->atoms, CurFunction->end_label);
+      /* assemble the new code */
+      n = slang_assemble_operation(A, &gotoOp);
+      /* destroy temp code */
+      slang_operation_destruct(&gotoOp);
+      return n;
    }
    else {
       /*
@@ -241,11 +225,12 @@ slang_assemble_return(slang_assemble_ctx * A, slang_operation *oper)
        */
       slang_operation *block, *assign, *jump;
       slang_atom a_retVal;
+      slang_ir_node *n;
 
       a_retVal = slang_atom_pool_atom(A->atoms, "__retVal");
       assert(a_retVal);
 
-#if 1
+#if 1 /* DEBUG */
       {
          slang_variable *v
             = _slang_locate_variable(oper->locals, a_retVal, GL_TRUE);
@@ -266,17 +251,13 @@ slang_assemble_return(slang_assemble_ctx * A, slang_operation *oper)
       assign->locals->outer_scope = block->locals;
       assign->num_children = 2;
       assign->children = slang_operation_new(2);
-      /* lhs */
+      /* lhs (__retVal) */
       assign->children[0].type = slang_oper_identifier;
       assign->children[0].a_id = a_retVal;
       assign->children[0].locals->outer_scope = assign->locals;
-      /* rhs */
-#if 0
-      assign->children[1] = oper->children[0]; /* XXX copy */
-#else
+      /* rhs (expr) */
+      /* XXX we might be able to avoid this copy someday */
       slang_operation_copy(&assign->children[1], &oper->children[0]);
-#endif
-
 
       /* child[1]: goto __endOfFunction */
       jump = &block->children[1];
@@ -284,17 +265,16 @@ slang_assemble_return(slang_assemble_ctx * A, slang_operation *oper)
       assert(CurFunction->end_label);
       jump->a_id = slang_atom_pool_atom(A->atoms, CurFunction->end_label);
 
-#if 00
+#if 0 /* debug */
       printf("NEW RETURN:\n");
       slang_print_tree(block, 0);
 #endif
 
-      slang_operation_copy(oper, block);
-      /* XXX destruct block */
+      /* assemble the new code */
+      n = slang_assemble_operation(A, block);
+      slang_operation_delete(block);
+      return n;
    }
-
-   /* assemble the new code */
-   return slang_assemble_operation(A, oper);
 }
 
 
@@ -426,28 +406,37 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
         }
       }
       break;
+#if 0 /* XXX rely on default case below */
    case slang_oper_return:
       /* do return replacement here too */
-      slang_assemble_return(A, oper);
-      slang_substitute(A, oper, substCount, substOld, substNew, GL_FALSE);
+      assert(oper->num_children == 0 || oper->num_children == 1);
+      if (oper->num_children == 1) {
+         slang_substitute(A, &oper->children[0],
+                          substCount, substOld, substNew, GL_FALSE);
+      }
       break;
+#endif
    case slang_oper_assign:
    case slang_oper_subscript:
       /* special case:
        * child[0] can't have substitutions but child[1] can.
        */
-      slang_substitute(A, &oper->children[0], substCount, substOld, substNew, GL_TRUE);
-      slang_substitute(A, &oper->children[1], substCount, substOld, substNew, GL_FALSE);
+      slang_substitute(A, &oper->children[0],
+                       substCount, substOld, substNew, GL_TRUE);
+      slang_substitute(A, &oper->children[1],
+                       substCount, substOld, substNew, GL_FALSE);
       break;
    case slang_oper_field:
       /* XXX NEW - test */
-      slang_substitute(A, &oper->children[0], substCount, substOld, substNew, GL_TRUE);
+      slang_substitute(A, &oper->children[0],
+                       substCount, substOld, substNew, GL_TRUE);
       break;
    default:
       {
          GLuint i;
          for (i = 0; i < oper->num_children; i++) 
-            slang_substitute(A, &oper->children[i], substCount, substOld, substNew, GL_FALSE);
+            slang_substitute(A, &oper->children[i],
+                             substCount, substOld, substNew, GL_FALSE);
       }
    }
 }
@@ -1015,11 +1004,10 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
 
          assert(oper->num_children == 0 || oper->num_children == 1);
 
-         v = _slang_locate_variable(oper->locals,
-                                    oper->a_id, GL_TRUE);
+         v = _slang_locate_variable(oper->locals, oper->a_id, GL_TRUE);
          assert(v);
          varDecl = new_var_decl(A, v);
-         slang_alloc_var_storage(v, varDecl);
+         slang_resolve_storage(A->codegen, varDecl, A->program);
 
          if (oper->num_children > 0) {
             /* child is initializer */
@@ -1027,18 +1015,26 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
             assert(oper->num_children == 1);
             var = new_var(A, oper, oper->a_id, SWIZZLE_NOOP);
             /* XXX make copy of this initializer? */
+            /*
             printf("\n*** ASSEMBLE INITIALIZER %p\n", (void*) v->initializer);
+            */
             rhs = slang_assemble_operation(A, &oper->children[0]);
             init = new_node(IR_MOVE, var, rhs);
+            /*assert(rhs->Opcode != IR_SEQ);*/
             n = new_seq(varDecl, init);
          }
          else if (v->initializer) {
             slang_ir_node *var, *init, *rhs;
             var = new_var(A, oper, oper->a_id, SWIZZLE_NOOP);
             /* XXX make copy of this initializer? */
+            /*
             printf("\n*** ASSEMBLE INITIALIZER %p\n", (void*) v->initializer);
+            */
             rhs = slang_assemble_operation(A, v->initializer);
             init = new_node(IR_MOVE, var, rhs);
+            /*
+         assert(rhs->Opcode != IR_SEQ);
+            */
             n = new_seq(varDecl, init);
          }
          else {
@@ -1056,10 +1052,9 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
           oper->children[1].type == slang_oper_call) {
          /* special case */
          slang_ir_node *n;
-         printf(">>>>>>>>>>>>>> Assign function call\n");
          n = slang_assemble_function_call_name(A,
-                                               (const char *) oper->children[1].a_id,
-                                              &oper->children[1], &oper->children[0]);
+                                      (const char *) oper->children[1].a_id,
+                                      &oper->children[1], &oper->children[0]);
          return n;
       }
       else
@@ -1077,6 +1072,9 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
          c1 = slang_assemble_operation(A, &oper->children[1]);
 
          n = new_node(IR_MOVE, c0, c1);
+         /*
+         assert(c1->Opcode != IR_SEQ);
+         */
         n->Writemask = mask;
         return n;
       }
@@ -1148,33 +1146,29 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
       /* array dereference */
       if (oper->children[1].type == slang_oper_literal_int) {
          /* compile-time constant index - OK */
-         slang_assembly_typeinfo ti;
+         slang_assembly_typeinfo elem_ti;
          slang_ir_node *base;
-         slang_ir_storage *store2;
          GLint index;
-         slang_assembly_typeinfo_construct(&ti);
-         _slang_typeof_operation(A, &oper->children[0], &ti);
+
+         /* get type of array element */
+         slang_assembly_typeinfo_construct(&elem_ti);
+         _slang_typeof_operation(A, oper, &elem_ti);
 
          base = slang_assemble_operation(A, &oper->children[0]);
          assert(base->Opcode == IR_VAR);
+         assert(base->Store);
 
          index = (GLint) oper->children[1].literal[0];
-         /*
-         printf("element[%d]\n", index);
-         */
-#if 1
-         store2 = (slang_ir_storage *) _mesa_calloc(sizeof(*store2));
-         *store2 = *base->Store;
-         base->Store = store2;
-         base->Store->Size = -15;
-#endif
-         assert(base->Store);
+         /*printf("element[%d]\n", index);*/
+         /* new storage info since we don't want to change the original */
+         base->Store = _slang_clone_ir_storage(base->Store);
+         /* bias Index by array subscript, update storage size */
          base->Store->Index += index;
-         base->Store->Size = 1;
+         base->Store->Size = _slang_sizeof_type_specifier(&elem_ti.spec);
          return base;
       }
       else {
-         /* run-time index - TBD */
+         /* run-time index - not supported yet - TBD */
          abort();
       }
       return NULL;
@@ -1192,6 +1186,7 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
         slang_ir_node *one = new_float_literal(1.0, 1.0, 1.0, 1.0);
         slang_ir_node *sum = new_node(IR_ADD, var, one);
         slang_ir_node *assign = new_node(IR_MOVE, var, sum);
+         assert(sum->Opcode != IR_SEQ);
         return assign;
       }
       break;
@@ -1233,12 +1228,13 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
      return 0;
 
    printf("\n*********** Assemble function2(%s)\n", (char*)fun->header.a_name);
-#if 0
+#if 1
    slang_print_function(fun, 1);
 #endif
 
    A->program->Parameters = _mesa_new_parameter_list();
    A->program->Varying = _mesa_new_parameter_list();
+   A->codegen = _slang_new_codegen_context();
 
    /*printf("** Begin Simplify\n");*/
    slang_simplify(fun->body, &A->space, A->atoms);
@@ -1246,11 +1242,11 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
 
    CurFunction = fun;
 
-   n = slang_assemble_operation(A, fun->body);
-
    if (!CurFunction->end_label)
       CurFunction->end_label = slang_atom_pool_gen(A->atoms, "__endOfFunction_Main");
 
+   n = slang_assemble_operation(A, fun->body);
+
    endLabel = new_label(fun->end_label);
    n = new_seq(n, endLabel);
 
@@ -1263,14 +1259,13 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
 
    printf("************* IR for %s *******\n", (char*)fun->header.a_name);
    slang_print_ir(n, 0);
+   printf("************* End assemble function2 ************\n\n");
 #endif
 
    if (_mesa_strcmp((char*) fun->header.a_name, "main") == 0) {
-      _slang_emit_code(n, A->program);
+      _slang_emit_code(n, A->codegen, A->program);
    }
 
-   printf("************* End assemble function2 ************\n\n");
-
    return n;
 }
 
index 192f2b0..28d9fdf 100644 (file)
@@ -135,6 +135,17 @@ slang_operation_new(GLuint count)
 }
 
 
+/**
+ * Delete operation and all children
+ */
+void
+slang_operation_delete(slang_operation *oper)
+{
+   slang_operation_destruct(oper);
+   _mesa_free(oper);
+}
+
+
 slang_operation *
 slang_operation_grow(GLuint *numChildren, slang_operation **children)
 {
index f6d0ba8..ad52b66 100644 (file)
@@ -138,6 +138,9 @@ slang_operation_copy(slang_operation *, const slang_operation *);
 extern slang_operation *
 slang_operation_new(GLuint count);
 
+extern void
+slang_operation_delete(slang_operation *oper);
+
 extern slang_operation *
 slang_operation_grow(GLuint *numChildren, slang_operation **children);
 
index 104064f..4f7a9dd 100644 (file)
@@ -130,6 +130,15 @@ _slang_new_ir_storage(enum register_file file, GLint index, GLint size)
 }
 
 
+slang_ir_storage *
+_slang_clone_ir_storage(slang_ir_storage *store)
+{
+   slang_ir_storage *clone
+      = _slang_new_ir_storage(store->File, store->Index, store->Size);
+   return clone;
+}
+
+
 static const char *
 swizzle_string(GLuint swizzle)
 {
@@ -194,10 +203,10 @@ sizeof_struct(const slang_struct *s)
 }
 
 
-static GLuint
-sizeof_type(const slang_fully_specified_type *t)
+GLuint
+_slang_sizeof_type_specifier(const slang_type_specifier *spec)
 {
-   switch (t->specifier.type) {
+   switch (spec->type) {
    case slang_spec_void:
       abort();
       return 0;
@@ -240,7 +249,7 @@ sizeof_type(const slang_fully_specified_type *t)
       abort();
       return 0;
    case slang_spec_struct:
-      return sizeof_struct(t->specifier._struct);
+      return sizeof_struct(spec->_struct);
    case slang_spec_array:
       return 1; /* XXX */
    default:
@@ -251,6 +260,14 @@ sizeof_type(const slang_fully_specified_type *t)
 }
 
 
+
+static GLuint
+sizeof_type(const slang_fully_specified_type *t)
+{
+   return _slang_sizeof_type_specifier(&t->specifier);
+}
+
+
 #define IND 0
 void
 slang_print_ir(const slang_ir_node *n, int indent)
@@ -269,7 +286,7 @@ slang_print_ir(const slang_ir_node *n, int indent)
    switch (n->Opcode) {
    case IR_SEQ:
 #if IND
-      printf("SEQ  store %p\n", (void*) n->Store);
+      printf("SEQ  at %p\n", (void*) n);
 #endif
       assert(n->Children[0]);
       assert(n->Children[1]);
@@ -325,12 +342,22 @@ slang_print_ir(const slang_ir_node *n, int indent)
 
 
 static GLint
-alloc_temporary(slang_gen_context *gc)
+alloc_temporary(slang_gen_context *gc, GLint size)
 {
-   GLuint i;
+   const GLuint sz4 = (size + 3) / 4;
+   GLuint i, j;
+   ASSERT(size > 0); /* number of floats */
    for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
-      if (!gc->TempUsed[i]) {
-         gc->TempUsed[i] = GL_TRUE;
+      GLuint found = 0;
+      for (j = 0; j < sz4; j++) {
+         if (!gc->TempUsed[i + j]) {
+            found++;
+         }
+      }
+      if (found == sz4) {
+         /* found block of size/4 free regs */
+         for (j = 0; j < sz4; j++)
+            gc->TempUsed[i + j] = GL_TRUE;
          return i;
       }
    }
@@ -349,10 +376,14 @@ is_temporary(const slang_gen_context *gc, const slang_ir_storage *st)
 
 
 static void
-free_temporary(slang_gen_context *gc, GLuint r)
+free_temporary(slang_gen_context *gc, GLuint r, GLint size)
 {
-   if (gc->TempUsed[r])
-      gc->TempUsed[r] = GL_FALSE;
+   const GLuint sz4 = (size + 3) / 4;
+   GLuint i;
+   for (i = 0; i < sz4; i++) {
+      if (gc->TempUsed[r + i])
+         gc->TempUsed[r + i] = GL_FALSE;
+   }
 }
 
 
@@ -589,7 +620,7 @@ slang_alloc_temp_storage(slang_gen_context *gc, slang_ir_node *n, GLint size)
    assert(!n->Var);
    assert(!n->Store);
    assert(size > 0);
-   indx = alloc_temporary(gc);
+   indx = alloc_temporary(gc, size);
    n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, indx, size);
 }
 
@@ -609,9 +640,12 @@ void
 slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
                       struct gl_program *prog)
 {
-   int k = 0;
+   assert(gc);
+   assert(n);
+   assert(prog);
+
    if (!n->Store) {
-      /**assert(n->Var);**/
+      /* allocate storage info for this node */
       if (n->Var && n->Var->aux) {
          /* node storage info = var storage info */
          n->Store = (slang_ir_storage *) n->Var->aux;
@@ -619,21 +653,19 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
       else {
          /* alloc new storage info */
          n->Store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -1, -5);
-         k = 1;
-         /*XXX n->Store->Size = sizeof(var's type) */
          if (n->Var)
             n->Var->aux = n->Store;
       }
    }
 
    if (n->Opcode == IR_VAR_DECL) {
-      /* allocate storage for a user's variable */
+      /* storage declaration */
       assert(n->Var);
-      if (n->Store->Index < 0) {
+      if (n->Store->Index < 0) { /* XXX assert this? */
          assert(gc);
          n->Store->File = PROGRAM_TEMPORARY;
-         n->Store->Index = alloc_temporary(gc);
          n->Store->Size = sizeof_type(&n->Var->type);
+         n->Store->Index = alloc_temporary(gc, n->Store->Size);
          printf("alloc var %s storage at %d (size %d)\n",
                 (char *) n->Var->a_name,
                 n->Store->Index,
@@ -641,6 +673,7 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
          assert(n->Store->Size > 0);
          n->Var->declared = GL_TRUE;
       }
+      assert(n->Store->Size > 0);
       return;
    }
 
@@ -649,7 +682,12 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
       GLint i;
 
       assert(n->Var);
-      assert(prog);
+
+      if (n->Store->Size < 0) {
+         /* determine var/storage size now */
+         n->Store->Size = sizeof_type(&n->Var->type);
+         assert(n->Store->Size > 0);
+      }
 
 #if 0
       assert(n->Var->declared ||
@@ -665,7 +703,6 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
       if (i >= 0) {
          n->Store->File = PROGRAM_INPUT;
          n->Store->Index = i;
-         n->Store->Size = sizeof_type(&n->Var->type);
          assert(n->Store->Size > 0);
          prog->InputsRead |= (1 << i);
          return;
@@ -675,7 +712,6 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
       if (i >= 0) {
          n->Store->File = PROGRAM_OUTPUT;
          n->Store->Index = i;
-         n->Store->Size = sizeof_type(&n->Var->type);
          prog->OutputsWritten |= (1 << i);
          return;
       }
@@ -684,7 +720,6 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
       if (i >= 0) {
          n->Store->File = PROGRAM_STATE_VAR;
          n->Store->Index = i;
-         n->Store->Size = sizeof_type(&n->Var->type);
          return;
       }
 
@@ -692,7 +727,6 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
       if (i >= 0) {
          n->Store->File = PROGRAM_CONSTANT;
          n->Store->Index = i;
-         n->Store->Size = sizeof_type(&n->Var->type);
          return;
       }
 
@@ -702,7 +736,6 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
          if (i >= 0) {
             n->Store->File = PROGRAM_UNIFORM;
             n->Store->Index = i;
-            n->Store->Size = sizeof_type(&n->Var->type);
             return;
          }
       }
@@ -717,27 +750,17 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
 #else
             n->Store->File = PROGRAM_VARYING;
 #endif
-            n->Store->Size = sizeof_type(&n->Var->type);
             n->Store->Index = i;
             return;
          }
       }
 
-      /* what is this?!? */
-      /*
-      abort();
-      */
-   }
-
-   if (n->Store->File == PROGRAM_TEMPORARY && n->Store->Index < 0) {
-      /* unnamed intermediate temporary */
-      if (gc)
-         n->Store->Index = alloc_temporary(gc);
-      return;
-   }
-
-   if (gc && n->Store->File == PROGRAM_UNDEFINED && n->Store->Size < 0) {
-      abort();
+      if (n->Store->File == PROGRAM_UNDEFINED && n->Store->Index < 0) {
+         /* ordinary local var */
+         assert(n->Store->Size > 0);
+         n->Store->File = PROGRAM_TEMPORARY;
+         n->Store->Index = alloc_temporary(gc, n->Store->Size);
+      }
    }
 }
 
@@ -755,6 +778,7 @@ alloc_constant(const GLfloat v[], GLuint size, struct gl_program *prog)
 /**
  * Swizzle a swizzle.
  */
+#if 0
 static GLuint
 swizzle_compose(GLuint swz1, GLuint swz2)
 {
@@ -766,6 +790,7 @@ swizzle_compose(GLuint swz1, GLuint swz2)
    swz = MAKE_SWIZZLE4(s[0], s[1], s[2], s[3]);
    return swz;
 }
+#endif
 
 
 /**
@@ -783,6 +808,7 @@ storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st,
    };
    dst->File = st->File;
    dst->Index = st->Index;
+   assert(st->File != PROGRAM_UNDEFINED);
    assert(st->Size >= 1);
    assert(st->Size <= 4);
    dst->WriteMask = defaultWritemask[st->Size - 1] & writemask;
@@ -805,6 +831,7 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st,
      
    src->File = st->File;
    src->Index = st->Index;
+   assert(st->File != PROGRAM_UNDEFINED);
    assert(st->Size >= 1);
    assert(st->Size <= 4);
    /* XXX swizzling logic here may need some work */
@@ -945,7 +972,8 @@ gen(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
           * Just modify the RHS to put its result into the dest of this
           * MOVE operation.  Then, this MOVE is a no-op.
           */
-         free_temporary(gc, n->Children[1]->Store->Index);
+         free_temporary(gc, n->Children[1]->Store->Index,
+                        n->Children[1]->Store->Size);
          *n->Children[1]->Store = *n->Children[0]->Store;
          /* fixup the prev (RHS) instruction */
          storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask);
@@ -954,14 +982,40 @@ gen(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
       else
 #endif
       {
-         inst = new_instruction(prog, OPCODE_MOV);
-         storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask);
-         storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store,
-                            n->Children[1]->Swizzle);
+#if 1
+         if (n->Children[0]->Store->Size > 4) {
+            /* move matrix/struct etc */
+            slang_ir_storage dstStore = *n->Children[0]->Store;
+            slang_ir_storage srcStore = *n->Children[1]->Store;
+            GLint size = srcStore.Size;
+            ASSERT(n->Children[0]->Writemask == WRITEMASK_XYZW);
+            ASSERT(n->Children[1]->Swizzle == SWIZZLE_NOOP);
+            dstStore.Size = 4;
+            srcStore.Size = 4;
+            while (size >= 4) {
+               inst = new_instruction(prog, OPCODE_MOV);
+               inst->Comment = _mesa_strdup("IR_MOVE block");
+               storage_to_dst_reg(&inst->DstReg, &dstStore, n->Writemask);
+               storage_to_src_reg(&inst->SrcReg[0], &srcStore,
+                                  n->Children[1]->Swizzle);
+               srcStore.Index++;
+               dstStore.Index++;
+               size -= 4;
+            }
+         }
+         else
+#endif
+         {
+            inst = new_instruction(prog, OPCODE_MOV);
+            storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask);
+            storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store,
+                               n->Children[1]->Swizzle);
+         }
          if (n->Children[1]->Store->File == PROGRAM_TEMPORARY) {
-            free_temporary(gc, n->Children[1]->Store->Index);
+            free_temporary(gc, n->Children[1]->Store->Index,
+                           n->Children[1]->Store->Size);
          }
-         inst->Comment = n->Comment;
+         /*inst->Comment = _mesa_strdup("IR_MOVE");*/
          n->Store = n->Children[0]->Store; /*XXX new */
          return inst;
       }
@@ -1012,14 +1066,24 @@ gen(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
 }
 
 
+slang_gen_context *
+_slang_new_codegen_context(void)
+{
+   slang_gen_context *gc = (slang_gen_context *) _mesa_calloc(sizeof(*gc));
+   return gc;
+}
+
+
 
 GLboolean
-_slang_emit_code(slang_ir_node *n, struct gl_program *prog)
+_slang_emit_code(slang_ir_node *n, slang_gen_context *gc,
+                 struct gl_program *prog)
 {
-   slang_gen_context *gc;
    /*GET_CURRENT_CONTEXT(ctx);*/
 
-   gc = (slang_gen_context *) _mesa_calloc(sizeof(*gc));
+   /*
+   gc = _slang_new_codegen_context();
+   */
 
    printf("************ Begin generate code\n");
 
index 1683542..8ac17e6 100644 (file)
@@ -32,9 +32,8 @@
 #include "mtypes.h"
 
 
-typedef struct {
-   GLboolean TempUsed[MAX_PROGRAM_TEMPS];
-} slang_gen_context;
+extern slang_gen_context *
+_slang_new_codegen_context(void);
 
 
 extern void
@@ -45,12 +44,21 @@ extern slang_ir_storage *
 _slang_new_ir_storage(enum register_file file, GLint index, GLint size);
 
 
+extern slang_ir_storage *
+_slang_clone_ir_storage(slang_ir_storage *store);
+
+
+extern GLuint
+_slang_sizeof_type_specifier(const slang_type_specifier *spec);
+
+
 extern void
 slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
                       struct gl_program *prog);
 
 extern GLboolean
-_slang_emit_code(slang_ir_node *n, struct gl_program *prog);
+_slang_emit_code(slang_ir_node *n, slang_gen_context *gc,
+                 struct gl_program *prog);
 
 
 #endif /* SLANG_EMIT_H */
index 9fa5399..50e62d8 100644 (file)
@@ -320,18 +320,6 @@ _slang_link2(GLcontext *ctx,
    linked->FragmentProgram = (struct gl_fragment_program *)
       _mesa_clone_program(ctx, &fragProg->Base);
 
-#if 1
-   printf("************** orig fragment program\n");
-   _mesa_print_program(&fragProg->Base);
-   _mesa_print_program_parameters(ctx, &fragProg->Base);
-#endif
-
-#if 1
-   printf("************** orig vertex program\n");
-   _mesa_print_program(&vertProg->Base);
-   _mesa_print_program_parameters(ctx, &fragProg->Base);
-#endif
-
    link_varying_vars(linked, &linked->VertexProgram->Base);
    link_varying_vars(linked, &linked->FragmentProgram->Base);
 
@@ -345,10 +333,22 @@ _slang_link2(GLcontext *ctx,
    linked->FragmentProgram->Base.Parameters = linked->Uniforms;
 
 #if 1
-   printf("************** linked/cloned frag prog\n");
+   printf("************** original fragment program\n");
+   _mesa_print_program(&fragProg->Base);
+   _mesa_print_program_parameters(ctx, &fragProg->Base);
+#endif
+#if 1
+   printf("************** linked fragment prog\n");
    _mesa_print_program(&linked->FragmentProgram->Base);
    _mesa_print_program_parameters(ctx, &linked->FragmentProgram->Base);
-   printf("************** linked/cloned vert prog\n");
+#endif
+#if 1
+   printf("************** original vertex program\n");
+   _mesa_print_program(&vertProg->Base);
+   _mesa_print_program_parameters(ctx, &fragProg->Base);
+#endif
+#if 1
+   printf("************** linked vertex prog\n");
    _mesa_print_program(&linked->VertexProgram->Base);
    _mesa_print_program_parameters(ctx, &linked->VertexProgram->Base);
 #endif