From 3e465c7e84490ea73f9419286fd53e95ba911c38 Mon Sep 17 00:00:00 2001 From: Platin21 Date: Sun, 19 Dec 2021 21:51:51 +0100 Subject: [PATCH 1/6] Changes to required llvm version 13 as both 12 and 11 don't work correctly on macOS Apple Silicon --- Makefile | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 23fb7be66..a7aecbb2d 100644 --- a/Makefile +++ b/Makefile @@ -8,11 +8,21 @@ CC=clang OS=$(shell uname) ifeq ($(OS), Darwin) + ARCH=$(shell uname -m) LLVM_CONFIG=llvm-config - ifneq ($(shell llvm-config --version | grep '^11\.'),) + + # LLVM Version Setting + LLVM_VERSION_PATTERN="^11\." + LLVM_VERSION="11" + ifeq ($(ARCH), arm64) + LLVM_VERSION="13" + LLVM_VERSION_PATTERN="^13" + endif + + ifneq ($(shell llvm-config --version | grep $(LLVM_VERSION_PATTERN)),) LLVM_CONFIG=llvm-config else - $(error "Requirement: llvm-config must be version 11") + $(error "Requirement: llvm-config must be version $(LLVM_VERSION)") endif LDFLAGS:=$(LDFLAGS) -liconv From e2b36c4004130f8566ec63037cfc584b7318c91c Mon Sep 17 00:00:00 2001 From: Tetralux Date: Tue, 21 Dec 2021 02:11:56 +0000 Subject: [PATCH 2/6] Rename slice.to_dynamic to slice.clone_to_dynamic --- core/slice/slice.odin | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/slice/slice.odin b/core/slice/slice.odin index 487dd46c2..a82c5fa96 100644 --- a/core/slice/slice.odin +++ b/core/slice/slice.odin @@ -185,7 +185,7 @@ concatenate :: proc(a: []$T/[]$E, allocator := context.allocator) -> (res: T) { return } -// copies slice into a new dynamic array +// copies a slice into a new slice clone :: proc(a: $T/[]$E, allocator := context.allocator) -> []E { d := make([]E, len(a), allocator) copy(d[:], a) @@ -194,11 +194,12 @@ clone :: proc(a: $T/[]$E, allocator := context.allocator) -> []E { // copies slice into a new dynamic array -to_dynamic :: proc(a: $T/[]$E, allocator := context.allocator) -> [dynamic]E { +clone_to_dynamic :: proc(a: $T/[]$E, allocator := context.allocator) -> [dynamic]E { d := make([dynamic]E, len(a), allocator) copy(d[:], a) return d } +to_dynamic :: clone_to_dynamic // Converts slice into a dynamic array without cloning or allocating memory into_dynamic :: proc(a: $T/[]$E) -> [dynamic]E { From 8dbeed8a9faba5b341823ae3a4ea4f7a453f3f87 Mon Sep 17 00:00:00 2001 From: Platin21 Date: Thu, 23 Dec 2021 01:59:31 +0100 Subject: [PATCH 3/6] Removes unneeded lookups / Adds sret to call site which fixes the mac bug --- src/llvm_abi.cpp | 12 ++++++------ src/llvm_backend_proc.cpp | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index e18dc344b..c30f6531a 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -981,16 +981,16 @@ namespace lbAbiArm64 { if (size <= 16) { LLVMTypeRef cast_type = nullptr; if (size <= 1) { - cast_type = LLVMIntTypeInContext(c, 8); + cast_type = LLVMInt8TypeInContext(c); } else if (size <= 2) { - cast_type = LLVMIntTypeInContext(c, 16); + cast_type = LLVMInt16TypeInContext(c); } else if (size <= 4) { - cast_type = LLVMIntTypeInContext(c, 32); + cast_type = LLVMInt32TypeInContext(c); } else if (size <= 8) { - cast_type = LLVMIntTypeInContext(c, 64); + cast_type = LLVMInt64TypeInContext(c); } else { unsigned count = cast(unsigned)((size+7)/8); - cast_type = LLVMArrayType(LLVMIntTypeInContext(c, 64), count); + cast_type = LLVMArrayType(LLVMInt64TypeInContext(c), count); } return lb_arg_type_direct(type, cast_type, nullptr, nullptr); } else { @@ -999,7 +999,7 @@ namespace lbAbiArm64 { } } } - + Array compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) { auto args = array_make(heap_allocator(), arg_count); diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 25b27ee47..84fddd9e2 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -736,6 +736,10 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr, LLVMValueRef ret = LLVMBuildCall2(p->builder, fnp, fn, args, arg_count, ""); + if (return_ptr.value != nullptr) { + LLVMAddCallSiteAttribute(ret, 1, lb_create_enum_attribute_with_type(p->module->ctx, "sret", LLVMTypeOf(args[0]))); + } + switch (inlining) { case ProcInlining_none: break; From dce120258fbca70dfaa9a738bc168463df7a3dda Mon Sep 17 00:00:00 2001 From: Yawning Angel Date: Thu, 23 Dec 2021 02:46:32 +0000 Subject: [PATCH 4/6] src: Add preliminary support for Linux AArch64 Tested via `tests/core`, on a Raspberry Pi 4 running the latest 64-bit Raspberry Pi OS image (LLVM 11). --- src/build_settings.cpp | 14 ++++++++++++++ src/gb/gb.h | 2 ++ src/threading.cpp | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 29abd441c..b8d50898d 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -300,6 +300,14 @@ gb_global TargetMetrics target_linux_amd64 = { str_lit("x86_64-pc-linux-gnu"), str_lit("e-m:w-i64:64-f80:128-n8:16:32:64-S128"), }; +gb_global TargetMetrics target_linux_arm64 = { + TargetOs_linux, + TargetArch_arm64, + 8, + 16, + str_lit("aarch64-linux-elf"), + str_lit("e-m:e-i8:8:32-i16:32-i64:64-i128:128-n32:64-S128"), +}; gb_global TargetMetrics target_darwin_amd64 = { TargetOs_darwin, @@ -394,6 +402,7 @@ gb_global NamedTargetMetrics named_targets[] = { { str_lit("essence_amd64"), &target_essence_amd64 }, { str_lit("linux_386"), &target_linux_386 }, { str_lit("linux_amd64"), &target_linux_amd64 }, + { str_lit("linux_arm64"), &target_linux_arm64 }, { str_lit("windows_386"), &target_windows_386 }, { str_lit("windows_amd64"), &target_windows_amd64 }, { str_lit("freebsd_386"), &target_freebsd_386 }, @@ -880,6 +889,8 @@ void init_build_context(TargetMetrics *cross_target) { #endif #elif defined(GB_SYSTEM_FREEBSD) metrics = &target_freebsd_amd64; + #elif defined(GB_CPU_ARM) + metrics = &target_linux_arm64; #else metrics = &target_linux_amd64; #endif @@ -959,6 +970,9 @@ void init_build_context(TargetMetrics *cross_target) { case TargetOs_darwin: bc->link_flags = str_lit("-arch arm64 "); break; + case TargetOs_linux: + bc->link_flags = str_lit("-arch aarch64 "); + break; } } else if (is_arch_wasm()) { gbString link_flags = gb_string_make(heap_allocator(), " "); diff --git a/src/gb/gb.h b/src/gb/gb.h index f716b0840..d9bf09436 100644 --- a/src/gb/gb.h +++ b/src/gb/gb.h @@ -3355,6 +3355,8 @@ gb_inline u32 gb_thread_current_id(void) { __asm__("mov %%gs:0x08,%0" : "=r"(thread_id)); #elif defined(GB_ARCH_64_BIT) && defined(GB_CPU_X86) __asm__("mov %%fs:0x10,%0" : "=r"(thread_id)); +#elif defined(GB_SYSTEM_LINUX) + thread_id = gettid(); #else #error Unsupported architecture for gb_thread_current_id() #endif diff --git a/src/threading.cpp b/src/threading.cpp index e9412b411..b318e4ff1 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -296,6 +296,8 @@ u32 thread_current_id(void) { __asm__("mov %%gs:0x08,%0" : "=r"(thread_id)); #elif defined(GB_ARCH_64_BIT) && defined(GB_CPU_X86) __asm__("mov %%fs:0x10,%0" : "=r"(thread_id)); +#elif defined(GB_SYSTEM_LINUX) + thread_id = gettid(); #else #error Unsupported architecture for thread_current_id() #endif @@ -315,6 +317,8 @@ gb_inline void yield_thread(void) { #endif #elif defined(GB_CPU_X86) _mm_pause(); +#elif defined(GB_CPU_ARM) + __asm__ volatile ("yield" : : : "memory"); #else #error Unknown architecture #endif From 9b2fe56d149fa23b03b678de2eb51c4f599d2711 Mon Sep 17 00:00:00 2001 From: Tetralux Date: Sat, 25 Dec 2021 18:53:20 +0000 Subject: [PATCH 5/6] Parse #no_nil on unions --- core/odin/ast/ast.odin | 1 + core/odin/parser/parser.odin | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/core/odin/ast/ast.odin b/core/odin/ast/ast.odin index 260979d89..9db57541b 100644 --- a/core/odin/ast/ast.odin +++ b/core/odin/ast/ast.odin @@ -711,6 +711,7 @@ Union_Type :: struct { poly_params: ^Field_List, align: ^Expr, is_maybe: bool, + is_no_nil: bool, where_token: tokenizer.Token, where_clauses: []^Expr, variants: []^Expr, diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 52d4b5e5a..aade2051a 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -2600,6 +2600,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { poly_params: ^ast.Field_List align: ^ast.Expr is_maybe: bool + is_no_nil: bool if allow_token(p, .Open_Paren) { param_count: int @@ -2626,6 +2627,11 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { error(p, tag.pos, "duplicate union tag '#%s'", tag.text) } is_maybe = true + case "no_nil": + if is_no_nil { + error(p, tag.pos, "duplicate union tag '#%s'", tag.text) + } + is_no_nil = true case: error(p, tag.pos, "invalid union tag '#%s", tag.text) } @@ -2669,6 +2675,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { ut.where_token = where_token ut.where_clauses = where_clauses ut.is_maybe = is_maybe + ut.is_no_nil = is_no_nil return ut From a60667e900f3e7f3b6253019961a17b65b76e479 Mon Sep 17 00:00:00 2001 From: Tetralux Date: Sat, 25 Dec 2021 19:17:34 +0000 Subject: [PATCH 6/6] core:odin/parser: Fix parsing of Allman style braces in for loops --- core/odin/parser/parser.odin | 1 + 1 file changed, 1 insertion(+) diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 52d4b5e5a..679623108 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -888,6 +888,7 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt { error(p, body.pos, "the body of a 'do' must be on the same line as the 'for' token") } } else { + allow_token(p, .Semicolon) body = parse_body(p) }