diff options
| author | gingerBill <bill@gingerbill.org> | 2021-07-11 16:08:16 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-07-11 16:08:16 +0100 |
| commit | 460e14e5860a503b8e7716ce18a29eb99f517cf7 (patch) | |
| tree | 058edb259fd5e6cab889f7b12156938c748509c0 /src/llvm_backend.cpp | |
| parent | ebcabb8a27ace67c3cd869a573df62b260000ee8 (diff) | |
Change the compiler's big integer library to use libTomMath
This now replaces Bill's crappy big int implementation
Diffstat (limited to 'src/llvm_backend.cpp')
| -rw-r--r-- | src/llvm_backend.cpp | 74 |
1 files changed, 54 insertions, 20 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index c351876d4..fa45583d6 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -6558,36 +6558,70 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc case ExactValue_Integer: if (is_type_pointer(type)) { - unsigned len = cast(unsigned)value.value_integer.len; LLVMTypeRef t = lb_type(m, original_type); - if (len == 0) { + if (mp_iszero(&value.value_integer)) { res.value = LLVMConstNull(t); } else { - LLVMValueRef i = LLVMConstIntOfArbitraryPrecision(lb_type(m, t_uintptr), len, big_int_ptr(&value.value_integer)); + 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); } } else { - unsigned len = cast(unsigned)value.value_integer.len; - if (len == 0) { + if (mp_iszero(&value.value_integer)) { res.value = LLVMConstNull(lb_type(m, original_type)); } else { - u64 *words = big_int_ptr(&value.value_integer); - if (is_type_different_to_arch_endianness(type)) { - // NOTE(bill): Swap byte order for different endianness - i64 sz = type_size_of(type); - isize byte_len = gb_size_of(u64)*len; - u8 *old_bytes = cast(u8 *)words; - // TODO(bill): Use a different allocator here for a temporary allocation - u8 *new_bytes = cast(u8 *)gb_alloc_align(permanent_allocator(), byte_len, gb_align_of(u64)); - for (i64 i = 0; i < sz; i++) { - new_bytes[i] = old_bytes[sz-1-i]; - } - words = cast(u64 *)new_bytes; - } - res.value = LLVMConstIntOfArbitraryPrecision(lb_type(m, original_type), len, words); - if (value.value_integer.neg) { + 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); + // } } } return res; |