From 460e14e5860a503b8e7716ce18a29eb99f517cf7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 11 Jul 2021 16:08:16 +0100 Subject: Change the compiler's big integer library to use libTomMath This now replaces Bill's crappy big int implementation --- src/check_expr.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'src/check_expr.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 54d610c0f..2e552ee79 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1503,13 +1503,13 @@ bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Typ big_int_from_i64(&bi127, 127); big_int_shl_eq(&umax, &bi128); - big_int_sub_eq(&umax, &BIG_INT_ONE); + mp_decr(&umax); big_int_shl_eq(&imin, &bi127); big_int_neg(&imin, &imin); big_int_shl_eq(&imax, &bi127); - big_int_sub_eq(&imax, &BIG_INT_ONE); + mp_decr(&imax); } switch (type->Basic.kind) { @@ -1555,7 +1555,7 @@ bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Typ { // return 0ull <= i && i <= umax; int b = big_int_cmp(&i, &umax); - return !i.neg && (b <= 0); + return !i.sign && (b <= 0); } case Basic_UntypedInteger: @@ -1758,12 +1758,6 @@ void check_is_expressible(CheckerContext *ctx, Operand *o, Type *type) { if (!is_type_integer(o->type) && is_type_integer(type)) { error(o->expr, "'%s' truncated to '%s'", a, b); } else { - #if 0 - gb_printf_err("AddressingMode, %d\n", o->mode); - gb_printf_err("ExactValueKind, %d\n", o->value.kind); - bool ok = check_representable_as_constant(ctx, o->value, type, &out_value); - gb_printf_err("ok, %d\n", ok); - #endif error(o->expr, "Cannot convert numeric value '%s' to '%s' from '%s", a, b, c); check_assignment_error_suggestion(ctx, o, type); } @@ -2206,7 +2200,7 @@ void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *node, Type *typ } BigInt max_shift = {}; - big_int_from_u64(&max_shift, 128); + big_int_from_u64(&max_shift, MAX_BIG_INT_SHIFT); if (big_int_cmp(&y_val.value_integer, &max_shift) > 0) { gbString err_str = expr_to_string(y->expr); @@ -2248,7 +2242,7 @@ void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *node, Type *typ } } - if (y->mode == Addressing_Constant && y->value.value_integer.neg) { + if (y->mode == Addressing_Constant && y->value.value_integer.sign) { gbString err_str = expr_to_string(y->expr); error(node, "Shift amount cannot be negative: '%s'", err_str); gb_string_free(err_str); @@ -3320,7 +3314,7 @@ bool check_index_value(CheckerContext *c, bool open_range, Ast *index_value, i64 if (operand.mode == Addressing_Constant && (c->state_flags & StateFlag_no_bounds_check) == 0) { BigInt i = exact_value_to_integer(operand.value).value_integer; - if (i.neg && !is_type_enum(index_type)) { + if (i.sign && !is_type_enum(index_type)) { gbString expr_str = expr_to_string(operand.expr); error(operand.expr, "Index '%s' cannot be a negative value", expr_str); gb_string_free(expr_str); @@ -3366,7 +3360,7 @@ bool check_index_value(CheckerContext *c, bool open_range, Ast *index_value, i64 } else { // NOTE(bill): Do array bound checking i64 v = -1; - if (i.len <= 1) { + if (i.used <= 1) { v = big_int_to_i64(&i); } if (value) *value = v; -- cgit v1.2.3 From 63b572a0abd9fb3b64b4b70b3f94dbafb4642f57 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 11 Jul 2021 16:18:30 +0100 Subject: Clean up big int to LLVM integer code --- src/big_int.cpp | 9 +++++ src/check_builtin.cpp | 6 ++-- src/check_expr.cpp | 2 +- src/check_type.cpp | 2 +- src/llvm_backend.cpp | 97 ++++++++++++++++++--------------------------------- 5 files changed, 48 insertions(+), 68 deletions(-) (limited to 'src/check_expr.cpp') diff --git a/src/big_int.cpp b/src/big_int.cpp index 74683ef63..9ed753753 100644 --- a/src/big_int.cpp +++ b/src/big_int.cpp @@ -55,6 +55,8 @@ void big_int_mul_eq(BigInt *dst, BigInt const *x); void big_int_quo_eq(BigInt *dst, BigInt const *x); void big_int_rem_eq(BigInt *dst, BigInt const *x); +bool big_int_is_neg(BigInt const *x); + void big_int_add_eq(BigInt *dst, BigInt const *x) { BigInt res = {}; @@ -450,6 +452,13 @@ void big_int_not(BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed) { big_int_dealloc(&v); } +bool big_int_is_neg(BigInt const *x) { + if (x == nullptr) { + return false; + } + return x->sign != MP_ZPOS; +} + char digit_to_char(u8 digit) { GB_ASSERT(digit < 16); diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 3beaba2e8..3c692b601 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -745,7 +745,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 return false; } - if (op.value.value_integer.sign) { + if (big_int_is_neg(&op.value.value_integer)) { error(op.expr, "Negative 'swizzle' index"); return false; } @@ -1843,7 +1843,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 operand->type = t_invalid; return false; } - if (x.value.value_integer.sign) { + if (big_int_is_neg(&x.value.value_integer)) { error(call, "Negative vector element length"); operand->mode = Addressing_Type; operand->type = t_invalid; @@ -1883,7 +1883,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 operand->type = t_invalid; return false; } - if (x.value.value_integer.sign) { + if (big_int_is_neg(&x.value.value_integer)) { error(call, "Negative array element length"); operand->mode = Addressing_Type; operand->type = t_invalid; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 2e552ee79..e3e73c391 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -2242,7 +2242,7 @@ void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *node, Type *typ } } - if (y->mode == Addressing_Constant && y->value.value_integer.sign) { + if (y->mode == Addressing_Constant && big_int_is_neg(&y->value.value_integer)) { gbString err_str = expr_to_string(y->expr); error(node, "Shift amount cannot be negative: '%s'", err_str); gb_string_free(err_str); diff --git a/src/check_type.cpp b/src/check_type.cpp index e8000d66c..4b4df4f3a 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1998,7 +1998,7 @@ i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) { if (is_type_untyped(type) || is_type_integer(type)) { if (o->value.kind == ExactValue_Integer) { BigInt count = o->value.value_integer; - if (o->value.value_integer.sign) { + if (big_int_is_neg(&o->value.value_integer)) { gbAllocator a = heap_allocator(); String str = big_int_to_string(a, &count); error(e, "Invalid negative array count, %.*s", LIT(str)); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index fa45583d6..9198e6604 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -6362,7 +6362,38 @@ lbValue lb_find_value_from_entity(lbModule *m, Entity *e) { } +LLVMValueRef lb_big_int_to_llvm(lbModule *m, Type *original_type, BigInt const *a) { + if (big_int_is_zero(a)) { + return LLVMConstNull(lb_type(m, original_type)); + } + + u8 *rop = nullptr; + size_t max_count = 0; + size_t written = 0; + size_t size = 1; + size_t nails = 0; + mp_endian endian = MP_NATIVE_ENDIAN; + if (is_type_endian_little(original_type)) { + endian = MP_LITTLE_ENDIAN; + } else if (is_type_endian_big(original_type)) { + endian = MP_BIG_ENDIAN; + } + + max_count = mp_pack_count(a, nails, size); + rop = cast(u8 *)gb_alloc_align(permanent_allocator(), max_count, gb_align_of(u64)); + mp_err err = mp_pack(rop, max_count, &written, + MP_LSB_FIRST, + size, endian, nails, + a); + GB_ASSERT(err == MP_OKAY); + + LLVMValueRef value = LLVMConstIntOfArbitraryPrecision(lb_type(m, original_type), cast(unsigned)((written+7)/8), cast(u64 *)rop); + if (big_int_is_neg(a)) { + value = LLVMConstNeg(value); + } + return value; +} lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local) { @@ -6559,70 +6590,10 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc case ExactValue_Integer: if (is_type_pointer(type)) { LLVMTypeRef t = lb_type(m, original_type); - if (mp_iszero(&value.value_integer)) { - res.value = LLVMConstNull(t); - } else { - unsigned len = cast(unsigned)value.value_integer.used; - u64 v = mp_get_u64(&value.value_integer); - LLVMValueRef i = LLVMConstInt(lb_type(m, t_uintptr), cast(unsigned long long)v, false); - res.value = LLVMConstIntToPtr(i, t); - } + LLVMValueRef i = lb_big_int_to_llvm(m, t_uintptr, &value.value_integer); + res.value = LLVMConstIntToPtr(i, t); } else { - if (mp_iszero(&value.value_integer)) { - res.value = LLVMConstNull(lb_type(m, original_type)); - } else { - mp_int *a = &value.value_integer; - - u8 *rop = nullptr; - size_t max_count = 0; - size_t written = 0; - size_t size = 1; - size_t nails = 0; - mp_endian endian = MP_NATIVE_ENDIAN; - if (is_type_endian_little(type)) { - endian = MP_LITTLE_ENDIAN; - } else if (is_type_endian_big(type)) { - endian = MP_BIG_ENDIAN; - } - - max_count = mp_pack_count(a, nails, size); - rop = cast(u8 *)gb_alloc_align(permanent_allocator(), max_count, gb_align_of(u64)); - mp_err err = mp_pack(rop, max_count, &written, - MP_LSB_FIRST, - size, endian, nails, - &value.value_integer); - GB_ASSERT(err == MP_OKAY); - - res.value = LLVMConstIntOfArbitraryPrecision(lb_type(m, original_type), cast(unsigned)((written+7)/8), cast(u64 *)rop); - if (value.value_integer.sign) { - res.value = LLVMConstNeg(res.value); - } - - // size_t written = 0; - // size_t max_bytes = (value.value_integer.used*gb_size_of(mp_digit)+7)&~7; - // u8 *buf = cast(u8 *)gb_alloc_align(permanent_allocator(), max_bytes, gb_align_of(u64)); - // mp_to_ubin(&value.value_integer, buf, max_bytes, &written); - - // gb_printf_err("%tu %tu", written, max_bytes); - // for (size_t i = 0; i < written; i++) { - // gb_printf_err("%02x", buf[i]); - // } - // gb_printf_err("\n"); - // gb_exit(1); - - // if (is_type_different_to_arch_endianness(type)) { - // u8 *old_bytes = buf; - // u8 *new_bytes = cast(u8 *)gb_alloc_align(permanent_allocator(), max_bytes, gb_align_of(u64)); - // for (size_t i = 0; i < written; i++) { - // new_bytes[i] = old_bytes[written-1-i]; - // } - // buf = new_bytes; - // } - // res.value = LLVMConstIntOfArbitraryPrecision(lb_type(m, original_type), cast(unsigned)((written+7)/8), cast(u64 *)buf); - // if (value.value_integer.sign) { - // res.value = LLVMConstNeg(res.value); - // } - } + res.value = lb_big_int_to_llvm(m, original_type, &value.value_integer); } return res; case ExactValue_Float: -- cgit v1.2.3