diff options
| author | Brian Paul <brianp@vmware.com> | 2010-03-04 09:45:34 -0700 | 
|---|---|---|
| committer | Brian Paul <brianp@vmware.com> | 2010-03-04 10:53:26 -0700 | 
| commit | 6464d81e779e8c05ef96c9e5dab4422ff1f25464 (patch) | |
| tree | 8df16f6ade2f0e5ba27ba3d0b88012976fe08ee9 | |
| parent | 7d230dae70e8caa67cc6bd7501f892d44c40a5d4 (diff) | |
gallivm: added lp_build_set_sign()
| -rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_arit.c | 35 | ||||
| -rw-r--r-- | 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 f60a7a213a..42ae9f6a22 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c @@ -718,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 diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.h b/src/gallium/auxiliary/gallivm/lp_bld_arit.h index 2d19ec06b4..866349d8cb 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_arit.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.h @@ -125,6 +125,10 @@ lp_build_sgn(struct lp_build_context *bld,               LLVMValueRef a);  LLVMValueRef +lp_build_set_sign(struct lp_build_context *bld, +                  LLVMValueRef a, LLVMValueRef sign); + +LLVMValueRef  lp_build_int_to_float(struct lp_build_context *bld,                        LLVMValueRef a);  | 
