aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-07-16 18:03:43 +0100
committergingerBill <bill@gingerbill.org>2022-07-16 18:03:43 +0100
commiteafa5098aa5fd10554f3348acba5ac6164a4b83e (patch)
tree8f4ab70cd89b3bf9067c249a856ac981957adc86 /src
parent0571b80d3725a815562f1bc0937743046301d955 (diff)
Fix #1883
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.cpp35
-rw-r--r--src/llvm_backend_const.cpp23
2 files changed, 32 insertions, 26 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 13d6badbe..721b5a5af 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -8404,23 +8404,30 @@ ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *node, Type *
if (is_type_bit_set(type)) {
// NOTE(bill): Encode as an integer
- i64 lower = base_type(type)->BitSet.lower;
+ Type *bt = base_type(type);
+ BigInt bits = {};
+ BigInt one = {};
+ big_int_from_u64(&one, 1);
- u64 bits = 0;
- for_array(index, cl->elems) {
- Ast *elem = cl->elems[index];
- GB_ASSERT(elem->kind != Ast_FieldValue);
- TypeAndValue tav = elem->tav;
- ExactValue i = exact_value_to_integer(tav.value);
- if (i.kind != ExactValue_Integer) {
+ for_array(i, cl->elems) {
+ Ast *e = cl->elems[i];
+ GB_ASSERT(e->kind != Ast_FieldValue);
+
+ TypeAndValue tav = e->tav;
+ if (tav.mode != Addressing_Constant) {
continue;
}
- i64 val = big_int_to_i64(&i.value_integer);
- val -= lower;
- u64 bit = u64(1ll<<val);
- bits |= bit;
- }
- o->value = exact_value_u64(bits);
+ GB_ASSERT(tav.value.kind == ExactValue_Integer);
+ i64 v = big_int_to_i64(&tav.value.value_integer);
+ i64 lower = bt->BitSet.lower;
+ u64 index = cast(u64)(v-lower);
+ BigInt bit = {};
+ big_int_from_u64(&bit, index);
+ big_int_shl(&bit, &one, &bit);
+ big_int_or(&bits, &bits, &bit);
+ }
+ o->value.kind = ExactValue_Integer;
+ o->value.value_integer = bits;
} else if (is_type_constant_type(type) && cl->elems.count == 0) {
ExactValue value = exact_value_compound(node);
Type *bt = core_type(type);
diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp
index 00452eb50..24b2bc3a2 100644
--- a/src/llvm_backend_const.cpp
+++ b/src/llvm_backend_const.cpp
@@ -1025,7 +1025,10 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
return lb_const_nil(m, original_type);
}
- u64 bits = 0;
+ BigInt bits = {};
+ BigInt one = {};
+ big_int_from_u64(&one, 1);
+
for_array(i, cl->elems) {
Ast *e = cl->elems[i];
GB_ASSERT(e->kind != Ast_FieldValue);
@@ -1037,18 +1040,14 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
GB_ASSERT(tav.value.kind == ExactValue_Integer);
i64 v = big_int_to_i64(&tav.value.value_integer);
i64 lower = type->BitSet.lower;
- bits |= 1ull<<cast(u64)(v-lower);
- }
- if (is_type_different_to_arch_endianness(type)) {
- i64 size = type_size_of(type);
- switch (size) {
- case 2: bits = cast(u64)gb_endian_swap16(cast(u16)bits); break;
- case 4: bits = cast(u64)gb_endian_swap32(cast(u32)bits); break;
- case 8: bits = cast(u64)gb_endian_swap64(cast(u64)bits); break;
- }
+ u64 index = cast(u64)(v-lower);
+ gb_printf_err("index: %llu\n", index);
+ BigInt bit = {};
+ big_int_from_u64(&bit, index);
+ big_int_shl(&bit, &one, &bit);
+ big_int_or(&bits, &bits, &bit);
}
-
- res.value = LLVMConstInt(lb_type(m, original_type), bits, false);
+ res.value = lb_big_int_to_llvm(m, original_type, &bits);
return res;
} else if (is_type_matrix(type)) {
ast_node(cl, CompoundLit, value.value_compound);