From afeb555e2f0ec8fac7f22b6ed4b8f646a3d9e440 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 10 Aug 2021 22:44:00 +0200 Subject: [PATCH] Improved support for vectors that allows correct usage in C ABI. To free keywords, half -> float16, i128 -> int128, u128 -> uint128, quad -> float128. --- resources/lib/std/cinterop.c3 | 4 ++-- src/compiler/enums.h | 14 +++++++------- src/compiler/parse_expr.c | 8 ++++---- src/compiler/target.c | 18 +++++++++++++++++- src/compiler/tokens.c | 16 ++++++++-------- src/compiler/types.c | 28 +++++++++++++++++++++++----- 6 files changed, 61 insertions(+), 27 deletions(-) diff --git a/resources/lib/std/cinterop.c3 b/resources/lib/std/cinterop.c3 index 9df255e46..e0a3d5f56 100644 --- a/resources/lib/std/cinterop.c3 +++ b/resources/lib/std/cinterop.c3 @@ -53,8 +53,8 @@ $else: $endif; $if (C_LONG_LONG_SIZE == 128): - define CLongLong = i128; - define CULongLong = u128; + define CLongLong = int128; + define CULongLong = uint128; $elif (C_LONG_LONG_SIZE == 64): define CLongLong = long; define CULongLong = ulong; diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 1d83a0eed..8a531fa3c 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -352,8 +352,8 @@ typedef enum TOKEN_CHAR, TOKEN_DOUBLE, TOKEN_FLOAT, - TOKEN_HALF, - TOKEN_I128, + TOKEN_FLOAT16, + TOKEN_INT128, TOKEN_ICHAR, TOKEN_INT, TOKEN_IPTR, @@ -361,14 +361,14 @@ typedef enum TOKEN_ISIZE, TOKEN_LONG, TOKEN_SHORT, - TOKEN_U128, + TOKEN_UINT128, TOKEN_UINT, TOKEN_ULONG, TOKEN_UPTR, TOKEN_UPTRDIFF, TOKEN_USHORT, TOKEN_USIZE, - TOKEN_QUAD, + TOKEN_FLOAT128, TOKEN_ANYERR, TOKEN_TYPEID, @@ -475,11 +475,11 @@ typedef enum #define NON_VOID_TYPE_TOKENS \ TOKEN_BOOL: case TOKEN_CHAR: case TOKEN_DOUBLE: case TOKEN_FLOAT: \ - case TOKEN_HALF: case TOKEN_I128: case TOKEN_ICHAR: case TOKEN_INT: \ + case TOKEN_FLOAT16: case TOKEN_INT128: case TOKEN_ICHAR: case TOKEN_INT: \ case TOKEN_IPTR: case TOKEN_IPTRDIFF: case TOKEN_ISIZE: case TOKEN_LONG: \ - case TOKEN_SHORT: case TOKEN_U128: case TOKEN_UINT: case TOKEN_ULONG: \ + case TOKEN_SHORT: case TOKEN_UINT128: case TOKEN_UINT: case TOKEN_ULONG: \ case TOKEN_UPTR: case TOKEN_UPTRDIFF: case TOKEN_USHORT: case TOKEN_USIZE: \ - case TOKEN_QUAD: case TOKEN_TYPEID: case TOKEN_ANYERR + case TOKEN_FLOAT128: case TOKEN_TYPEID: case TOKEN_ANYERR #define TYPE_TOKENS NON_VOID_TYPE_TOKENS: case TOKEN_VOID #define TYPELIKE_TOKENS TYPE_TOKENS: case TOKEN_TYPE_IDENT: \ case TOKEN_CT_TYPE_IDENT: case TOKEN_VIRTUAL: case TOKEN_CT_TYPEOF diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index 932a2a3c2..9874c22d0 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -1059,8 +1059,8 @@ ParseRule rules[TOKEN_EOF + 1] = { [TOKEN_UINT] = { parse_type_identifier, NULL, PREC_NONE }, [TOKEN_LONG] = { parse_type_identifier, NULL, PREC_NONE }, [TOKEN_ULONG] = { parse_type_identifier, NULL, PREC_NONE }, - [TOKEN_I128] = { parse_type_identifier, NULL, PREC_NONE }, - [TOKEN_U128] = { parse_type_identifier, NULL, PREC_NONE }, + [TOKEN_INT128] = { parse_type_identifier, NULL, PREC_NONE }, + [TOKEN_UINT128] = { parse_type_identifier, NULL, PREC_NONE }, [TOKEN_ISIZE] = { parse_type_identifier, NULL, PREC_NONE }, [TOKEN_USIZE] = { parse_type_identifier, NULL, PREC_NONE }, [TOKEN_IPTR] = { parse_type_identifier, NULL, PREC_NONE }, @@ -1069,8 +1069,8 @@ ParseRule rules[TOKEN_EOF + 1] = { [TOKEN_UPTRDIFF] = { parse_type_identifier, NULL, PREC_NONE }, [TOKEN_FLOAT] = { parse_type_identifier, NULL, PREC_NONE }, [TOKEN_DOUBLE] = { parse_type_identifier, NULL, PREC_NONE }, - [TOKEN_HALF] = { parse_type_identifier, NULL, PREC_NONE }, - [TOKEN_QUAD] = { parse_type_identifier, NULL, PREC_NONE }, + [TOKEN_FLOAT16] = { parse_type_identifier, NULL, PREC_NONE }, + [TOKEN_FLOAT128] = { parse_type_identifier, NULL, PREC_NONE }, [TOKEN_VOID] = { parse_type_identifier, NULL, PREC_NONE }, [TOKEN_TYPEID] = { parse_type_identifier, NULL, PREC_NONE }, [TOKEN_ANYERR] = { parse_type_identifier, NULL, PREC_NONE }, diff --git a/src/compiler/target.c b/src/compiler/target.c index 8b54e1617..436444a00 100644 --- a/src/compiler/target.c +++ b/src/compiler/target.c @@ -208,6 +208,22 @@ static inline bool os_is_apple(OsType os_type) os_type == OS_TYPE_MACOSX || os_type == OS_TYPE_IOS; } +static AlignSize os_arch_max_alignment_of_vector(OsType os, ArchType arch) +{ + switch (arch) + { + case ARCH_TYPE_AARCH64: + return 128 / 8; + case ARCH_TYPE_ARM: + case ARCH_TYPE_ARMB: + // Only if aapcs and not android + REMINDER("Check if AAPCS"); + return 64 / 8; + default: + return 0; + } +} + static bool os_target_signed_c_char_type(OsType os, ArchType arch) { switch (arch) @@ -1227,7 +1243,7 @@ void target_setup(BuildTarget *target) platform_target.width_c_long = os_target_c_type_bits(platform_target.os, platform_target.arch, CTYPE_LONG); platform_target.width_c_long_long = os_target_c_type_bits(platform_target.os, platform_target.arch, CTYPE_LONG_LONG); platform_target.signed_c_char = os_target_signed_c_char_type(platform_target.os, platform_target.arch); - + platform_target.align_max_vector = os_arch_max_alignment_of_vector(platform_target.os, platform_target.arch); /** * x86-64: CMOV, CMPXCHG8B, FPU, FXSR, MMX, FXSR, SCE, SSE, SSE2 * x86-64-v2: (close to Nehalem) CMPXCHG16B, LAHF-SAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3 diff --git a/src/compiler/tokens.c b/src/compiler/tokens.c index 8c8918dd8..bde20a41a 100644 --- a/src/compiler/tokens.c +++ b/src/compiler/tokens.c @@ -268,8 +268,8 @@ const char *token_type_to_string(TokenType type) return "void"; case TOKEN_BOOL: return "bool"; - case TOKEN_QUAD: - return "quad"; + case TOKEN_FLOAT128: + return "float128"; case TOKEN_DOUBLE: return "double"; case TOKEN_FLOAT: @@ -278,10 +278,10 @@ const char *token_type_to_string(TokenType type) return "long"; case TOKEN_ULONG: return "ulong"; - case TOKEN_I128: - return "i128"; - case TOKEN_U128: - return "u128"; + case TOKEN_INT128: + return "int128"; + case TOKEN_UINT128: + return "uint128"; case TOKEN_INT: return "int"; case TOKEN_UINT: @@ -306,8 +306,8 @@ const char *token_type_to_string(TokenType type) return "iptrdiff"; case TOKEN_UPTRDIFF: return "uptrdiff"; - case TOKEN_HALF: - return "half"; + case TOKEN_FLOAT16: + return "float16"; case TOKEN_DOCS_EOL: return "EOL"; case TOKEN_DOCS_START: diff --git a/src/compiler/types.c b/src/compiler/types.c index 07ce8c876..7135b9b7d 100644 --- a/src/compiler/types.c +++ b/src/compiler/types.c @@ -53,6 +53,7 @@ static unsigned size_subarray; static AlignSize alignment_subarray; unsigned size_error_code; unsigned alignment_error_code; +static AlignSize max_alignment_vector; #define PTR_OFFSET 0 #define INFERRED_ARRAY_OFFSET 1 @@ -191,7 +192,15 @@ ByteSize type_size(Type *type) case TYPE_DISTINCT: return type_size(type->decl->distinct_decl.base_type); case TYPE_VECTOR: - return type_size(type->vector.base) * type->vector.len; + { + ByteSize width = type_size(type->vector.base) * type->vector.len; + if (width & (width - 1)) + { + ByteSize alignment = next_highest_power_of_2(width); + width = aligned_offset(width, alignment); + } + return width; + } case TYPE_POISONED: case TYPE_TYPEINFO: case TYPE_INFERRED_ARRAY: @@ -645,7 +654,16 @@ AlignSize type_abi_alignment(Type *type) case TYPE_INFERRED_ARRAY: UNREACHABLE; case TYPE_VECTOR: - TODO + { + ByteSize width = type_size(type->vector.base) * type->vector.len; + ByteSize alignment = width; + if (alignment & (alignment - 1)) + { + alignment = next_highest_power_of_2(alignment); + } + if (max_alignment_vector && alignment > max_alignment_vector) alignment = max_alignment_vector; + return alignment; + } case TYPE_VOID: return 1; case TYPE_DISTINCT: @@ -1107,7 +1125,7 @@ Type *type_find_function_type(FunctionSignature *signature) void type_setup(PlatformTarget *target) { stable_init(&function_types, 0x1000); - + max_alignment_vector = target->align_max_vector; /*TODO * decl_string = (Decl) { .decl_kind = DECL_BUILTIN, .name.string = "string" }; create_type(&decl_string, &type_string); @@ -1244,7 +1262,7 @@ Type *type_from_token(TokenType type) return type_double; case TOKEN_FLOAT: return type_float; - case TOKEN_I128: + case TOKEN_INT128: return type_i128; case TOKEN_ICHAR: return type_ichar; @@ -1260,7 +1278,7 @@ Type *type_from_token(TokenType type) return type_long; case TOKEN_SHORT: return type_short; - case TOKEN_U128: + case TOKEN_UINT128: return type_u128; case TOKEN_UINT: return type_uint;