Browse Source

Added simd_extract_lsbs intrinsic as well.

Equivalent to the simd_extract_msbs intrinsic, except it extracts the
least significant bit of each element instead.
Barinzaya 5 months ago
parent
commit
4afedbc051

+ 1 - 0
base/intrinsics/intrinsics.odin

@@ -285,6 +285,7 @@ simd_reduce_xor         :: proc(a: #simd[N]T) -> T where type_is_integer(T) || t
 simd_reduce_any         :: proc(a: #simd[N]T) -> T where type_is_boolean(T) ---
 simd_reduce_all         :: proc(a: #simd[N]T) -> T where type_is_boolean(T) ---
 
+simd_extract_lsbs       :: proc(a: #simd[N]T) -> bit_set[0..<N] where type_is_integer(T) || type_is_boolean(T) ---
 simd_extract_msbs       :: proc(a: #simd[N]T) -> bit_set[0..<N] where type_is_integer(T) || type_is_boolean(T) ---
 
 

+ 1 - 0
core/simd/simd.odin

@@ -135,6 +135,7 @@ reduce_xor         :: intrinsics.simd_reduce_xor
 reduce_any         :: intrinsics.simd_reduce_any
 reduce_all         :: intrinsics.simd_reduce_all
 
+extract_lsbs       :: intrinsics.simd_extract_lsbs
 extract_msbs       :: intrinsics.simd_extract_msbs
 
 // swizzle :: proc(a: #simd[N]T, indices: ..int) -> #simd[len(indices)]T

+ 1 - 0
src/check_builtin.cpp

@@ -888,6 +888,7 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
 			return true;
 		}
 
+	case BuiltinProc_simd_extract_lsbs:
 	case BuiltinProc_simd_extract_msbs:
 		{
 			Operand x = {};

+ 2 - 0
src/checker_builtin_procs.hpp

@@ -181,6 +181,7 @@ BuiltinProc__simd_begin,
 	BuiltinProc_simd_reduce_any,
 	BuiltinProc_simd_reduce_all,
 
+	BuiltinProc_simd_extract_lsbs,
 	BuiltinProc_simd_extract_msbs,
 
 	BuiltinProc_simd_shuffle,
@@ -525,6 +526,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
 	{STR_LIT("simd_reduce_any"),          1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
 	{STR_LIT("simd_reduce_all"),         1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
 
+	{STR_LIT("simd_extract_lsbs"),       1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
 	{STR_LIT("simd_extract_msbs"),       1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
 
 

+ 7 - 3
src/llvm_backend_proc.cpp

@@ -1564,6 +1564,7 @@ gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAn
 			return res;
 		}
 
+	case BuiltinProc_simd_extract_lsbs:
 	case BuiltinProc_simd_extract_msbs:
 		{
 			Type *vt = arg0.type;
@@ -1572,9 +1573,12 @@ gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAn
 			i64 elem_bits = 8*type_size_of(elem);
 			i64 num_elems = get_array_type_count(vt);
 
-			LLVMTypeRef word_type = lb_type(m, elem);
-			LLVMValueRef shift_value = llvm_splat_int(num_elems, word_type, elem_bits - 1);
-			LLVMValueRef broadcast_value = LLVMBuildAShr(p->builder, arg0.value, shift_value, "");
+			LLVMValueRef broadcast_value = arg0.value;
+			if (builtin_id == BuiltinProc_simd_extract_msbs) {
+				LLVMTypeRef word_type = lb_type(m, elem);
+				LLVMValueRef shift_value = llvm_splat_int(num_elems, word_type, elem_bits - 1);
+				broadcast_value = LLVMBuildAShr(p->builder, broadcast_value, shift_value, "");
+			}
 
 			LLVMTypeRef bitvec_type = LLVMVectorType(LLVMInt1TypeInContext(m->ctx), (unsigned)num_elems);
 			LLVMValueRef bitvec_value = LLVMBuildTrunc(p->builder, broadcast_value, bitvec_type, "");