gallivm: add bitfield reverse and ufind_msb
authorDave Airlie <airlied@redhat.com>
Tue, 3 Dec 2019 05:54:56 +0000 (15:54 +1000)
committerDave Airlie <airlied@redhat.com>
Sun, 8 Dec 2019 20:05:02 +0000 (06:05 +1000)
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Reviewed-by: Krzysztof Raszkowski <krzysztof.raszkowski@intel.com>
src/gallium/auxiliary/gallivm/lp_bld_bitarit.c
src/gallium/auxiliary/gallivm/lp_bld_bitarit.h
src/gallium/auxiliary/gallivm/lp_bld_nir.c

index c717b988f27439f722245c416b48cd7f988c97e4..eee3cba2fb5ece6ba137c82baf696162335d719b 100644 (file)
@@ -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;
+}
index 989ce5ca568e1f09dc9997ee64ff484916f0a4dc..ae85ea4b16d1efb46060dad3831a1fd2174631f6 100644 (file)
@@ -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 */
index e13ec4e1a192c70f59891604790ec2ecf7f7b4ab..197e4118d0dbd1776182c38cf81741f123e431f7 100644 (file)
@@ -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;