From c75421ebecb71e1aebed9a642e2febf0b4277173 Mon Sep 17 00:00:00 2001
From: nobled <nobled@dreamwidth.org>
Date: Mon, 9 Aug 2010 21:25:18 +0000
Subject: [PATCH] gallivm: Fix bitwise operations for floats, division for integers

http://bugs.freedesktop.org/29407
---
 src/gallium/auxiliary/gallivm/lp_bld_arit.c  |   17 ++++++++++++++---
 src/gallium/auxiliary/gallivm/lp_bld_logic.c |   11 +++++++++++
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
index 860fbd8..e7ec985 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
@@ -588,13 +588,24 @@ lp_build_div(struct lp_build_context *bld,
    if(a == bld->undef || b == bld->undef)
       return bld->undef;
 
-   if(LLVMIsConstant(a) && LLVMIsConstant(b))
-      return LLVMConstFDiv(a, b);
+   if(LLVMIsConstant(a) && LLVMIsConstant(b)) {
+      if (type.floating)
+         return LLVMConstFDiv(a, b);
+      else if (type.sign)
+         return LLVMConstSDiv(a, b);
+      else
+         return LLVMConstUDiv(a, b);
+   }
 
    if(util_cpu_caps.has_sse && type.width == 32 && type.length == 4)
       return lp_build_mul(bld, a, lp_build_rcp(bld, b));
 
-   return LLVMBuildFDiv(bld->builder, a, b, "");
+   if (type.floating)
+      return LLVMBuildFDiv(bld->builder, a, b);
+   else if (type.sign)
+      return LLVMBuildSDiv(bld->builder, a, b);
+   else
+      return LLVMBuildUDiv(bld->builder, a, b);
 }
 
 
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.c b/src/gallium/auxiliary/gallivm/lp_bld_logic.c
index 96f8e21..3a7ee35 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_logic.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.c
@@ -553,8 +553,19 @@ lp_build_andc(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
    assert(lp_check_value(bld->type, a));
    assert(lp_check_value(bld->type, b));
 
+   /* can't do bitwise ops on floating-point values */
+   if(type.floating) {
+      LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+      a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
+      b = LLVMBuildBitCast(bld->builder, b, int_vec_type, "");
+   }
+
    b = LLVMBuildNot(bld->builder, b, "");
    b = LLVMBuildAnd(bld->builder, a, b, "");
 
+   if(type.floating) {
+      LLVMTypeRef vec_type = lp_build_vec_type(type);
+      b = LLVMBuildBitCast(bld->builder, b, vec_type, "");
+   }
    return b;
 }
-- 
1.5.4.3