aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2026-02-02 14:28:16 +0000
committergingerBill <gingerBill@users.noreply.github.com>2026-02-02 14:28:16 +0000
commitbb7496a2fcc58238a4e3abcc431313385a15183f (patch)
tree1bced935d1c3ad3b74dc530cc60d95a103b0db28 /src
parent80c948277455eb9deaf79ac910fdc8957038fb75 (diff)
Add `intrinsics.count_trailing_ones` and `intrinsics.count_leading_ones`
Diffstat (limited to 'src')
-rw-r--r--src/check_builtin.cpp23
-rw-r--r--src/checker_builtin_procs.hpp4
-rw-r--r--src/llvm_backend_proc.cpp6
-rw-r--r--src/llvm_backend_utility.cpp12
4 files changed, 45 insertions, 0 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp
index e2428576e..1a094c1f0 100644
--- a/src/check_builtin.cpp
+++ b/src/check_builtin.cpp
@@ -5204,6 +5204,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
case BuiltinProc_count_zeros:
case BuiltinProc_count_trailing_zeros:
case BuiltinProc_count_leading_zeros:
+ case BuiltinProc_count_trailing_ones:
+ case BuiltinProc_count_leading_ones:
case BuiltinProc_reverse_bits:
{
Operand x = {};
@@ -5301,6 +5303,27 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
v += 1;
}
break;
+
+ case BuiltinProc_count_trailing_ones:
+ for (u64 i = 0; i < bit_size; i++) {
+ u8 b = cast(u8)(i & 7);
+ u8 j = cast(u8)(i >> 3);
+ if ((rop[j] & (1 << b)) == 0) {
+ break;
+ }
+ v += 1;
+ }
+ break;
+ case BuiltinProc_count_leading_ones:
+ for (u64 i = bit_size-1; i < bit_size; i--) {
+ u8 b = cast(u8)(i & 7);
+ u8 j = cast(u8)(i >> 3);
+ if ((rop[j] & (1 << b)) == 0) {
+ break;
+ }
+ v += 1;
+ }
+ break;
}
diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp
index 5b446cc1c..a13ffc3cd 100644
--- a/src/checker_builtin_procs.hpp
+++ b/src/checker_builtin_procs.hpp
@@ -74,6 +74,8 @@ enum BuiltinProcId {
BuiltinProc_count_zeros,
BuiltinProc_count_trailing_zeros,
BuiltinProc_count_leading_zeros,
+ BuiltinProc_count_trailing_ones,
+ BuiltinProc_count_leading_ones,
BuiltinProc_reverse_bits,
BuiltinProc_byte_swap,
@@ -453,6 +455,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
{STR_LIT("count_zeros"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("count_trailing_zeros"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("count_leading_zeros"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
+ {STR_LIT("count_trailing_ones"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
+ {STR_LIT("count_leading_ones"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("reverse_bits"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("byte_swap"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index b596f15ef..e52e91f75 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -2850,6 +2850,12 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
case BuiltinProc_count_leading_zeros:
return lb_emit_count_leading_zeros(p, lb_build_expr(p, ce->args[0]), tv.type);
+ case BuiltinProc_count_trailing_ones:
+ return lb_emit_count_trailing_ones(p, lb_build_expr(p, ce->args[0]), tv.type);
+ case BuiltinProc_count_leading_ones:
+ return lb_emit_count_leading_ones(p, lb_build_expr(p, ce->args[0]), tv.type);
+
+
case BuiltinProc_count_ones:
return lb_emit_count_ones(p, lb_build_expr(p, ce->args[0]), tv.type);
case BuiltinProc_count_zeros:
diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp
index 367e7be75..8a7bced59 100644
--- a/src/llvm_backend_utility.cpp
+++ b/src/llvm_backend_utility.cpp
@@ -648,6 +648,18 @@ gb_internal lbValue lb_emit_count_leading_zeros(lbProcedure *p, lbValue x, Type
return res;
}
+gb_internal lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x, Type *type);
+
+gb_internal lbValue lb_emit_count_trailing_ones(lbProcedure *p, lbValue x, Type *type) {
+ lbValue z = lb_emit_unary_arith(p, Token_Xor, x, type);
+ return lb_emit_count_trailing_zeros(p, z, type);
+}
+
+gb_internal lbValue lb_emit_count_leading_ones(lbProcedure *p, lbValue x, Type *type) {
+ lbValue z = lb_emit_unary_arith(p, Token_Xor, x, type);
+ return lb_emit_count_leading_zeros(p, z, type);
+}
+
gb_internal lbValue lb_emit_reverse_bits(lbProcedure *p, lbValue x, Type *type) {