gallivm: Compensate for lp_const_offset in lp_build_conv.
authorJames Benton <jbenton@vmware.com>
Fri, 18 May 2012 15:04:49 +0000 (16:04 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Mon, 21 May 2012 19:24:46 +0000 (20:24 +0100)
Fixing a /*FIXME*/ to remove errors in integer conversion in lp_build_conv.
Tested using lp_test_conv and lp_test_format, reduced errors.

Signed-off-by: José Fonseca <jfonseca@vmware.com>
src/gallium/auxiliary/gallivm/lp_bld_conv.c

index f0ef5167351433ca78999024e3589362224c840f..9c7846031ec285a965ae070446cf679dda9469ba 100644 (file)
@@ -473,8 +473,23 @@ lp_build_conv(struct gallivm_state *gallivm,
    else {
       unsigned src_shift = lp_const_shift(src_type);
       unsigned dst_shift = lp_const_shift(dst_type);
+      unsigned src_offset = lp_const_offset(src_type);
+      unsigned dst_offset = lp_const_offset(dst_type);
+
+      /* Compensate for different offsets */
+      if (dst_offset > src_offset && src_type.width > dst_type.width) {
+         for (i = 0; i < num_tmps; ++i) {
+            LLVMValueRef shifted;
+            LLVMValueRef shift = lp_build_const_int_vec(gallivm, tmp_type, src_shift - 1);
+            if(src_type.sign)
+               shifted = LLVMBuildAShr(builder, tmp[i], shift, "");
+            else
+               shifted = LLVMBuildLShr(builder, tmp[i], shift, "");
+
+            tmp[i] = LLVMBuildSub(builder, tmp[i], shifted, "");
+         }
+      }
 
-      /* FIXME: compensate different offsets too */
       if(src_shift > dst_shift) {
          LLVMValueRef shift = lp_build_const_int_vec(gallivm, tmp_type,
                                                      src_shift - dst_shift);
@@ -554,12 +569,24 @@ lp_build_conv(struct gallivm_state *gallivm,
     else {
        unsigned src_shift = lp_const_shift(src_type);
        unsigned dst_shift = lp_const_shift(dst_type);
+       unsigned src_offset = lp_const_offset(src_type);
+       unsigned dst_offset = lp_const_offset(dst_type);
 
-       /* FIXME: compensate different offsets too */
-       if(src_shift < dst_shift) {
+       if (src_shift < dst_shift) {
+          LLVMValueRef pre_shift[LP_MAX_VECTOR_LENGTH];
           LLVMValueRef shift = lp_build_const_int_vec(gallivm, tmp_type, dst_shift - src_shift);
-          for(i = 0; i < num_tmps; ++i)
+
+          for (i = 0; i < num_tmps; ++i) {
+             pre_shift[i] = tmp[i];
              tmp[i] = LLVMBuildShl(builder, tmp[i], shift, "");
+          }
+
+          /* Compensate for different offsets */
+          if (dst_offset > src_offset) {
+             for (i = 0; i < num_tmps; ++i) {
+                tmp[i] = LLVMBuildSub(builder, tmp[i], pre_shift[i], "");
+             }
+          }
        }
     }