diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index 2fe8a0dec..77f64ba82 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -912,8 +912,8 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") { fmt_bit_set(fi, val, info.name); case runtime.Type_Info_Bit_Set: - bits: u64; - bit_size := u64(8*type_info.size); + bits: u128; + bit_size := u128(8*type_info.size); do_byte_swap := is_bit_set_different_endian_to_platform(info.underlying); @@ -921,19 +921,23 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") { case 0: bits = 0; case 8: x := (^u8)(v.data)^; - bits = u64(x); + bits = u128(x); case 16: x := (^u16)(v.data)^; if do_byte_swap do x = byte_swap(x); - bits = u64(x); + bits = u128(x); case 32: x := (^u32)(v.data)^; if do_byte_swap do x = byte_swap(x); - bits = u64(x); + bits = u128(x); case 64: x := (^u64)(v.data)^; if do_byte_swap do x = byte_swap(x); - bits = u64(x); + bits = u128(x); + case 128: + x := (^u128)(v.data)^; + if do_byte_swap do x = byte_swap(x); + bits = u128(x); case: panic("unknown bit_size size"); } @@ -958,7 +962,7 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") { if is_enum do for ev, evi in e.values { v := enum_value_to_u64(ev); - if v == i { + if v == u64(i) { strings.write_string(fi.buf, e.names[evi]); commas += 1; continue loop; diff --git a/core/math/bits/bits.odin b/core/math/bits/bits.odin index 51f24b1bf..33f7f86ee 100644 --- a/core/math/bits/bits.odin +++ b/core/math/bits/bits.odin @@ -22,6 +22,7 @@ I16_MAX :: 1 << 15 - 1; I32_MAX :: 1 << 31 - 1; I64_MAX :: 1 << 63 - 1; +@(default_calling_convention="none") foreign { @(link_name="llvm.ctpop.i8") count_ones8 :: proc(i: u8) -> u8 --- @(link_name="llvm.ctpop.i16") count_ones16 :: proc(i: u16) -> u16 --- @@ -49,6 +50,8 @@ foreign { @(link_name="llvm.bswap.i16") byte_swap_i16 :: proc(i16) -> i16 --- @(link_name="llvm.bswap.i32") byte_swap_i32 :: proc(i32) -> i32 --- @(link_name="llvm.bswap.i64") byte_swap_i64 :: proc(i64) -> i64 --- + @(link_name="llvm.bswap.i128") byte_swap_u128 :: proc(u128) -> u128 --- + @(link_name="llvm.bswap.i128") byte_swap_i128 :: proc(i128) -> i128 --- } byte_swap_uint :: proc(i: uint) -> uint { @@ -70,9 +73,11 @@ byte_swap :: proc{ byte_swap_u16, byte_swap_u32, byte_swap_u64, + byte_swap_u128, byte_swap_i16, byte_swap_i32, byte_swap_i64, + byte_swap_i128, byte_swap_uint, byte_swap_int, }; @@ -120,6 +125,7 @@ to_le_u64 :: proc(i: u64) -> u64 { when os.ENDIAN == "little" { return i; } e to_le_uint :: proc(i: uint) -> uint { when os.ENDIAN == "little" { return i; } else { return byte_swap(i); } } +@(default_calling_convention="none") foreign { @(link_name="llvm.uadd.with.overflow.i8") overflowing_add_u8 :: proc(lhs, rhs: u8) -> (u8, bool) --- @(link_name="llvm.sadd.with.overflow.i8") overflowing_add_i8 :: proc(lhs, rhs: i8) -> (i8, bool) --- @@ -158,6 +164,7 @@ overflowing_add :: proc{ overflowing_add_uint, overflowing_add_int, }; +@(default_calling_convention="none") foreign { @(link_name="llvm.usub.with.overflow.i8") overflowing_sub_u8 :: proc(lhs, rhs: u8) -> (u8, bool) --- @(link_name="llvm.ssub.with.overflow.i8") overflowing_sub_i8 :: proc(lhs, rhs: i8) -> (i8, bool) --- @@ -195,7 +202,7 @@ overflowing_sub :: proc{ overflowing_sub_uint, overflowing_sub_int, }; - +@(default_calling_convention="none") foreign { @(link_name="llvm.umul.with.overflow.i8") overflowing_mul_u8 :: proc(lhs, rhs: u8) -> (u8, bool) --- @(link_name="llvm.smul.with.overflow.i8") overflowing_mul_i8 :: proc(lhs, rhs: i8) -> (i8, bool) --- diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index 9afe31a71..b6fff0864 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -510,6 +510,7 @@ quo_complex128 :: proc(n, m: complex128) -> complex128 { return complex(e, f); } +@(default_calling_convention="none") foreign { @(link_name="llvm.cttz.i8") _ctz_u8 :: proc(i: u8, is_zero_undef := false) -> u8 --- @(link_name="llvm.cttz.i16") _ctz_u16 :: proc(i: u16, is_zero_undef := false) -> u16 --- @@ -523,6 +524,7 @@ _ctz :: proc{ _ctz_u64, }; +@(default_calling_convention="none") foreign { @(link_name="llvm.ctlz.i8") _clz_u8 :: proc(i: u8, is_zero_undef := false) -> u8 --- @(link_name="llvm.ctlz.i16") _clz_u16 :: proc(i: u16, is_zero_undef := false) -> u16 --- diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index bd4f5c8ca..206fa4a2d 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -946,22 +946,7 @@ deferred_procedure_associations :: proc() { } main :: proc() { - x: u128 = 1233456453347654617; - y: u128 = 19; - z := x * y; - w := z / 120; - - assert(z == 23435672613605437723); - // assert(w == 195297271780045314); - - - fmt.println(x); - fmt.println(y); - fmt.println(z, u128(23435672613605437723)); - fmt.println(w, u128(195297271780045314)); - fmt.println(x % 33774564533476546); - - when false { + when true { general_stuff(); union_type(); parametric_polymorphism(); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 1e7e7a965..be135ce68 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -86,8 +86,8 @@ CallArgumentData check_call_arguments (CheckerContext *c, Operand *operand, Ty Type * check_init_variable (CheckerContext *c, Entity *e, Operand *operand, String context_name); -Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type); -Type *type_to_abi_compat_result_type(gbAllocator a, Type *original_type); +Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type, ProcCallingConvention cc); +Type *type_to_abi_compat_result_type(gbAllocator a, Type *original_type, ProcCallingConvention cc); bool abi_compat_return_by_pointer(gbAllocator a, ProcCallingConvention cc, Type *abi_return_type); void set_procedure_abi_types(CheckerContext *c, Type *type); diff --git a/src/check_type.cpp b/src/check_type.cpp index 15c621729..1ab975b07 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -746,6 +746,11 @@ void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast return; } + if (is_type_integer_128bit(base_type)) { + error(node, "Base type for enumeration cannot be a 128-bit integer"); + return; + } + // NOTE(bill): Must be up here for the 'check_init_constant' system enum_type->Enum.base_type = base_type; enum_type->Enum.scope = ctx->scope; @@ -1825,7 +1830,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { return tuple; } -Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) { +Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type, ProcCallingConvention cc) { Type *new_type = original_type; if (is_type_boolean(original_type)) { @@ -1851,7 +1856,11 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) { if (build_context.word_size == 8) { if (is_type_integer_128bit(original_type)) { - return alloc_type_simd_vector(2, t_u64); + if (cc == ProcCC_None) { + return original_type; + } else { + return alloc_type_simd_vector(2, t_u64); + } } } @@ -1947,7 +1956,7 @@ Type *reduce_tuple_to_single_type(Type *original_type) { return original_type; } -Type *type_to_abi_compat_result_type(gbAllocator a, Type *original_type) { +Type *type_to_abi_compat_result_type(gbAllocator a, Type *original_type, ProcCallingConvention cc) { Type *new_type = original_type; if (new_type == nullptr) { return nullptr; @@ -1963,7 +1972,11 @@ Type *type_to_abi_compat_result_type(gbAllocator a, Type *original_type) { if (build_context.ODIN_OS == "windows") { if (build_context.word_size == 8) { if (is_type_integer_128bit(single_type)) { - return alloc_type_simd_vector(2, t_u64); + if (cc == ProcCC_None) { + return original_type; + } else { + return alloc_type_simd_vector(2, t_u64); + } } } @@ -2071,13 +2084,13 @@ void set_procedure_abi_types(CheckerContext *c, Type *type) { Entity *e = type->Proc.params->Tuple.variables[i]; if (e->kind == Entity_Variable) { Type *original_type = e->type; - Type *new_type = type_to_abi_compat_param_type(c->allocator, original_type); + Type *new_type = type_to_abi_compat_param_type(c->allocator, original_type, type->Proc.calling_convention); type->Proc.abi_compat_params[i] = new_type; } } // NOTE(bill): The types are the same - type->Proc.abi_compat_result_type = type_to_abi_compat_result_type(c->allocator, type->Proc.results); + type->Proc.abi_compat_result_type = type_to_abi_compat_result_type(c->allocator, type->Proc.results, type->Proc.calling_convention); type->Proc.return_by_pointer = abi_compat_return_by_pointer(c->allocator, type->Proc.calling_convention, type->Proc.abi_compat_result_type); }