diff --git a/lib/std/core/env.c3 b/lib/std/core/env.c3 index e24f04a8c..2ef7c19b8 100644 --- a/lib/std/core/env.c3 +++ b/lib/std/core/env.c3 @@ -55,5 +55,7 @@ const OsType OS_TYPE = (OsType)($$OS_TYPE); const CompilerOptLevel COMPILER_OPT_LEVEL = (CompilerOptLevel)($$COMPILER_OPT_LEVEL); const bool BIG_ENDIAN = $$PLATFORM_BIG_ENDIAN; const bool I128_SUPPORT = $$PLATFORM_I128_SUPPORTED; +const bool F128_SUPPORT = $$PLATFORM_F128_SUPPORTED; +const bool F16_SUPPORT = $$PLATFORM_F16_SUPPORTED; const bool COMPILER_SAFE_MODE = $$COMPILER_SAFE_MODE; const usize TEMP_ALLOCATOR_SIZE = 128 * 1024; \ No newline at end of file diff --git a/lib/std/io_printf.c3 b/lib/std/io_printf.c3 index bc0b6424f..cf5c00bed 100644 --- a/lib/std/io_printf.c3 +++ b/lib/std/io_printf.c3 @@ -624,6 +624,12 @@ private fn FloatType float_from_variant(variant arg) return *arg; } $endif; + $if (env::F128_SUPPORT): + if (arg.type == float128.typeid) return *((float128*)arg.ptr); + $endif; + $if (env::F16_SUPPORT): + if (arg.type == float16.typeid) return *((float16*)arg.ptr); + $endif; if (arg.type.kind == TypeKind.POINTER) { @@ -666,7 +672,7 @@ private fn NtoaType int_from_variant(variant arg, bool *is_neg) { case int128: int128 val = *arg; - return (*is_neg = val < 0) ? -val : val; + return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : val; case uint128: return *arg; } @@ -682,16 +688,16 @@ private fn NtoaType int_from_variant(variant arg, bool *is_neg) return (NtoaType)*arg; case ichar: int val = *arg; - return (NtoaType)((*is_neg = val < 0) ? -val : val); + return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : (NtoaType)val; case short: int val = *arg; - return (NtoaType)((*is_neg = val < 0) ? -val : val); + return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : (NtoaType)val; case int: int val = *arg; - return (NtoaType)((*is_neg = val < 0) ? -val : val); + return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : (NtoaType)val; case long: long val = *arg; - return (NtoaType)((*is_neg = val < 0) ? -val : val); + return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : (NtoaType)val; case char: return *arg; case ushort: diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 4b299f0b1..3edb0e307 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -642,6 +642,8 @@ void compile() setup_bool_define("C_CHAR_IS_SIGNED", platform_target.signed_c_char); setup_bool_define("PLATFORM_BIG_ENDIAN", platform_target.big_endian); setup_bool_define("PLATFORM_I128_SUPPORTED", platform_target.int128); + setup_bool_define("PLATFORM_F128_SUPPORTED", platform_target.float128); + setup_bool_define("PLATFORM_F16_SUPPORTED", platform_target.float16); setup_int_define("COMPILER_OPT_LEVEL", (uint64_t)active_target.optimization_level, type_int); setup_int_define("OS_TYPE", (uint64_t)platform_target.os, type_int); setup_int_define("COMPILER_SIZE_OPT_LEVEL", (uint64_t)active_target.size_optimization_level, type_int); diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index ff478e0fa..c5926872a 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -1774,7 +1774,7 @@ extern TypeInfo *poisoned_type_info; extern Type *type_bool, *type_void, *type_voidptr; -extern Type *type_half, *type_float, *type_double, *type_f128; +extern Type *type_float16, *type_float, *type_double, *type_f128; extern Type *type_ichar, *type_short, *type_int, *type_long, *type_isize; extern Type *type_char, *type_ushort, *type_uint, *type_ulong, *type_usize; extern Type *type_iptr, *type_uptr, *type_iptrdiff, *type_uptrdiff; diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index bb3487c49..764caba20 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -1442,7 +1442,7 @@ static Expr *parse_double(ParseContext *c, Expr *left) number->type = type_float; break; case TYPE_F16: - number->type = type_half; + number->type = type_float16; break; default: UNREACHABLE diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index 34f93f83a..65a0a47aa 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -845,8 +845,9 @@ Expr *recursive_may_narrow_float(Expr *expr, Type *type) { switch (expr->unary_expr.operator) { - case UNARYOP_ERROR: case UNARYOP_DEREF: + return false; + case UNARYOP_ERROR: case UNARYOP_ADDR: case UNARYOP_NOT: case UNARYOP_TADDR: diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 1599a4462..a7041b077 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -3709,6 +3709,9 @@ static inline bool sema_create_const_min(SemaContext *context, Expr *expr, Type expr->const_expr.fxx.type = flat->type_kind; switch (flat->type_kind) { + case TYPE_F16: + expr->const_expr.fxx.f = 5.9604645e-8; + break; case TYPE_F32: expr->const_expr.fxx.f = FLT_MIN; break; @@ -3734,19 +3737,19 @@ static inline bool sema_create_const_min(SemaContext *context, Expr *expr, Type switch (flat->type_kind) { case TYPE_I8: - expr->const_expr.ixx.i = (Int128){ 0, 0xFF }; + expr->const_expr.ixx.i = (Int128){ 0, 0x80 }; break; case TYPE_I16: - expr->const_expr.ixx.i = (Int128){ 0, 0xFFFF }; + expr->const_expr.ixx.i = (Int128){ 0, 0x8000 }; break; case TYPE_I32: - expr->const_expr.ixx.i = (Int128){ 0, 0xFFFFFFFFLL }; + expr->const_expr.ixx.i = (Int128){ 0, 1ULL << 31 }; break; case TYPE_I64: - expr->const_expr.ixx.i = (Int128){ 0, ~((uint64_t)0) }; + expr->const_expr.ixx.i = (Int128){ 0, 1ULL << 63 }; break; case TYPE_I128: - expr->const_expr.ixx.i = (Int128){ ~((uint64_t)0), ~((uint64_t)0) }; + expr->const_expr.ixx.i = (Int128){ 1ULL << 63, 0 }; break; default: expr->const_expr.ixx.i = (Int128){ 0, 0 }; @@ -3812,6 +3815,9 @@ static inline bool sema_create_const_max(SemaContext *context, Expr *expr, Type expr->const_expr.fxx.type = flat->type_kind; switch (flat->type_kind) { + case TYPE_F16: + expr->const_expr.fxx.f = 65504.0; + break; case TYPE_F32: expr->const_expr.fxx.f = FLT_MAX; break; diff --git a/src/compiler/target.c b/src/compiler/target.c index 28fd5fe13..f6e979cf7 100644 --- a/src/compiler/target.c +++ b/src/compiler/target.c @@ -831,7 +831,7 @@ static unsigned os_target_supports_float128(OsType os, ArchType arch) switch (arch) { case ARCH_TYPE_AARCH64: - return true; + return false; case ARCH_TYPE_PPC64: if (os == OS_TYPE_MACOSX) return true; return false; diff --git a/src/compiler/types.c b/src/compiler/types.c index cfc60c931..3fe2c6ad3 100644 --- a/src/compiler/types.c +++ b/src/compiler/types.c @@ -17,7 +17,7 @@ static struct Type *type_bool = &t.u1; Type *type_void = &t.u0; Type *type_voidptr = &t.voidstar; -Type *type_half = &t.f16; +Type *type_float16 = &t.f16; Type *type_float = &t.f32; Type *type_double = &t.f64; Type *type_f128 = &t.f128; @@ -1410,6 +1410,8 @@ Type *type_from_token(TokenType type) return type_bool; case TOKEN_CHAR: return type_char; + case TOKEN_FLOAT16: + return type_float16; case TOKEN_DOUBLE: return type_double; case TOKEN_FLOAT: diff --git a/src/version.h b/src/version.h index 54443ef6e..ed6d5dcdc 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.3.40" \ No newline at end of file +#define COMPILER_VERSION "0.3.41" \ No newline at end of file diff --git a/test/test_suite/expressions/type_support.c3t b/test/test_suite/expressions/type_support.c3t new file mode 100644 index 000000000..8a75336b9 --- /dev/null +++ b/test/test_suite/expressions/type_support.c3t @@ -0,0 +1,75 @@ +// #target: macos-x64 + +module test; +import std::io; + +macro print_type_info(...) +{ + $for (var $i = 0; $i < $vacount; $i++): + io::printfln("type: %s", $nameof($vatype($i))); + io::printfln("%s.sizeof = %d", $nameof($vatype($i)), $vatype($i).sizeof); + io::printfln("%s.min = %s", $nameof($vatype($i)), $vatype($i).min); + io::printfln("%s.max = %s\n", $nameof($vatype($i)), $vatype($i).max); + $endfor; +} + +fn void main() +{ + io::printfln("Unsigned integers:"); + print_type_info(char, ushort, uint, ulong, uptr, uptrdiff, usize); + io::printfln("Signed integers:"); + print_type_info(ichar, short, int, long, iptr, iptrdiff, isize); + io::printfln("Floats:"); + print_type_info(float, double); +} + +/* #expect: test.ll + + store i64 1 + store i8 0 + store i8 -1 + store i16 0 + store i16 -1 + store i64 4 + store i64 2 + store i32 0 + store i32 -1 + store i64 8 + store i64 0 + store i64 -1 + store i64 8 + store i64 0 + store i64 -1 + store i64 8 + store i64 0 + store i64 -1 + store i64 8 + store i64 0 + store i64 -1 + store i64 1 + store i8 -128 + store i8 127 + store i64 2 + store i16 -32768 + store i16 32767 + store i64 4 + store i32 -2147483648 + store i32 2147483647 + store i64 8 + store i64 -9223372036854775808 + store i64 9223372036854775807 + store i64 8 + store i64 -9223372036854775808 + store i64 9223372036854775807 + store i64 8 + store i64 -9223372036854775808 + store i64 9223372036854775807 + store i64 8 + store i64 -9223372036854775808 + store i64 9223372036854775807 + store i64 4 + store float 0x3810000000000000 + store float 0x47EFFFFFE0000000 + store i64 8 + store double 0x10000000000000 + store double 0x7FEFFFFFFFFFFFFF \ No newline at end of file diff --git a/test/test_suite2/expressions/type_support.c3t b/test/test_suite2/expressions/type_support.c3t new file mode 100644 index 000000000..8a75336b9 --- /dev/null +++ b/test/test_suite2/expressions/type_support.c3t @@ -0,0 +1,75 @@ +// #target: macos-x64 + +module test; +import std::io; + +macro print_type_info(...) +{ + $for (var $i = 0; $i < $vacount; $i++): + io::printfln("type: %s", $nameof($vatype($i))); + io::printfln("%s.sizeof = %d", $nameof($vatype($i)), $vatype($i).sizeof); + io::printfln("%s.min = %s", $nameof($vatype($i)), $vatype($i).min); + io::printfln("%s.max = %s\n", $nameof($vatype($i)), $vatype($i).max); + $endfor; +} + +fn void main() +{ + io::printfln("Unsigned integers:"); + print_type_info(char, ushort, uint, ulong, uptr, uptrdiff, usize); + io::printfln("Signed integers:"); + print_type_info(ichar, short, int, long, iptr, iptrdiff, isize); + io::printfln("Floats:"); + print_type_info(float, double); +} + +/* #expect: test.ll + + store i64 1 + store i8 0 + store i8 -1 + store i16 0 + store i16 -1 + store i64 4 + store i64 2 + store i32 0 + store i32 -1 + store i64 8 + store i64 0 + store i64 -1 + store i64 8 + store i64 0 + store i64 -1 + store i64 8 + store i64 0 + store i64 -1 + store i64 8 + store i64 0 + store i64 -1 + store i64 1 + store i8 -128 + store i8 127 + store i64 2 + store i16 -32768 + store i16 32767 + store i64 4 + store i32 -2147483648 + store i32 2147483647 + store i64 8 + store i64 -9223372036854775808 + store i64 9223372036854775807 + store i64 8 + store i64 -9223372036854775808 + store i64 9223372036854775807 + store i64 8 + store i64 -9223372036854775808 + store i64 9223372036854775807 + store i64 8 + store i64 -9223372036854775808 + store i64 9223372036854775807 + store i64 4 + store float 0x3810000000000000 + store float 0x47EFFFFFE0000000 + store i64 8 + store double 0x10000000000000 + store double 0x7FEFFFFFFFFFFFFF \ No newline at end of file