diff options
| author | gingerBill <bill@gingerbill.org> | 2024-08-30 10:48:21 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2024-08-30 10:48:21 +0100 |
| commit | 38ea276231cba6860ac013ffb338b96afb6cd2fa (patch) | |
| tree | abbbcbb1ecb30fd3c4683b33adec865f34b38a07 /src/llvm_backend_expr.cpp | |
| parent | b020b91df2aa86ea3a1500ce0ce459035d26c140 (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.cpp | 12 |
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); } |