Kaynağa Gözat

Merge branch 'master' of https://github.com/odin-lang/Odin

gingerBill 3 yıl önce
ebeveyn
işleme
5d653a9d8e

+ 12 - 2
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

+ 1 - 0
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,

+ 8 - 0
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)
 	}
 
@@ -2600,6 +2601,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 +2628,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 +2676,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
 

+ 3 - 2
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 {

+ 14 - 0
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(), " ");

+ 2 - 0
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

+ 6 - 6
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<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) {
 		auto args = array_make<lbArgType>(heap_allocator(), arg_count);
 

+ 4 - 0
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;

+ 4 - 0
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