From 6a3219ad43bc88aedb93725656f5eed14257beea Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Wed, 1 Feb 2023 01:10:17 +0100 Subject: [PATCH] Make thread allocator take the thread allocator by default for allocating initial memory. Add some int128 methods. Fix attribute parsing. --- lib/std/core/mem.c3 | 6 +-- lib/std/math/math_i128.c3 | 97 ++++++++++++++++++++++++++++++++++ src/compiler/bigint.c | 2 +- src/compiler/parse_global.c | 6 +-- src/version.h | 2 +- test/test_suite/stdlib/map.c3t | 61 ++++++++++----------- 6 files changed, 135 insertions(+), 39 deletions(-) diff --git a/lib/std/core/mem.c3 b/lib/std/core/mem.c3 index 7251b22c1..a1e078ff5 100644 --- a/lib/std/core/mem.c3 +++ b/lib/std/core/mem.c3 @@ -277,11 +277,11 @@ macro TempAllocator* temp_allocator() { $switch (env::MEMORY_ENV): $case NORMAL: - thread_temp_allocator = allocator::new_temp(1024 * 256, allocator::LIBC_ALLOCATOR)!!; + thread_temp_allocator = allocator::new_temp(1024 * 256, thread_allocator)!!; $case SMALL: - thread_temp_allocator = allocator::new_temp(1024 * 16, allocator::LIBC_ALLOCATOR)!!; + thread_temp_allocator = allocator::new_temp(1024 * 16, thread_allocator)!!; $case TINY: - thread_temp_allocator = allocator::new_temp(1024 * 4, allocator::LIBC_ALLOCATOR)!!; + thread_temp_allocator = allocator::new_temp(1024 * 2, thread_allocator)!!; $case NONE: unreachable("Temp allocator must explicitly created when memory-env is set to 'none'."); $endswitch; diff --git a/lib/std/math/math_i128.c3 b/lib/std/math/math_i128.c3 index a471bec75..33412c56b 100644 --- a/lib/std/math/math_i128.c3 +++ b/lib/std/math/math_i128.c3 @@ -70,6 +70,103 @@ fn int128 __modti3(int128 a, int128 b) @extname("__modti3") @weak return __umodti3(unsigned_a, unsigned_b) ^ sign + (-sign); } +private union Int128bits +{ + struct + { + ulong ulow, uhigh; + } + struct + { + long ilow, ihigh; + } + uint128 all; +} + +fn uint128 __lshrti3(uint128 a, uint b) @extname("__lshrti3") @weak +{ + Int128bits result; + result.all = a; + if (b >= 64) + { + result.ulow = result.uhigh >> (b - 64); + result.uhigh = 0; + } + else + { + if (b == 0) return a; + result.ulow = (result.uhigh << (64 - b)) | (result.ulow >> b); + result.uhigh = result.uhigh >> b; + } + return result.all; +} + +fn int128 __ashrti3(int128 a, uint b) @extern("__ashrti3") @weak +{ + Int128bits result; + result.all = a; + if (b >= 64) + { + result.ilow = result.ihigh >> (b - 64); + result.ihigh = result.ihigh >> 63; + } + else + { + if (b == 0) return a; + result.ilow = result.ihigh << (64 - b) | (result.ilow >> b); + result.ihigh = result.ihigh >> b; + } + return result.all; +} + +fn int128 __ashlti3(int128 a, uint b) @extern("__ashlti3") @weak +{ + Int128bits result; + result.all = a; + if (b >= 64) + { + result.ulow = 0; + result.uhigh = result.ulow << (b - 64); + } + else + { + if (b == 0) return a; + result.uhigh = (result.uhigh << b) | (result.ulow >> (64 - b)); + result.ulow = result.ulow << b; + } + return result.all; +} + +// Returns: a * b + +private fn int128 __mulddi3(ulong a, ulong b) +{ + Int128bits r; + const ulong LOWER_MASK = 0xffff_ffff; + r.ulow = (a & LOWER_MASK) * (b & LOWER_MASK); + ulong t = r.ulow >> 32; + r.ulow &= LOWER_MASK; + t += (a >> 32) * (b & LOWER_MASK); + r.ulow += (t & LOWER_MASK) << 32; + r.uhigh = t >> 32; + t = r.ulow >> 32; + r.ulow &= LOWER_MASK; + t += (b >> 32) * (a & LOWER_MASK); + r.ulow += (t & LOWER_MASK) << 32; + r.uhigh += t >> 32; + r.uhigh += (a >> 32) * (b >> 32); + return r.all; +} + +fn int128 __multi3(int128 a, int128 b) @extern("__multi3") @weak +{ + Int128bits x = { .all = a }; + Int128bits y = { .all = b }; + Int128bits r = { .all = __mulddi3(x.ulow, y.ulow) }; + r.uhigh += x.uhigh * y.ulow + x.ulow * y.uhigh; + return r.all; +} + fn float __floattisf(int128 a) @extname("__floattisf") @weak => float_from_i128(float, a); fn double __floattidf(int128 a) @extname("__floattidf") @weak => float_from_i128(double, a); fn float __floatuntisf(uint128 a) @extname("__floatuntisf") @weak => float_from_u128(float, a); diff --git a/src/compiler/bigint.c b/src/compiler/bigint.c index e697365ab..67ca328c8 100644 --- a/src/compiler/bigint.c +++ b/src/compiler/bigint.c @@ -267,7 +267,7 @@ Int128 i128_shl64(Int128 op1, uint64_t amount) if (amount > 127) return (Int128){ 0, 0 }; if (amount == 64) return (Int128){ op1.low, 0 }; if (amount > 64) return (Int128){ op1.low << (amount - 64), 0 }; - return (Int128){ (op1.high <<= amount) | op1.low >> (64 - amount), op1.low << amount }; + return (Int128){ (op1.high << amount) | op1.low >> (64 - amount), op1.low << amount }; } Int128 i128_shl(Int128 op1, Int128 op) diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index 2db80105d..644f82061 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -1024,15 +1024,13 @@ bool parse_attributes(ParseContext *c, Attr ***attributes_ref) if (!parse_attribute(c, &attr)) return false; if (!attr) return true; const char *name = attr->name; - VECEACH(*attributes_ref, i) - { - Attr *other_attr = *attributes_ref[i]; + FOREACH_BEGIN(Attr *other_attr, *attributes_ref) if (other_attr->name == name) { SEMA_ERROR(attr, "Repeat of attribute '%s' here.", name); return false; } - } + FOREACH_END(); vec_add(*attributes_ref, attr); } return true; diff --git a/src/version.h b/src/version.h index 0be26c5d4..beb5c25db 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.37" \ No newline at end of file +#define COMPILER_VERSION "0.4.38" \ No newline at end of file diff --git a/test/test_suite/stdlib/map.c3t b/test/test_suite/stdlib/map.c3t index 994df1fdd..f5cfd3795 100644 --- a/test/test_suite/stdlib/map.c3t +++ b/test/test_suite/stdlib/map.c3t @@ -350,57 +350,58 @@ voiderr64: ; preds = %after_check63, %voi br i1 %not, label %if.then, label %if.exit if.then: ; preds = %voiderr64 - %79 = call i64 @std_core_mem_allocator_new_temp(ptr %retparam65, i64 262144, ptr @std_core_mem_allocator__SYSTEM_ALLOCATOR) - %not_err66 = icmp eq i64 %79, 0 + %79 = load ptr, ptr @std_core_mem_thread_allocator, align 8 + %80 = call i64 @std_core_mem_allocator_new_temp(ptr %retparam65, i64 262144, ptr %79) + %not_err66 = icmp eq i64 %80, 0 br i1 %not_err66, label %after_check67, label %assign_optional assign_optional: ; preds = %if.then - store i64 %79, ptr %error_var, align 8 + store i64 %80, ptr %error_var, align 8 br label %panic_block after_check67: ; preds = %if.then - %80 = load ptr, ptr %retparam65, align 8 + %81 = load ptr, ptr %retparam65, align 8 br label %noerr_block panic_block: ; preds = %assign_optional - %81 = load ptr, ptr @std_core_builtin_panic, align 8 - call void %81(ptr @.panic_msg, i64 27, ptr @.file, i64 6, ptr @.func, i64 4, i32 280) + %82 = load ptr, ptr @std_core_builtin_panic, align 8 + call void %82(ptr @.panic_msg, i64 27, ptr @.file, i64 6, ptr @.func, i64 4, i32 280) unreachable noerr_block: ; preds = %after_check67 - store ptr %80, ptr @std_core_mem_thread_temp_allocator, align 8 + store ptr %81, ptr @std_core_mem_thread_temp_allocator, align 8 br label %if.exit if.exit: ; preds = %noerr_block, %voiderr64 - %82 = load ptr, ptr @std_core_mem_thread_temp_allocator, align 8 - store ptr %82, ptr %temp, align 8 - %83 = load ptr, ptr %temp, align 8 - %84 = getelementptr inbounds %TempAllocator, ptr %83, i32 0, i32 3 - %85 = load i64, ptr %84, align 8 - store i64 %85, ptr %mark, align 8 + %83 = load ptr, ptr @std_core_mem_thread_temp_allocator, align 8 + store ptr %83, ptr %temp, align 8 + %84 = load ptr, ptr %temp, align 8 + %85 = getelementptr inbounds %TempAllocator, ptr %84, i32 0, i32 3 + %86 = load i64, ptr %85, align 8 + store i64 %86, ptr %mark, align 8 call void @llvm.memset.p0.i64(ptr align 8 %map3, i8 0, i64 40, i1 false) - %86 = load ptr, ptr @std_core_mem_thread_allocator, align 8 - call void @"std_map$$int.double_HashMap_init"(ptr %map3, i32 16, float 7.500000e-01, ptr %86) - %87 = call i8 @"std_map$$int.double_HashMap_set"(ptr %map3, i32 5, double 3.200000e+00) - %88 = call i8 @"std_map$$int.double_HashMap_set"(ptr %map3, i32 7, double 5.200000e+00) - %89 = load ptr, ptr @std_core_mem_thread_allocator, align 8 - %90 = call { ptr, i64 } @"std_map$$int.double_HashMap_key_list"(ptr %map3, ptr %89) - store { ptr, i64 } %90, ptr %result70, align 8 - %91 = insertvalue %variant undef, ptr %result70, 0 - %92 = insertvalue %variant %91, i64 ptrtoint (ptr @"ct$sa$int" to i64), 1 - %93 = getelementptr inbounds [1 x %variant], ptr %varargslots69, i64 0, i64 0 - store %variant %92, ptr %93, align 16 - %94 = call i64 @std_io_printfn(ptr %retparam68, ptr @.str.11, i64 2, ptr %varargslots69, i64 1) - %not_err71 = icmp eq i64 %94, 0 + %87 = load ptr, ptr @std_core_mem_thread_allocator, align 8 + call void @"std_map$$int.double_HashMap_init"(ptr %map3, i32 16, float 7.500000e-01, ptr %87) + %88 = call i8 @"std_map$$int.double_HashMap_set"(ptr %map3, i32 5, double 3.200000e+00) + %89 = call i8 @"std_map$$int.double_HashMap_set"(ptr %map3, i32 7, double 5.200000e+00) + %90 = load ptr, ptr @std_core_mem_thread_allocator, align 8 + %91 = call { ptr, i64 } @"std_map$$int.double_HashMap_key_list"(ptr %map3, ptr %90) + store { ptr, i64 } %91, ptr %result70, align 8 + %92 = insertvalue %variant undef, ptr %result70, 0 + %93 = insertvalue %variant %92, i64 ptrtoint (ptr @"ct$sa$int" to i64), 1 + %94 = getelementptr inbounds [1 x %variant], ptr %varargslots69, i64 0, i64 0 + store %variant %93, ptr %94, align 16 + %95 = call i64 @std_io_printfn(ptr %retparam68, ptr @.str.11, i64 2, ptr %varargslots69, i64 1) + %not_err71 = icmp eq i64 %95, 0 br i1 %not_err71, label %after_check72, label %voiderr73 after_check72: ; preds = %if.exit br label %voiderr73 voiderr73: ; preds = %after_check72, %if.exit - %95 = load ptr, ptr %temp, align 8 - %96 = getelementptr inbounds %TempAllocator, ptr %95, i32 0, i32 0 - %97 = load i64, ptr %mark, align 8 - call void @std_core_mem_allocator_Allocator_reset(ptr %96, i64 %97) + %96 = load ptr, ptr %temp, align 8 + %97 = getelementptr inbounds %TempAllocator, ptr %96, i32 0, i32 0 + %98 = load i64, ptr %mark, align 8 + call void @std_core_mem_allocator_Allocator_reset(ptr %97, i64 %98) ret void }