More GLSL code - more support for vec4 operations on x86 back-end.
authorMichal Krol <mjkrol@gmail.org>
Wed, 9 Aug 2006 20:05:26 +0000 (20:05 +0000)
committerMichal Krol <mjkrol@gmail.org>
Wed, 9 Aug 2006 20:05:26 +0000 (20:05 +0000)
progs/slang/cltest.txt
progs/slang/vstest.c
src/mesa/shader/slang/slang_assemble.c
src/mesa/shader/slang/slang_assemble.h
src/mesa/shader/slang/slang_assemble_assignment.c
src/mesa/shader/slang/slang_assemble_constructor.c
src/mesa/shader/slang/slang_execute_x86.c
src/mesa/shader/slang/slang_storage.c
src/mesa/shader/slang/slang_storage.h
src/mesa/x86/rtasm/x86sse.c
src/mesa/x86/rtasm/x86sse.h

index 07fee4de57e808fd712e676d2bf200fdad4814b0..e7d47c2cb6206fd6ae859fb6d522f24e61637b5e 100644 (file)
@@ -1463,6 +1463,16 @@ void main () {
 
    printMESA (normalize (_Two4.xyz));
    printMESA (normalize (_Three4));
+
+   vec4 tmp = _Two4;
+   printMESA (tmp);
+
+   printMESA (_Two4 == _Three4);
+   printMESA (_Two4 != _Three4);
+   printMESA (_Two4 == _Two4);
+   printMESA (_Three4 != _Three4);
+   printMESA (_Two4 != vec4 (_Two4.xyz, 999.0));
+   printMESA (_Two4 != vec4 (999.0, _Two4.yzw));
 }
 
 $output
@@ -1552,3 +1562,14 @@ $output
 0.507392
 0.522768
 
+2.1
+2.2
+2.3
+2.4
+
+false
+true
+true
+false
+true
+true
index e31f3b16dfb6f9fff98f4c7bca56da4d17af4750..5108d157428d36c62ffd6b9d52bb06fcd1aa2eab 100644 (file)
@@ -320,7 +320,7 @@ void RenderScene (void)
             break;
          }
          if (fabs (value - attribs[i].data[j]) > EPSILON)
-            printf ("*** %s\n", "Values are different");
+            printf ("*** %s, is %f, should be %f\n", "Values are different", value, attribs[i].data[j]);
          p = strchr (p, '\n');
          if (p != NULL)
             p++;
index 9e5851383c93780d5d25709f49234e12d2accd0d..36fb2305f688eb9a596296b3e7c2421b61984a9d 100644 (file)
@@ -398,74 +398,95 @@ GLboolean _slang_cleanup_stack (slang_assemble_ctx *A, slang_operation *op)
 
 /* _slang_assemble_operation() */
 
-static GLboolean dereference_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg,
-       GLuint *size, slang_swizzle *swz, GLboolean is_swizzled)
+static GLboolean
+dereference_basic (slang_assemble_ctx *A, slang_storage_type type, GLuint *size, slang_swizzle *swz,
+                   GLboolean is_swizzled)
 {
-       GLuint i;
-
-       for (i = agg->count; i > 0; i--)
-       {
-               const slang_storage_array *arr = &agg->arrays[i - 1];
-               GLuint j;
-
-               for (j = arr->length; j > 0; j--)
-               {
-                       if (arr->type == slang_stor_aggregate)
-                       {
-                               if (!dereference_aggregate (A, arr->aggregate, size, swz, is_swizzled))
-                                       return GL_FALSE;
-                       }
-                       else
-                       {
-                               GLuint src_offset;
-                               slang_assembly_type ty;
+   GLuint src_offset;
+   slang_assembly_type ty;
+
+   *size -= _slang_sizeof_type (type);
+
+   /* If swizzling is taking place, we are forced to use scalar operations, even if we have
+    * vec4 instructions enabled (this should be actually done with special vec4 shuffle
+    * instructions).
+    * Adjust the size and calculate the offset within source variable to read.
+    */
+   if (is_swizzled)
+      src_offset = swz->swizzle[*size / 4] * 4;
+   else
+      src_offset = *size;
+
+   /* dereference data slot of a basic type */
+   if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
+      return GL_FALSE;
+   if (!PUSH (A->file, slang_asm_addr_deref))
+      return GL_FALSE;
+   if (src_offset != 0) {
+      if (!PLAB (A->file, slang_asm_addr_push, src_offset))
+         return GL_FALSE;
+      if (!PUSH (A->file, slang_asm_addr_add))
+         return GL_FALSE;
+   }
+
+   switch (type) {
+   case slang_stor_bool:
+      ty = slang_asm_bool_deref;
+      break;
+   case slang_stor_int:
+      ty = slang_asm_int_deref;
+      break;
+   case slang_stor_float:
+      ty = slang_asm_float_deref;
+      break;
+#if defined(USE_X86_ASM) || defined(SLANG_X86)
+   case slang_stor_vec4:
+      ty = slang_asm_vec4_deref;
+      break;
+#endif
+   default:
+      _mesa_problem(NULL, "Unexpected arr->type in dereference_basic");
+      ty = slang_asm_none;
+   }
 
-                               *size -= 4;
+   return PUSH (A->file, ty);
+}
 
-                               /* calculate the offset within source variable to read */
-                               if (is_swizzled)
-                               {
-                                       /* swizzle the index to get the actual offset */
-                                       src_offset = swz->swizzle[*size / 4] * 4;
-                               }
-                               else
-                               {
-                                       /* no swizzling - read sequentially */
-                                       src_offset = *size;
-                               }
+static GLboolean
+dereference_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLuint *size,
+                       slang_swizzle *swz, GLboolean is_swizzled)
+{
+   GLuint i;
 
-                               /* dereference data slot of a basic type */
-                               if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
-                                       return GL_FALSE;
-                               if (!PUSH (A->file, slang_asm_addr_deref))
-                                       return GL_FALSE;
-                               if (!PLAB (A->file, slang_asm_addr_push, src_offset))
-                                       return GL_FALSE;
-                               if (!PUSH (A->file, slang_asm_addr_add))
-                                       return GL_FALSE;
+   for (i = agg->count; i > 0; i--) {
+      const slang_storage_array *arr = &agg->arrays[i - 1];
+      GLuint j;
 
-                               switch (arr->type)
-                               {
-                               case slang_stor_bool:
-                                       ty = slang_asm_bool_deref;
-                                       break;
-                               case slang_stor_int:
-                                       ty = slang_asm_int_deref;
-                                       break;
-                               case slang_stor_float:
-                                       ty = slang_asm_float_deref;
-                                       break;
-                               default:
-                                       _mesa_problem(NULL, "Unexpected arr->type in dereference_aggregate");
-                                       ty = slang_asm_none;
-                               }
-                               if (!PUSH (A->file, ty))
-                                       return GL_FALSE;
-                       }
-               }
-       }
+      for (j = arr->length; j > 0; j--) {
+         if (arr->type == slang_stor_aggregate) {
+            if (!dereference_aggregate (A, arr->aggregate, size, swz, is_swizzled))
+               return GL_FALSE;
+         }
+         else {
+            if (is_swizzled && arr->type == slang_stor_vec4) {
+               if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled))
+                  return GL_FALSE;
+               if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled))
+                  return GL_FALSE;
+               if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled))
+                  return GL_FALSE;
+               if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled))
+                  return GL_FALSE;
+            }
+            else {
+               if (!dereference_basic (A, arr->type, size, swz, is_swizzled))
+                  return GL_FALSE;
+            }
+         }
+      }
+   }
 
-       return GL_TRUE;
+   return GL_TRUE;
 }
 
 GLboolean _slang_dereference (slang_assemble_ctx *A, slang_operation *op)
@@ -694,35 +715,40 @@ static GLboolean call_asm_instruction (slang_assemble_ctx *A, slang_atom a_name)
        return GL_TRUE;
 }
 
-static GLboolean equality_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg,
-       GLuint *index, GLuint size, GLuint z_label)
+static GLboolean
+equality_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLuint *index,
+                    GLuint size, GLuint z_label)
 {
-       GLuint i;
+   GLuint i;
 
-       for (i = 0; i < agg->count; i++)
-       {
-               const slang_storage_array *arr = &agg->arrays[i];
-               GLuint j;
+   for (i = 0; i < agg->count; i++) {
+      const slang_storage_array *arr = &agg->arrays[i];
+      GLuint j;
 
-               for (j = 0; j < arr->length; j++)
-               {
-                       if (arr->type == slang_stor_aggregate)
-                       {
-                               if (!equality_aggregate (A, arr->aggregate, index, size, z_label))
-                                       return GL_FALSE;
-                       }
-                       else
-                       {
-                               if (!PLAB2 (A->file, slang_asm_float_equal_int, size + *index, *index))
-                                       return GL_FALSE;
-                               *index += 4;
-                               if (!PLAB (A->file, slang_asm_jump_if_zero, z_label))
-                                       return GL_FALSE;
-                       }
-               }
-       }
+      for (j = 0; j < arr->length; j++) {
+         if (arr->type == slang_stor_aggregate) {
+            if (!equality_aggregate (A, arr->aggregate, index, size, z_label))
+               return GL_FALSE;
+         }
+         else {
+#if defined(USE_X86_ASM) || defined(SLANG_X86)
+            if (arr->type == slang_stor_vec4) {
+               if (!PLAB2 (A->file, slang_asm_vec4_equal_int, size + *index, *index))
+                  return GL_FALSE;
+            }
+            else
+#endif
+               if (!PLAB2 (A->file, slang_asm_float_equal_int, size + *index, *index))
+                  return GL_FALSE;
 
-       return GL_TRUE;
+            *index += _slang_sizeof_type (arr->type);
+            if (!PLAB (A->file, slang_asm_jump_if_zero, z_label))
+               return GL_FALSE;
+         }
+      }
+   }
+
+   return GL_TRUE;
 }
 
 static GLboolean equality (slang_assemble_ctx *A, slang_operation *op, GLboolean equal)
index fbf88bd6d185df3a799c06bd3ad820a2cd5dabbf..95e4fa263a3a2d91ebe5692d0288dd4ba9276989 100644 (file)
@@ -105,6 +105,9 @@ typedef enum slang_assembly_type_
    slang_asm_vec4_divide,
    slang_asm_vec4_negate,
    slang_asm_vec4_dot,
+   slang_asm_vec4_copy,
+   slang_asm_vec4_deref,
+   slang_asm_vec4_equal_int,
    /* not a real assembly instruction */
        slang_asm__last
 } slang_assembly_type;
index 2f4cb1423f374f5959ce362d12c57cd96d148f15..d894a8db18c19426d42d0e9ac67cb5303622a0c9 100644 (file)
  *      +------------------+
  */
 
-static GLboolean assign_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg,
-       GLuint *index, GLuint size)
+static GLboolean
+assign_basic (slang_assemble_ctx *A, slang_storage_type type, GLuint *index, GLuint size)
 {
-       GLuint i;
-
-       for (i = 0; i < agg->count; i++)
-       {
-               const slang_storage_array *arr = &agg->arrays[i];
-               GLuint j;
-
-               for (j = 0; j < arr->length; j++)
-               {
-                       if (arr->type == slang_stor_aggregate)
-                       {
-                               if (!assign_aggregate (A, arr->aggregate, index, size))
-                                       return GL_FALSE;
-                       }
-                       else
-                       {
-                               GLuint dst_addr_loc, dst_offset;
-                               slang_assembly_type ty;
-
-                               /* calculate the distance from top of the stack to the destination address */
-                               dst_addr_loc = size - *index;
-
-                               /* calculate the offset within destination variable to write */
-                               if (A->swz.num_components != 0)
-                               {
-                                       /* swizzle the index to get the actual offset */
-                                       dst_offset = A->swz.swizzle[*index / 4] * 4;
-                               }
-                               else
-                               {
-                                       /* no swizzling - write sequentially */
-                                       dst_offset = *index;
-                               }
-
-                               switch (arr->type)
-                               {
-                               case slang_stor_bool:
-                                       ty = slang_asm_bool_copy;
-                                       break;
-                               case slang_stor_int:
-                                       ty = slang_asm_int_copy;
-                                       break;
-                               case slang_stor_float:
-                                       ty = slang_asm_float_copy;
-                                       break;
-                               default:
-                                       break;
-                               }
-                               if (!slang_assembly_file_push_label2 (A->file, ty, dst_addr_loc, dst_offset))
-                                       return GL_FALSE;
-
-                               *index += 4;
-                       }
-               }
-       }
+   GLuint dst_offset, dst_addr_loc;
+   slang_assembly_type ty;
+
+   /* Calculate the offset within destination variable to write. */
+   if (A->swz.num_components != 0)
+      dst_offset = A->swz.swizzle[*index / 4] * 4;
+   else
+      dst_offset = *index;
+
+   switch (type) {
+   case slang_stor_bool:
+      ty = slang_asm_bool_copy;
+      break;
+   case slang_stor_int:
+      ty = slang_asm_int_copy;
+      break;
+   case slang_stor_float:
+      ty = slang_asm_float_copy;
+      break;
+#if defined(USE_X86_ASM) || defined(SLANG_X86)
+   case slang_stor_vec4:
+      ty = slang_asm_vec4_copy;
+      break;
+#endif
+   default:
+      _mesa_problem(NULL, "Unexpected arr->type in assign_basic");
+      ty = slang_asm_none;
+   }
+
+  /* Calculate the distance from top of the stack to the destination address. As the
+   * copy operation progresses, components of the source are being successively popped
+   * off the stack by the amount of *index increase step.
+   */
+   dst_addr_loc = size - *index;
+
+   if (!slang_assembly_file_push_label2 (A->file, ty, dst_addr_loc, dst_offset))
+      return GL_FALSE;
+   *index += _slang_sizeof_type (type);
+
+   return GL_TRUE;
+}
 
-       return GL_TRUE;
+static GLboolean
+assign_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLuint *index,
+                  GLuint size)
+{
+   GLuint i;
+
+   for (i = 0; i < agg->count; i++) {
+      const slang_storage_array *arr = &agg->arrays[i];
+      GLuint j;
+
+      for (j = 0; j < arr->length; j++) {
+         if (arr->type == slang_stor_aggregate) {
+            if (!assign_aggregate (A, arr->aggregate, index, size))
+               return GL_FALSE;
+         }
+         else {
+            /* When the destination is swizzled, we are forced to do float_copy, even if
+             * vec4 extension is enabled with vec4_copy operation.
+             */
+            if (A->swz.num_components != 0 && arr->type == slang_stor_vec4) {
+               if (!assign_basic (A, slang_stor_float, index, size))
+                  return GL_FALSE;
+               if (!assign_basic (A, slang_stor_float, index, size))
+                  return GL_FALSE;
+               if (!assign_basic (A, slang_stor_float, index, size))
+                  return GL_FALSE;
+               if (!assign_basic (A, slang_stor_float, index, size))
+                  return GL_FALSE;
+            }
+            else {
+               if (!assign_basic (A, arr->type, index, size))
+                  return GL_FALSE;
+            }
+         }
+      }
+   }
+
+   return GL_TRUE;
 }
 
 GLboolean _slang_assemble_assignment (slang_assemble_ctx *A, slang_operation *op)
index 6f02772bcd7e73d2e5476bcea14aa7a89ec9ede3..9d1aa7071828135b406f1cdc496f0b056b6c209f 100644 (file)
@@ -143,38 +143,32 @@ GLvoid _slang_multiply_swizzles (slang_swizzle *dst, const slang_swizzle *left,
 
 /* _slang_assemble_constructor() */
 
-static GLboolean sizeof_argument (slang_assemble_ctx *A, GLuint *size, slang_operation *op)
+static GLboolean
+sizeof_argument (slang_assemble_ctx *A, GLuint *size, slang_operation *op)
 {
-       slang_assembly_typeinfo ti;
-       GLboolean result = GL_FALSE;
-       slang_storage_aggregate agg, flat_agg;
+   slang_assembly_typeinfo ti;
+   GLboolean result = GL_FALSE;
+   slang_storage_aggregate agg;
 
-       if (!slang_assembly_typeinfo_construct (&ti))
-               return GL_FALSE;
-       if (!_slang_typeof_operation (A, op, &ti))
-               goto end1;
+   if (!slang_assembly_typeinfo_construct (&ti))
+      return GL_FALSE;
+   if (!_slang_typeof_operation (A, op, &ti))
+      goto end1;
 
-       if (!slang_storage_aggregate_construct (&agg))
-               goto end1;
-       if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs,
-                       A->space.vars, A->mach, A->file, A->atoms))
-               goto end2;
+   if (!slang_storage_aggregate_construct (&agg))
+      goto end1;
+   if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs,
+                                   A->space.vars, A->mach, A->file, A->atoms))
+      goto end;
 
-       if (!slang_storage_aggregate_construct (&flat_agg))
-               goto end2;
-       if (!_slang_flatten_aggregate (&flat_agg, &agg))
-               goto end;
-
-       *size = flat_agg.count * 4;
+   *size = _slang_sizeof_aggregate (&agg);
+   result = GL_TRUE;
 
-       result = GL_TRUE;
 end:
-       slang_storage_aggregate_destruct (&flat_agg);
-end2:
-       slang_storage_aggregate_destruct (&agg);
+   slang_storage_aggregate_destruct (&agg);
 end1:
-       slang_assembly_typeinfo_destruct (&ti);
-       return result;
+   slang_assembly_typeinfo_destruct (&ti);
+   return result;
 }
 
 static GLboolean constructor_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *flat,
@@ -270,7 +264,7 @@ GLboolean _slang_assemble_constructor (slang_assemble_ctx *A, slang_operation *o
        arg_sums[1] = 0;        /* will hold all argument's size sum */
        for (i = 0; i < op->num_children; i++)
        {
-               GLuint arg_size;
+               GLuint arg_size = 0;
 
                if (!sizeof_argument (A, &arg_size, &op->children[i]))
                        goto end;
index 59c3aadcaac84438aa75ce7ed024ba5ea6d211b2..468984dce6bddfbc99c4e29ba3c4143fedc8d4c5 100644 (file)
@@ -50,6 +50,7 @@ typedef struct
        struct x86_reg r_eax;
        struct x86_reg r_ecx;
        struct x86_reg r_edx;
+   struct x86_reg r_ebx;
        struct x86_reg r_esp;
        struct x86_reg r_ebp;
        struct x86_reg r_st0;
@@ -183,7 +184,7 @@ static GLvoid do_print_bool (slang_info_log **infolog, GLfloat x)
 
 static GLvoid codegen_assem (codegen_ctx *G, slang_assembly *a, slang_info_log **infolog)
 {
-       GLint disp;
+       GLint disp, i;
 
        switch (a->type)
        {
@@ -517,128 +518,133 @@ static GLvoid codegen_assem (codegen_ctx *G, slang_assembly *a, slang_info_log *
       break;
    case slang_asm_vec4_add:
       /* [vec4] | vec4 */
-      x87_fld (&G->f, x86_deref (G->r_esp));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 4));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 8));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 12));
+      for (i = 0; i < 4; i++)
+         x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4));
       x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16));
       x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp));
-      x87_fld (&G->f, x86_deref (G->r_eax));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 4));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 8));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 12));
-      x87_faddp (&G->f, G->r_st4);
-      x87_faddp (&G->f, G->r_st4);
-      x87_faddp (&G->f, G->r_st4);
-      x87_faddp (&G->f, G->r_st4);
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 12));
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 8));
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 4));
-      x87_fstp (&G->f, x86_deref (G->r_eax));
+      for (i = 0; i < 4; i++)
+         x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4));
+      for (i = 0; i < 4; i++)
+         x87_faddp (&G->f, G->r_st4);
+      for (i = 0; i < 4; i++)
+         x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4));
       break;
    case slang_asm_vec4_subtract:
       /* [vec4] | vec4 */
       x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, 16));
-      x87_fld (&G->f, x86_deref (G->r_eax));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 4));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 8));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 12));
-      x87_fld (&G->f, x86_deref (G->r_esp));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 4));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 8));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 12));
+      for (i = 0; i < 4; i++)
+         x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4));
+      for (i = 0; i < 4; i++)
+         x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4));
       x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16));
-      x87_fsubp (&G->f, G->r_st4);
-      x87_fsubp (&G->f, G->r_st4);
-      x87_fsubp (&G->f, G->r_st4);
-      x87_fsubp (&G->f, G->r_st4);
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 12));
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 8));
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 4));
-      x87_fstp (&G->f, x86_deref (G->r_eax));
+      for (i = 0; i < 4; i++)
+         x87_fsubp (&G->f, G->r_st4);
+      for (i = 0; i < 4; i++)
+         x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4));
       break;
    case slang_asm_vec4_multiply:
       /* [vec4] | vec4 */
-      x87_fld (&G->f, x86_deref (G->r_esp));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 4));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 8));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 12));
+      for (i = 0; i < 4; i++)
+         x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4));
       x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16));
       x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp));
-      x87_fld (&G->f, x86_deref (G->r_eax));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 4));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 8));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 12));
-      x87_fmulp (&G->f, G->r_st4);
-      x87_fmulp (&G->f, G->r_st4);
-      x87_fmulp (&G->f, G->r_st4);
-      x87_fmulp (&G->f, G->r_st4);
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 12));
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 8));
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 4));
-      x87_fstp (&G->f, x86_deref (G->r_eax));
+      for (i = 0; i < 4; i++)
+         x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4));
+      for (i = 0; i < 4; i++)
+         x87_fmulp (&G->f, G->r_st4);
+      for (i = 0; i < 4; i++)
+         x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4));
       break;
    case slang_asm_vec4_divide:
       /* [vec4] | vec4 */
       x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, 16));
-      x87_fld (&G->f, x86_deref (G->r_eax));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 4));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 8));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 12));
-      x87_fld (&G->f, x86_deref (G->r_esp));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 4));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 8));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 12));
+      for (i = 0; i < 4; i++)
+         x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4));
+      for (i = 0; i < 4; i++)
+         x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4));
       x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16));
-      x87_fdivp (&G->f, G->r_st4);
-      x87_fdivp (&G->f, G->r_st4);
-      x87_fdivp (&G->f, G->r_st4);
-      x87_fdivp (&G->f, G->r_st4);
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 12));
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 8));
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 4));
-      x87_fstp (&G->f, x86_deref (G->r_eax));
+      for (i = 0; i < 4; i++)
+         x87_fdivp (&G->f, G->r_st4);
+      for (i = 0; i < 4; i++)
+         x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4));
       break;
    case slang_asm_vec4_negate:
       /* [vec4] */
       x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp));
-      x87_fld (&G->f, x86_deref (G->r_eax));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 4));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 8));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 12));
-      x87_fchs (&G->f);
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 12));
-      x87_fchs (&G->f);
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 8));
-      x87_fchs (&G->f);
-      x87_fstp (&G->f, x86_make_disp (G->r_eax, 4));
-      x87_fchs (&G->f);
-      x87_fstp (&G->f, x86_deref (G->r_eax));
+      for (i = 0; i < 4; i++)
+         x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4));
+      for (i = 0; i < 4; i++) {
+         x87_fchs (&G->f);
+         x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4));
+      }
       break;
    case slang_asm_vec4_dot:
       /* [vec4] | vec4 */
-      x87_fld (&G->f, x86_deref (G->r_esp));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 4));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 8));
-      x87_fld (&G->f, x86_make_disp (G->r_esp, 12));
+      for (i = 0; i < 4; i++)
+         x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4));
       x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16));
       x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp));
-      x87_fld (&G->f, x86_deref (G->r_eax));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 4));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 8));
-      x87_fld (&G->f, x86_make_disp (G->r_eax, 12));
-      x87_fmulp (&G->f, G->r_st4);
-      x87_fmulp (&G->f, G->r_st4);
-      x87_fmulp (&G->f, G->r_st4);
-      x87_fmulp (&G->f, G->r_st4);
-      x87_faddp (&G->f, G->r_st1);
-      x87_faddp (&G->f, G->r_st1);
-      x87_faddp (&G->f, G->r_st1);
+      for (i = 0; i < 4; i++)
+         x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4));
+      for (i = 0; i < 4; i++)
+         x87_fmulp (&G->f, G->r_st4);
+      for (i = 0; i < 3; i++)
+         x87_faddp (&G->f, G->r_st1);
       x87_fstp (&G->f, x86_deref (G->r_eax));
       break;
-       default:
-               assert (0);
-       }
+   case slang_asm_vec4_copy:
+      /* [vec4] | vec4 */
+      x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, a->param[0]));
+      x86_pop (&G->f, G->r_ecx);
+      x86_pop (&G->f, G->r_edx);
+      x86_mov (&G->f, x86_make_disp (G->r_eax, a->param[1]), G->r_ecx);
+      x86_pop (&G->f, G->r_ebx);
+      x86_mov (&G->f, x86_make_disp (G->r_eax, a->param[1] + 4), G->r_edx);
+      x86_pop (&G->f, G->r_ecx);
+      x86_mov (&G->f, x86_make_disp (G->r_eax, a->param[1] + 8), G->r_ebx);
+      x86_mov (&G->f, x86_make_disp (G->r_eax, a->param[1] + 12), G->r_ecx);
+      break;
+   case slang_asm_vec4_deref:
+      /* [vec4] */
+      x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp));
+      x86_mov (&G->f, G->r_ecx, x86_make_disp (G->r_eax, 12));
+      x86_mov (&G->f, G->r_edx, x86_make_disp (G->r_eax, 8));
+      x86_mov (&G->f, x86_deref (G->r_esp), G->r_ecx);
+      x86_mov (&G->f, G->r_ebx, x86_make_disp (G->r_eax, 4));
+      x86_push (&G->f, G->r_edx);
+      x86_mov (&G->f, G->r_ecx, x86_deref (G->r_eax));
+      x86_push (&G->f, G->r_ebx);
+      x86_push (&G->f, G->r_ecx);
+      break;
+   case slang_asm_vec4_equal_int:
+      x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, -4));
+      x86_mov_reg_imm (&G->f, G->r_edx, 0x4000);
+      for (i = 0; i < 4; i++) {
+         x87_fld (&G->f, x86_make_disp (G->r_esp, a->param[0] + 4 + i * 4));
+         x87_fcomp (&G->f, x86_make_disp (G->r_esp, a->param[1] + 4 + i * 4));
+         x87_fnstsw (&G->f, G->r_eax);
+         x86_and (&G->f, G->r_edx, G->r_eax);
+      }
+      /* TODO: use test r8,imm8 */
+      x86_mov_reg_imm (&G->f, G->r_ecx, 0x4000);
+      x86_test (&G->f, G->r_edx, G->r_ecx);
+      {
+         GLubyte *lab0, *lab1;
+
+         /* TODO: use jcc rel8 */
+         lab0 = x86_jcc_forward (&G->f, cc_E);
+         x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ONE);
+         /* TODO: use jmp rel8 */
+         lab1 = x86_jmp_forward (&G->f);
+         x86_fixup_fwd_jump (&G->f, lab0);
+         x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ZERO);
+         x86_fixup_fwd_jump (&G->f, lab1);
+         x86_mov (&G->f, x86_deref (G->r_esp), G->r_ecx);
+      }
+      break;
+   default:
+      assert (0);
+   }
 }
 
 GLboolean _slang_x86_codegen (slang_machine *mach, slang_assembly_file *file, GLuint start)
@@ -664,6 +670,7 @@ GLboolean _slang_x86_codegen (slang_machine *mach, slang_assembly_file *file, GL
        G.r_eax = x86_make_reg (file_REG32, reg_AX);
        G.r_ecx = x86_make_reg (file_REG32, reg_CX);
        G.r_edx = x86_make_reg (file_REG32, reg_DX);
+   G.r_ebx = x86_make_reg (file_REG32, reg_BX);
        G.r_esp = x86_make_reg (file_REG32, reg_SP);
        G.r_ebp = x86_make_reg (file_REG32, reg_BP);
        G.r_st0 = x86_make_reg (file_x87, 0);
index 34c62081f0509518690a60f5999b092727a40b83..6220b7c5bf6e2fe47fb09a28b1e15ed93960fd93 100644 (file)
@@ -211,14 +211,22 @@ GLboolean _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_sp
                return aggregate_vector (agg, slang_stor_float, 2);
        case slang_spec_vec3:
                return aggregate_vector (agg, slang_stor_float, 3);
-       case slang_spec_vec4:
-               return aggregate_vector (agg, slang_stor_float, 4);
+   case slang_spec_vec4:
+#if defined(USE_X86_ASM) || defined(SLANG_X86)
+      return aggregate_vector (agg, slang_stor_vec4, 1);
+#else
+      return aggregate_vector (agg, slang_stor_float, 4);
+#endif
        case slang_spec_mat2:
                return aggregate_matrix (agg, slang_stor_float, 2);
        case slang_spec_mat3:
                return aggregate_matrix (agg, slang_stor_float, 3);
-       case slang_spec_mat4:
-               return aggregate_matrix (agg, slang_stor_float, 4);
+   case slang_spec_mat4:
+#if defined(USE_X86_ASM) || defined(SLANG_X86)
+      return aggregate_vector (agg, slang_stor_vec4, 4);
+#else
+      return aggregate_matrix (agg, slang_stor_float, 4);
+#endif
        case slang_spec_sampler1D:
        case slang_spec_sampler2D:
        case slang_spec_sampler3D:
@@ -258,54 +266,77 @@ GLboolean _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_sp
        }
 }
 
-/* _slang_sizeof_aggregate() */
+/* _slang_sizeof_type() */
 
-GLuint _slang_sizeof_aggregate (const slang_storage_aggregate *agg)
+GLuint
+_slang_sizeof_type (slang_storage_type type)
 {
-       GLuint i, size = 0;
+   if (type == slang_stor_aggregate)
+      return 0;
+   if (type == slang_stor_vec4)
+      return 4 * sizeof (GLfloat);
+   return sizeof (GLfloat);
+}
 
-       for (i = 0; i < agg->count; i++)
-       {
-               GLuint element_size;
+/* _slang_sizeof_aggregate() */
 
-               if (agg->arrays[i].type == slang_stor_aggregate)
-                       element_size = _slang_sizeof_aggregate (agg->arrays[i].aggregate);
-               else
-                       element_size = sizeof (GLfloat);
-               size += element_size * agg->arrays[i].length;
-       }
-       return size;
+GLuint _slang_sizeof_aggregate (const slang_storage_aggregate *agg)
+{
+   GLuint i, size = 0;
+
+   for (i = 0; i < agg->count; i++) {
+      slang_storage_array *arr = &agg->arrays[i];
+      GLuint element_size;
+
+      if (arr->type == slang_stor_aggregate)
+         element_size = _slang_sizeof_aggregate (arr->aggregate);
+      else
+         element_size = _slang_sizeof_type (arr->type);
+      size += element_size * arr->length;
+   }
+   return size;
 }
 
 /* _slang_flatten_aggregate () */
 
-GLboolean _slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage_aggregate *agg)
+GLboolean
+_slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage_aggregate *agg)
 {
-       GLuint i;
-
-       for (i = 0; i < agg->count; i++)
-       {
-               GLuint j;
-
-               for (j = 0; j < agg->arrays[i].length; j++)
-               {
-                       if (agg->arrays[i].type == slang_stor_aggregate)
-                       {
-                               if (!_slang_flatten_aggregate (flat, agg->arrays[i].aggregate))
-                                       return GL_FALSE;
-                       }
-                       else
-                       {
-                               slang_storage_array *arr;
-
-                               arr = slang_storage_aggregate_push_new (flat);
-                               if (arr == NULL)
-                                       return GL_FALSE;
-                               arr->type = agg->arrays[i].type;
-                               arr->length = 1;
-                       }
-               }
-       }
-       return GL_TRUE;
+   GLuint i;
+
+   for (i = 0; i < agg->count; i++) {
+      GLuint j;
+
+      for (j = 0; j < agg->arrays[i].length; j++) {
+         if (agg->arrays[i].type == slang_stor_aggregate) {
+            if (!_slang_flatten_aggregate (flat, agg->arrays[i].aggregate))
+               return GL_FALSE;
+         }
+         else {
+            GLuint k, count;
+            slang_storage_type type;
+
+            if (agg->arrays[i].type == slang_stor_vec4) {
+               count = 4;
+               type = slang_stor_float;
+            }
+            else {
+               count = 1;
+               type = agg->arrays[i].type;
+            }
+
+            for (k = 0; k < count; k++) {
+               slang_storage_array *arr;
+
+               arr = slang_storage_aggregate_push_new (flat);
+               if (arr == NULL)
+                  return GL_FALSE;
+               arr->type = type;
+               arr->length = 1;
+            }
+         }
+      }
+   }
+   return GL_TRUE;
 }
 
index 532ea638ee7cbf58107e6582bdb66db8bebc86d7..209f8674d974ca0377a03cc0c0ede1bb5b8f2392 100644 (file)
@@ -41,13 +41,19 @@ extern "C" {
  *
  * For now, only the three basic types are supported, that is bool, int and float. Other built-in
  * types like vector or matrix can easily be decomposed into a series of basic types.
+ *
+ * If the vec4 module is enabled, 4-component vectors of floats are used when possible. 4x4 matrices
+ * are constructed of 4 vec4 slots.
  */
 typedef enum slang_storage_type_
 {
-       slang_stor_aggregate,
-       slang_stor_bool,
-       slang_stor_int,
-       slang_stor_float
+   /* core */
+   slang_stor_aggregate,
+   slang_stor_bool,
+   slang_stor_int,
+   slang_stor_float,
+   /* vec4 */
+   slang_stor_vec4
 } slang_storage_type;
 
 /*
@@ -105,6 +111,14 @@ _slang_evaluate_int(slang_assembly_file *file,
                     GLuint *pint,
                     slang_atom_pool *atoms);
 
+/*
+ * Returns the size (in machine units) of the given storage type.
+ * It is an error to pass-in slang_stor_aggregate.
+ * Returns 0 on error.
+ */
+extern GLuint
+_slang_sizeof_type (slang_storage_type);
+
 /*
  * Returns total size (in machine units) of the given aggregate.
  * Returns 0 on error.
index 6137aef8ecee7be5aafcf313fc6f72ce81003ca1..3ea37bb5e76137673d6b92ef91a70fcff7432bf0 100644 (file)
@@ -367,6 +367,20 @@ void x86_sub( struct x86_function *p,
    emit_op_modrm(p, 0x2b, 0x29, dst, src );
 }
 
+void x86_or( struct x86_function *p,
+             struct x86_reg dst,
+             struct x86_reg src )
+{
+   emit_op_modrm( p, 0x0b, 0x09, dst, src );
+}
+
+void x86_and( struct x86_function *p,
+              struct x86_reg dst,
+              struct x86_reg src )
+{
+   emit_op_modrm( p, 0x23, 0x21, dst, src );
+}
+
 
 
 /***********************************************************************
index 5ec5489431106dab30d93ae72d39da7edb94fcf6..66fb852ac98cc89d3008ffe741de2b48d86acc6c 100644 (file)
@@ -172,12 +172,14 @@ void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src
 void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, GLubyte shuf );
 
 void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
+void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
 void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
 void x86_dec( struct x86_function *p, struct x86_reg reg );
 void x86_inc( struct x86_function *p, struct x86_reg reg );
 void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
 void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
 void x86_mul( struct x86_function *p, struct x86_reg src );
+void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
 void x86_pop( struct x86_function *p, struct x86_reg reg );
 void x86_push( struct x86_function *p, struct x86_reg reg );
 void x86_ret( struct x86_function *p );