aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_expr.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2024-08-30 10:48:21 +0100
committergingerBill <bill@gingerbill.org>2024-08-30 10:48:21 +0100
commit38ea276231cba6860ac013ffb338b96afb6cd2fa (patch)
treeabbbcbb1ecb30fd3c4683b33adec865f34b38a07 /src/llvm_backend_expr.cpp
parentb020b91df2aa86ea3a1500ce0ce459035d26c140 (diff)
Make `~some_bit_set` work on only the possible bits by doing a mask with the full set
Diffstat (limited to 'src/llvm_backend_expr.cpp')
-rw-r--r--src/llvm_backend_expr.cpp12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp
index c2707612a..b10b7745a 100644
--- a/src/llvm_backend_expr.cpp
+++ b/src/llvm_backend_expr.cpp
@@ -136,6 +136,11 @@ gb_internal lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x,
switch (op) {
case Token_Xor:
opv = LLVMBuildNot(p->builder, v, "");
+ if (is_type_bit_set(elem_type)) {
+ ExactValue ev_mask = exact_bit_set_all_set_mask(elem_type);
+ lbValue mask = lb_const_value(p->module, elem_type, ev_mask);
+ opv = LLVMBuildAnd(p->builder, opv, mask.value, "");
+ }
break;
case Token_Sub:
if (is_type_float(elem_type)) {
@@ -176,8 +181,13 @@ gb_internal lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x,
if (op == Token_Xor) {
lbValue cmp = {};
- cmp.value = LLVMBuildNot(p->builder, x.value, "");
cmp.type = x.type;
+ cmp.value = LLVMBuildNot(p->builder, x.value, "");
+ if (is_type_bit_set(x.type)) {
+ ExactValue ev_mask = exact_bit_set_all_set_mask(x.type);
+ lbValue mask = lb_const_value(p->module, x.type, ev_mask);
+ cmp.value = LLVMBuildAnd(p->builder, cmp.value, mask.value, "");
+ }
return lb_emit_conv(p, cmp, type);
}