Mesa (master): gallivm: Fast implementation of iround(log2(x))

Jose Fonseca jrfonseca at kemper.freedesktop.org
Wed Oct 6 18:06:25 UTC 2010


Module: Mesa
Branch: master
Commit: 012d57737b1b4e4263aa3414abe433195ff8a713
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=012d57737b1b4e4263aa3414abe433195ff8a713

Author: José Fonseca <jfonseca at vmware.com>
Date:   Wed Oct  6 17:44:05 2010 +0100

gallivm: Fast implementation of iround(log2(x))

Not tested yet, but should be correct.

---

 src/gallium/auxiliary/gallivm/lp_bld_arit.c |   35 +++++++++++++++++++++++++++
 src/gallium/auxiliary/gallivm/lp_bld_arit.h |    4 +++
 2 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
index ff94f49..15b7441 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
@@ -2330,3 +2330,38 @@ lp_build_fast_log2(struct lp_build_context *bld,
    /* floor(log2(x)) + frac(x) */
    return LLVMBuildFAdd(bld->builder, ipart, fpart, "");
 }
+
+
+/**
+ * Fast implementation of iround(log2(x)).
+ *
+ * Not an approximation -- it should give accurate results all the time.
+ */
+LLVMValueRef
+lp_build_ilog2(struct lp_build_context *bld,
+               LLVMValueRef x)
+{
+   const struct lp_type type = bld->type;
+   LLVMTypeRef int_vec_type = bld->int_vec_type;
+
+   unsigned mantissa = lp_mantissa(type);
+   LLVMValueRef sqrt2 = lp_build_const_vec(type, 1.4142135623730951);
+
+   LLVMValueRef ipart;
+
+   assert(lp_check_value(bld->type, x));
+
+   assert(type.floating);
+
+   /* x * 2^(0.5)   i.e., add 0.5 to the log2(x) */
+   x = LLVMBuildFMul(bld->builder, x, sqrt2, "");
+
+   x = LLVMBuildBitCast(bld->builder, x, int_vec_type, "");
+
+   /* ipart = floor(log2(x) + 0.5)  */
+   ipart = LLVMBuildLShr(bld->builder, x, lp_build_const_int_vec(type, mantissa), "");
+   ipart = LLVMBuildAnd(bld->builder, ipart, lp_build_const_int_vec(type, 255), "");
+   ipart = LLVMBuildSub(bld->builder, ipart, lp_build_const_int_vec(type, 127), "");
+
+   return ipart;
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.h b/src/gallium/auxiliary/gallivm/lp_bld_arit.h
index 3ed4fec..f361974 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.h
@@ -216,6 +216,10 @@ LLVMValueRef
 lp_build_fast_log2(struct lp_build_context *bld,
                    LLVMValueRef a);
 
+LLVMValueRef
+lp_build_ilog2(struct lp_build_context *bld,
+               LLVMValueRef x);
+
 
 void
 lp_build_exp2_approx(struct lp_build_context *bld,




More information about the mesa-commit mailing list