summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/gallivm/lp_bld_arit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/gallivm/lp_bld_arit.c')
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_arit.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
index bbce31f9eb..32f9e5201c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
@@ -669,6 +669,14 @@ lp_build_abs(struct lp_build_context *bld,
LLVMValueRef
+lp_build_negate(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ return LLVMBuildNeg(bld->builder, a, "");
+}
+
+
+LLVMValueRef
lp_build_sgn(struct lp_build_context *bld,
LLVMValueRef a)
{
@@ -710,6 +718,41 @@ lp_build_sgn(struct lp_build_context *bld,
/**
+ * Set the sign of float vector 'a' according to 'sign'.
+ * If sign==0, return abs(a).
+ * If sign==1, return -abs(a);
+ * Other values for sign produce undefined results.
+ */
+LLVMValueRef
+lp_build_set_sign(struct lp_build_context *bld,
+ LLVMValueRef a, LLVMValueRef sign)
+{
+ const struct lp_type type = bld->type;
+ LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
+ LLVMValueRef shift = lp_build_int_const_scalar(type, type.width - 1);
+ LLVMValueRef mask = lp_build_int_const_scalar(type,
+ ~((unsigned long long) 1 << (type.width - 1)));
+ LLVMValueRef val, res;
+
+ assert(type.floating);
+
+ /* val = reinterpret_cast<int>(a) */
+ val = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
+ /* val = val & mask */
+ val = LLVMBuildAnd(bld->builder, val, mask, "");
+ /* sign = sign << shift */
+ sign = LLVMBuildShl(bld->builder, sign, shift, "");
+ /* res = val | sign */
+ res = LLVMBuildOr(bld->builder, val, sign, "");
+ /* res = reinterpret_cast<float>(res) */
+ res = LLVMBuildBitCast(bld->builder, res, vec_type, "");
+
+ return res;
+}
+
+
+/**
* Convert vector of int to vector of float.
*/
LLVMValueRef
@@ -857,6 +900,19 @@ lp_build_ceil(struct lp_build_context *bld,
/**
+ * Return fractional part of 'a' computed as a - floor(f)
+ * Typically used in texture coord arithmetic.
+ */
+LLVMValueRef
+lp_build_fract(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ assert(bld->type.floating);
+ return lp_build_sub(bld, a, lp_build_floor(bld, a));
+}
+
+
+/**
* Convert to integer, through whichever rounding method that's fastest,
* typically truncating toward zero.
*/