*/\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_typeinfo.h"\r
-#include "slang_assemble_conditional.h"\r
-#include "slang_assemble_assignment.h"\r
-#include "slang_execute.h"\r
\r
/* slang_assembly */\r
\r
slang_assembly_typeinfo_destruct (&ti);\r
return GL_FALSE;\r
}\r
- if (ti.spec.type != slang_spec_void)\r
- if (A->ref == slang_ref_force)\r
+ if (ti.spec.type != slang_spec_void) {\r
+ if (A->ref == slang_ref_force) {\r
size = 4;\r
+ }\r
else if (!sizeof_variable (A, &ti.spec, slang_qual_none, 0, &size))\r
{\r
slang_assembly_typeinfo_destruct (&ti);\r
return GL_FALSE;\r
}\r
+ }\r
slang_assembly_typeinfo_destruct (&ti);\r
\r
/* if nonzero, free it from the stack */\r
{ "float_noise3", slang_asm_float_noise3, slang_asm_float_copy },\r
{ "float_noise4", slang_asm_float_noise4, slang_asm_float_copy },\r
{ "int_to_float", slang_asm_int_to_float, slang_asm_float_copy },\r
+ { "vec4_tex1d", slang_asm_vec4_tex1d, slang_asm_none },\r
{ "vec4_tex2d", slang_asm_vec4_tex2d, slang_asm_none },\r
+ { "vec4_tex3d", slang_asm_vec4_tex3d, slang_asm_none },\r
+ { "vec4_texcube", slang_asm_vec4_texcube, slang_asm_none },\r
+ { "vec4_shad1d", slang_asm_vec4_shad1d, slang_asm_none },\r
+ { "vec4_shad2d", slang_asm_vec4_shad2d, slang_asm_none },\r
/* mesa-specific extensions */\r
{ "float_print", slang_asm_float_deref, slang_asm_float_print },\r
{ "int_print", slang_asm_int_deref, slang_asm_int_print },\r
else\r
{\r
GLuint i, struct_size = 0, field_offset = 0, field_size = 0;\r
+ GLboolean relocate, shrink;\r
\r
+ /* calculate struct size, field offset and field size */\r
for (i = 0; i < tib->spec._struct->fields->num_variables; i++)\r
{\r
slang_variable *field;\r
field_offset += size;\r
}\r
\r
- if (!PLAB (A->file, slang_asm_addr_push, field_offset))\r
- return GL_FALSE;\r
+ /*\r
+ * OPTIMIZATION: If selecting the last field, no relocation is needed.\r
+ */\r
+ relocate = field_offset != struct_size - field_size;\r
\r
- if (ref == slang_ref_force)\r
+ /*\r
+ * OPTIMIZATION: If field and struct sizes are equal, no partial free is needed.\r
+ */\r
+ shrink = field_size != struct_size;\r
+\r
+ if (relocate)\r
{\r
- if (!PUSH (A->file, slang_asm_addr_add))\r
+ if (!PLAB (A->file, slang_asm_addr_push, field_offset))\r
return GL_FALSE;\r
}\r
+\r
+ if (ref == slang_ref_force)\r
+ {\r
+ if (relocate)\r
+ {\r
+ if (!PUSH (A->file, slang_asm_addr_add))\r
+ return GL_FALSE;\r
+ }\r
+ }\r
else\r
{\r
- GLuint i;\r
+ GLuint free_b = 0;\r
\r
- /* move the selected element to the beginning of the master expression */\r
- for (i = 0; i < field_size; i += 4)\r
- if (!PLAB2 (A->file, slang_asm_float_move, struct_size - field_size + i + 4, i + 4))\r
- return GL_FALSE;\r
- if (!PLAB (A->file, slang_asm_local_free, 4))\r
- return GL_FALSE;\r
+ if (relocate)\r
+ {\r
+ GLuint i;\r
\r
- /* free the rest of the master expression */\r
- if (!PLAB (A->file, slang_asm_local_free, struct_size - field_size))\r
- return GL_FALSE;\r
+ /* move the selected element to the beginning of the master expression */\r
+ for (i = 0; i < field_size; i += 4)\r
+ if (!PLAB2 (A->file, slang_asm_float_move, struct_size - field_size + i + 4, i + 4))\r
+ return GL_FALSE;\r
+ free_b += 4;\r
+ }\r
+\r
+ if (shrink)\r
+ {\r
+ /* free the rest of the master expression */\r
+ free_b += struct_size - field_size;\r
+ }\r
+\r
+ if (free_b)\r
+ {\r
+ if (!PLAB (A->file, slang_asm_local_free, free_b))\r
+ return GL_FALSE;\r
+ }\r
}\r
}\r
\r
/* push the variable's address */\r
if (var->global)\r
{\r
- if (!PLAB (A->file, slang_asm_addr_push, var->address))\r
+ if (!PLAB (A->file, slang_asm_global_addr, var->address))\r
return GL_FALSE;\r
}\r
else\r
case slang_oper_addassign:\r
if (!_slang_assemble_assign (A, op, "+=", ref))\r
return GL_FALSE;\r
+ A->ref = ref;\r
break;\r
case slang_oper_subassign:\r
if (!_slang_assemble_assign (A, op, "-=", ref))\r
return GL_FALSE;\r
+ A->ref = ref;\r
break;\r
case slang_oper_mulassign:\r
if (!_slang_assemble_assign (A, op, "*=", ref))\r
return GL_FALSE;\r
+ A->ref = ref;\r
break;\r
/*case slang_oper_modassign:*/\r
/*case slang_oper_lshassign:*/\r
case slang_oper_divassign:\r
if (!_slang_assemble_assign (A, op, "/=", ref))\r
return GL_FALSE;\r
+ A->ref = ref;\r
break;\r
case slang_oper_select:\r
if (!_slang_assemble_select (A, op))\r
case slang_oper_preincrement:\r
if (!_slang_assemble_assign (A, op, "++", ref))\r
return GL_FALSE;\r
+ A->ref = ref;\r
break;\r
case slang_oper_predecrement:\r
if (!_slang_assemble_assign (A, op, "--", ref))\r
return GL_FALSE;\r
+ A->ref = ref;\r
break;\r
case slang_oper_plus:\r
if (!_slang_dereference (A, op))\r