From: Dave Airlie Date: Tue, 3 Dec 2019 05:54:56 +0000 (+1000) Subject: gallivm: add bitfield reverse and ufind_msb X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d7dc14628a96989d9bf317f4c64540b41dee48cb;p=mesa.git gallivm: add bitfield reverse and ufind_msb Reviewed-by: Roland Scheidegger Reviewed-by: Krzysztof Raszkowski --- diff --git a/src/gallium/auxiliary/gallivm/lp_bld_bitarit.c b/src/gallium/auxiliary/gallivm/lp_bld_bitarit.c index c717b988f27..eee3cba2fb5 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_bitarit.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_bitarit.c @@ -253,6 +253,18 @@ lp_build_popcount(struct lp_build_context *bld, LLVMValueRef a) return result; } +LLVMValueRef +lp_build_bitfield_reverse(struct lp_build_context *bld, LLVMValueRef a) +{ + LLVMBuilderRef builder = bld->gallivm->builder; + LLVMValueRef result; + char intr_str[256]; + + lp_format_intrinsic(intr_str, sizeof(intr_str), "llvm.bitreverse", bld->vec_type); + result = lp_build_intrinsic_unary(builder, intr_str, bld->vec_type, a); + return result; +} + LLVMValueRef lp_build_cttz(struct lp_build_context *bld, LLVMValueRef a) { @@ -266,3 +278,17 @@ lp_build_cttz(struct lp_build_context *bld, LLVMValueRef a) result = lp_build_intrinsic_binary(builder, intr_str, bld->vec_type, a, undef_val); return result; } + +LLVMValueRef +lp_build_ctlz(struct lp_build_context *bld, LLVMValueRef a) +{ + LLVMBuilderRef builder = bld->gallivm->builder; + LLVMValueRef result; + char intr_str[256]; + + lp_format_intrinsic(intr_str, sizeof(intr_str), "llvm.ctlz", bld->vec_type); + + LLVMValueRef undef_val = LLVMConstNull(LLVMInt1TypeInContext(bld->gallivm->context)); + result = lp_build_intrinsic_binary(builder, intr_str, bld->vec_type, a, undef_val); + return result; +} diff --git a/src/gallium/auxiliary/gallivm/lp_bld_bitarit.h b/src/gallium/auxiliary/gallivm/lp_bld_bitarit.h index 989ce5ca568..ae85ea4b16d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_bitarit.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_bitarit.h @@ -74,6 +74,12 @@ lp_build_not(struct lp_build_context *bld, LLVMValueRef a); LLVMValueRef lp_build_popcount(struct lp_build_context *bld, LLVMValueRef a); +LLVMValueRef +lp_build_bitfield_reverse(struct lp_build_context *bld, LLVMValueRef a); + LLVMValueRef lp_build_cttz(struct lp_build_context *bld, LLVMValueRef a); + +LLVMValueRef +lp_build_ctlz(struct lp_build_context *bld, LLVMValueRef a); #endif /* !LP_BLD_ARIT_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir.c b/src/gallium/auxiliary/gallivm/lp_bld_nir.c index e13ec4e1a19..197e4118d0d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir.c @@ -406,6 +406,9 @@ static LLVMValueRef do_alu_action(struct lp_build_nir_context *bld_base, case nir_op_bitfield_select: result = lp_build_xor(&bld_base->uint_bld, src[2], lp_build_and(&bld_base->uint_bld, src[0], lp_build_xor(&bld_base->uint_bld, src[1], src[2]))); break; + case nir_op_bitfield_reverse: + result = lp_build_bitfield_reverse(get_int_bld(bld_base, false, src_bit_size[0]), src[0]); + break; case nir_op_f2b32: result = flt_to_bool32(bld_base, src_bit_size[0], src[0]); break; @@ -653,6 +656,12 @@ static LLVMValueRef do_alu_action(struct lp_build_nir_context *bld_base, result = lp_build_div(&bld_base->uint_bld, src[0], src[1]); break; + case nir_op_ufind_msb: { + struct lp_build_context *uint_bld = get_int_bld(bld_base, true, src_bit_size[0]); + result = lp_build_ctlz(uint_bld, src[0]); + result = lp_build_sub(uint_bld, lp_build_const_int_vec(gallivm, uint_bld->type, src_bit_size[0] - 1), result); + break; + } case nir_op_uge32: result = icmp32(bld_base, PIPE_FUNC_GEQUAL, true, src_bit_size[0], src); break;