Bladeren bron

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

gingerBill 4 jaren geleden
bovenliggende
commit
3d5e180dec
6 gewijzigde bestanden met toevoegingen van 284 en 132 verwijderingen
  1. 10 1
      .github/workflows/nightly.yml
  2. 1 1
      Makefile
  3. 1 1
      README.md
  4. 135 0
      core/runtime/internal_linux.odin
  5. 92 92
      core/runtime/internal_windows.odin
  6. 45 37
      src/main.cpp

+ 10 - 1
.github/workflows/nightly.yml

@@ -1,6 +1,7 @@
 name:  Nightly
 
 on:
+  workflow_dispatch:
   schedule:
     - cron: 0 20 * * *
 
@@ -96,10 +97,18 @@ jobs:
     needs: [build_windows, build_macos, build_ubuntu]
     steps:
       - uses: actions/checkout@v1
+      - uses: actions/setup-python@v2
+        with:
+          python-version: '3.x'
       
       - name: Install B2 CLI
         shell: bash
-        run: sudo pip install --upgrade b2
+        run: |
+          python -m pip install --upgrade pip
+          pip install --upgrade b2
+      
+      - name: Display Python version
+        run: python -c "import sys; print(sys.version)"
       
       - name: Download Windows artifacts
         uses: actions/download-artifact@v1

+ 1 - 1
Makefile

@@ -22,7 +22,7 @@ release:
 	$(CC) src/main.cpp $(DISABLED_WARNINGS) $(CFLAGS) -O3 -march=native $(LDFLAGS) -o odin
 
 nightly:
-	$(CC) src/main.cpp $(DISABLED_WARNINGS) $(CFLAGS) -DNIGHTLY -O3 -march=native $(LDFLAGS) -o odin
+	$(CC) src/main.cpp $(DISABLED_WARNINGS) $(CFLAGS) -DNIGHTLY -O3 $(LDFLAGS) -o odin
 
 
 

+ 1 - 1
README.md

@@ -60,7 +60,7 @@ main :: proc() {
 
 #### [Getting Started](https://odin-lang.org/docs/install)
 
-Instructions for downloading and install the Odin compiler and libraries.
+Instructions for downloading and installing the Odin compiler and libraries.
 
 ### Learning Odin
 

+ 135 - 0
core/runtime/internal_linux.odin

@@ -0,0 +1,135 @@
+package runtime
+
+@(link_name="__umodti3")
+umodti3 :: proc "c" (a, b: u128) -> u128 {
+	r: u128 = ---;
+	_ = udivmod128(a, b, &r);
+	return r;
+}
+
+
+@(link_name="__udivmodti4")
+udivmodti4 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {
+	return udivmod128(a, b, rem);
+}
+
+@(link_name="__udivti3")
+udivti3 :: proc "c" (a, b: u128) -> u128 {
+	return udivmodti4(a, b, nil);
+}
+
+
+@(link_name="__modti3")
+modti3 :: proc "c" (a, b: i128) -> i128 {
+	s_a := a >> (128 - 1);
+	s_b := b >> (128 - 1);
+	an := (a ~ s_a) - s_a;
+	bn := (b ~ s_b) - s_b;
+
+	r: u128 = ---;
+	_ = udivmod128(transmute(u128)an, transmute(u128)bn, &r);
+	return (transmute(i128)r ~ s_a) - s_a;
+}
+
+
+@(link_name="__divmodti4")
+divmodti4 :: proc "c" (a, b: i128, rem: ^i128) -> i128 {
+	u := udivmod128(transmute(u128)a, transmute(u128)b, cast(^u128)rem);
+	return transmute(i128)u;
+}
+
+@(link_name="__divti3")
+divti3 :: proc "c" (a, b: i128) -> i128 {
+	u := udivmodti4(transmute(u128)a, transmute(u128)b, nil);
+	return transmute(i128)u;
+}
+
+
+@(link_name="__fixdfti")
+fixdfti :: proc(a: u64) -> i128 {
+	significandBits :: 52;
+	typeWidth       :: (size_of(u64)*8);
+	exponentBits    :: (typeWidth - significandBits - 1);
+	maxExponent     :: ((1 << exponentBits) - 1);
+	exponentBias    :: (maxExponent >> 1);
+
+	implicitBit     :: (u64(1) << significandBits);
+	significandMask :: (implicitBit - 1);
+	signBit         :: (u64(1) << (significandBits + exponentBits));
+	absMask         :: (signBit - 1);
+	exponentMask    :: (absMask ~ significandMask);
+
+	// Break a into sign, exponent, significand
+	aRep := a;
+	aAbs := aRep & absMask;
+	sign := i128(-1 if aRep & signBit != 0 else 1);
+	exponent := u64((aAbs >> significandBits) - exponentBias);
+	significand := u64((aAbs & significandMask) | implicitBit);
+
+	// If exponent is negative, the result is zero.
+	if exponent < 0 {
+		return 0;
+	}
+
+	// If the value is too large for the integer type, saturate.
+	if exponent >= size_of(i128) * 8 {
+		return max(i128) if sign == 1 else min(i128);
+	}
+
+	// If 0 <= exponent < significandBits, right shift to get the result.
+	// Otherwise, shift left.
+	if exponent < significandBits {
+		return sign * i128(significand >> (significandBits - exponent));
+	} else {
+		return sign * (i128(significand) << (exponent - significandBits));
+	}
+
+}
+
+@(default_calling_convention = "none")
+foreign {
+	@(link_name="llvm.ctlz.i128") _clz_i128 :: proc(x: i128, is_zero_undef := false) -> i128 ---
+}
+
+
+@(link_name="__floattidf")
+floattidf :: proc(a: i128) -> f64 {
+	DBL_MANT_DIG :: 53;
+	if a == 0 {
+		return 0.0;
+	}
+	a := a;
+	N :: size_of(i128) * 8;
+	s := a >> (N-1);
+	a = (a ~ s) - s;
+	sd: = N - _clz_i128(a);  // number of significant digits
+	e := u32(sd - 1);        // exponent 
+	if sd > DBL_MANT_DIG {
+		switch sd {
+		case DBL_MANT_DIG + 1:
+			a <<= 1;
+		case DBL_MANT_DIG + 2:
+			// okay
+		case:
+			a = i128(u128(a) >> u128(sd - (DBL_MANT_DIG+2))) |
+				i128(u128(a) & (~u128(0) >> u128(N + DBL_MANT_DIG+2 - sd)) != 0);
+		};
+
+		a |= i128((a & 4) != 0);  
+		a += 1; 
+		a >>= 2;
+
+		if a & (1 << DBL_MANT_DIG) != 0 {
+			a >>= 1;
+			e += 1;
+		}
+	} else {
+		a <<= u128(DBL_MANT_DIG - sd);
+	}
+	fb: [2]u32;
+	fb[1] = (u32(s) & 0x80000000) |        // sign
+	        ((e + 1023) << 20)      |      // exponent
+	        ((u32(a) >> 32) & 0x000FFFFF); // mantissa-high
+	fb[1] = u32(a);                        // mantissa-low
+	return transmute(f64)fb;
+}

+ 92 - 92
core/runtime/internal_windows.odin

@@ -2,134 +2,134 @@ package runtime
 
 @(link_name="__umodti3")
 umodti3 :: proc "c" (a, b: u128) -> u128 {
-	r: u128 = ---;
-	_ = udivmod128(a, b, &r);
-	return r;
+    r: u128 = ---;
+    _ = udivmod128(a, b, &r);
+    return r;
 }
 
 
 @(link_name="__udivmodti4")
 udivmodti4 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {
-	return udivmod128(a, b, rem);
+    return udivmod128(a, b, rem);
 }
 
 @(link_name="__udivti3")
 udivti3 :: proc "c" (a, b: u128) -> u128 {
-	return udivmodti4(a, b, nil);
+    return udivmodti4(a, b, nil);
 }
 
 
 @(link_name="__modti3")
 modti3 :: proc "c" (a, b: i128) -> i128 {
-	s_a := a >> (128 - 1);
-	s_b := b >> (128 - 1);
-	an := (a ~ s_a) - s_a;
-	bn := (b ~ s_b) - s_b;
-
-	r: u128 = ---;
-	_ = udivmod128(transmute(u128)an, transmute(u128)bn, &r);
-	return (transmute(i128)r ~ s_a) - s_a;
+    s_a := a >> (128 - 1);
+    s_b := b >> (128 - 1);
+    an := (a ~ s_a) - s_a;
+    bn := (b ~ s_b) - s_b;
+
+    r: u128 = ---;
+    _ = udivmod128(transmute(u128)an, transmute(u128)bn, &r);
+    return (transmute(i128)r ~ s_a) - s_a;
 }
 
 
 @(link_name="__divmodti4")
 divmodti4 :: proc "c" (a, b: i128, rem: ^i128) -> i128 {
-	u := udivmod128(transmute(u128)a, transmute(u128)b, cast(^u128)rem);
-	return transmute(i128)u;
+    u := udivmod128(transmute(u128)a, transmute(u128)b, cast(^u128)rem);
+    return transmute(i128)u;
 }
 
 @(link_name="__divti3")
 divti3 :: proc "c" (a, b: i128) -> i128 {
-	u := udivmodti4(transmute(u128)a, transmute(u128)b, nil);
-	return transmute(i128)u;
+    u := udivmodti4(transmute(u128)a, transmute(u128)b, nil);
+    return transmute(i128)u;
 }
 
 
 @(link_name="__fixdfti")
 fixdfti :: proc(a: u64) -> i128 {
-	significandBits :: 52;
-	typeWidth       :: (size_of(u64)*8);
-	exponentBits    :: (typeWidth - significandBits - 1);
-	maxExponent     :: ((1 << exponentBits) - 1);
-	exponentBias    :: (maxExponent >> 1);
-
-	implicitBit     :: (u64(1) << significandBits);
-	significandMask :: (implicitBit - 1);
-	signBit         :: (u64(1) << (significandBits + exponentBits));
-	absMask         :: (signBit - 1);
-	exponentMask    :: (absMask ~ significandMask);
-
-	// Break a into sign, exponent, significand
-	aRep := a;
-	aAbs := aRep & absMask;
-	sign := i128(-1 if aRep & signBit != 0 else 1);
-	exponent := u64((aAbs >> significandBits) - exponentBias);
-	significand := u64((aAbs & significandMask) | implicitBit);
-
-	// If exponent is negative, the result is zero.
-	if exponent < 0 {
-		return 0;
-	}
-
-	// If the value is too large for the integer type, saturate.
-	if exponent >= size_of(i128) * 8 {
-		return max(i128) if sign == 1 else min(i128);
-	}
-
-	// If 0 <= exponent < significandBits, right shift to get the result.
-	// Otherwise, shift left.
-	if exponent < significandBits {
-		return sign * i128(significand >> (significandBits - exponent));
-	} else {
-		return sign * (i128(significand) << (exponent - significandBits));
-	}
+    significandBits :: 52;
+    typeWidth       :: (size_of(u64)*8);
+    exponentBits    :: (typeWidth - significandBits - 1);
+    maxExponent     :: ((1 << exponentBits) - 1);
+    exponentBias    :: (maxExponent >> 1);
+
+    implicitBit     :: (u64(1) << significandBits);
+    significandMask :: (implicitBit - 1);
+    signBit         :: (u64(1) << (significandBits + exponentBits));
+    absMask         :: (signBit - 1);
+    exponentMask    :: (absMask ~ significandMask);
+
+    // Break a into sign, exponent, significand
+    aRep := a;
+    aAbs := aRep & absMask;
+    sign := i128(-1 if aRep & signBit != 0 else 1);
+    exponent := u64((aAbs >> significandBits) - exponentBias);
+    significand := u64((aAbs & significandMask) | implicitBit);
+
+    // If exponent is negative, the result is zero.
+    if exponent < 0 {
+        return 0;
+    }
+
+    // If the value is too large for the integer type, saturate.
+    if exponent >= size_of(i128) * 8 {
+        return max(i128) if sign == 1 else min(i128);
+    }
+
+    // If 0 <= exponent < significandBits, right shift to get the result.
+    // Otherwise, shift left.
+    if exponent < significandBits {
+        return sign * i128(significand >> (significandBits - exponent));
+    } else {
+        return sign * (i128(significand) << (exponent - significandBits));
+    }
 
 }
 
 @(default_calling_convention = "none")
 foreign {
-	@(link_name="llvm.ctlz.i128") _clz_i128 :: proc(x: i128, is_zero_undef := false) -> i128 ---
+    @(link_name="llvm.ctlz.i128") _clz_i128 :: proc(x: i128, is_zero_undef := false) -> i128 ---
 }
 
 
 @(link_name="__floattidf")
 floattidf :: proc(a: i128) -> f64 {
-	DBL_MANT_DIG :: 53;
-	if a == 0 {
-		return 0.0;
-	}
-	a := a;
-	N :: size_of(i128) * 8;
-	s := a >> (N-1);
-	a = (a ~ s) - s;
-	sd: = N - _clz_i128(a);  // number of significant digits
-	e := u32(sd - 1);        // exponent 
-	if sd > DBL_MANT_DIG {
-		switch sd {
-		case DBL_MANT_DIG + 1:
-			a <<= 1;
-		case DBL_MANT_DIG + 2:
-			// okay
-		case:
-			a = i128(u128(a) >> u128(sd - (DBL_MANT_DIG+2))) |
-				i128(u128(a) & (~u128(0) >> u128(N + DBL_MANT_DIG+2 - sd)) != 0);
-		};
-
-		a |= i128((a & 4) != 0);  
-		a += 1; 
-		a >>= 2;
-
-		if a & (1 << DBL_MANT_DIG) != 0 {
-			a >>= 1;
-			e += 1;
-		}
-	} else {
-		a <<= u128(DBL_MANT_DIG - sd);
-	}
-	fb: [2]u32;
-	fb[1] = (u32(s) & 0x80000000) |        // sign
-	        ((e + 1023) << 20)      |      // exponent
-	        ((u32(a) >> 32) & 0x000FFFFF); // mantissa-high
-	fb[1] = u32(a);                        // mantissa-low
-	return transmute(f64)fb;
+    DBL_MANT_DIG :: 53;
+    if a == 0 {
+        return 0.0;
+    }
+    a := a;
+    N :: size_of(i128) * 8;
+    s := a >> (N-1);
+    a = (a ~ s) - s;
+    sd: = N - _clz_i128(a);  // number of significant digits
+    e := u32(sd - 1);        // exponent 
+    if sd > DBL_MANT_DIG {
+        switch sd {
+        case DBL_MANT_DIG + 1:
+            a <<= 1;
+        case DBL_MANT_DIG + 2:
+            // okay
+        case:
+            a = i128(u128(a) >> u128(sd - (DBL_MANT_DIG+2))) |
+                i128(u128(a) & (~u128(0) >> u128(N + DBL_MANT_DIG+2 - sd)) != 0);
+        };
+
+        a |= i128((a & 4) != 0);  
+        a += 1; 
+        a >>= 2;
+
+        if a & (1 << DBL_MANT_DIG) != 0 {
+            a >>= 1;
+            e += 1;
+        }
+    } else {
+        a <<= u128(DBL_MANT_DIG - sd);
+    }
+    fb: [2]u32;
+    fb[1] = (u32(s) & 0x80000000) |        // sign
+            ((e + 1023) << 20)      |      // exponent
+            ((u32(a) >> 32) & 0x000FFFFF); // mantissa-high
+    fb[1] = u32(a);                        // mantissa-low
+    return transmute(f64)fb;
 }

+ 45 - 37
src/main.cpp

@@ -342,9 +342,9 @@ i32 linker_stage(lbGenerator *gen) {
 					lib_name = remove_extension_from_path(lib_name);
 					lib_str = gb_string_append_fmt(lib_str, " -framework %.*s ", LIT(lib_name));
 				} else if (string_ends_with(lib, str_lit(".a")) || string_ends_with(lib, str_lit(".o")) || string_ends_with(lib, str_lit(".dylib"))) {
-          				// For:
-          				// object 
-          				// dynamic lib
+					// For:
+					// object
+					// dynamic lib
 					// static libs, absolute full path relative to the file in which the lib was imported from
 					lib_str = gb_string_append_fmt(lib_str, " %.*s ", LIT(lib));
 				} else {
@@ -382,20 +382,33 @@ i32 linker_stage(lbGenerator *gen) {
 		// Unlike the Win32 linker code, the output_ext includes the dot, because
 		// typically executable files on *NIX systems don't have extensions.
 		String output_ext = {};
-		char const *link_settings = "";
+		gbString link_settings = gb_string_make_reserve(heap_allocator(), 32);
 		char const *linker;
 		if (build_context.build_mode == BuildMode_DynamicLibrary) {
+			// NOTE(tetra, 2020-11-06): __$startup_runtime must be called at DLL load time.
+			// Clang, for some reason, won't let us pass the '-init' flag that lets us do this,
+			// so use ld instead.
+			// :UseLDForShared
+			linker = "ld";
+			link_settings = gb_string_appendc(link_settings, "-init '__$startup_runtime' ");
 			// Shared libraries are .dylib on MacOS and .so on Linux.
 			#if defined(GB_SYSTEM_OSX)
 				output_ext = STR_LIT(".dylib");
-				link_settings = "-dylib -dynamic";
+				link_settings = gb_string_appendc(link_settings, "-dylib -dynamic ");
 			#else
 				output_ext = STR_LIT(".so");
-				link_settings = "-shared";
+				link_settings = gb_string_appendc(link_settings, "-shared ");
 			#endif
 		} else {
-			// TODO: Do I need anything here?
-			link_settings = "";
+			#if defined(GB_SYSTEM_OSX)
+				linker = "ld";
+			#else
+				// TODO(zangent): Figure out how to make ld work on Linux.
+				//   It probably has to do with including the entire CRT, but
+				//   that's quite a complicated issue to solve while remaining distro-agnostic.
+				//   Clang can figure out linker flags for us, and that's good enough _for now_.
+				linker = "clang -Wno-unused-command-line-argument";
+			#endif
 		}
 
 		if (build_context.out_filepath.len > 0) {
@@ -406,16 +419,6 @@ i32 linker_stage(lbGenerator *gen) {
 			}
 		}
 
-		#if defined(GB_SYSTEM_OSX)
-			linker = "ld";
-		#else
-			// TODO(zangent): Figure out how to make ld work on Linux.
-			//   It probably has to do with including the entire CRT, but
-			//   that's quite a complicated issue to solve while remaining distro-agnostic.
-			//   Clang can figure out linker flags for us, and that's good enough _for now_.
-			linker = "clang -Wno-unused-command-line-argument";
-		#endif
-
 		exit_code = system_exec_command_line_app("ld-link",
 			"%s %s -o \"%.*s%.*s\" %s "
 			" %s "
@@ -443,7 +446,7 @@ i32 linker_stage(lbGenerator *gen) {
 		if (exit_code != 0) {
 			return exit_code;
 		}
-    
+
 	#if defined(GB_SYSTEM_OSX)
 		if (build_context.ODIN_DEBUG) {
 			// NOTE: macOS links DWARF symbols dynamically. Dsymutil will map the stubs in the exe
@@ -2136,11 +2139,11 @@ int main(int arg_count, char const **arg_ptr) {
 						String lib_name = lib;
 						lib_name = remove_extension_from_path(lib_name);
 						lib_str = gb_string_append_fmt(lib_str, " -framework %.*s ", LIT(lib_name));
-						
+
 				} else if (string_ends_with(lib, str_lit(".a")) || string_ends_with(lib, str_lit(".o")) || string_ends_with(lib, str_lit(".dylib"))) {
-          				// For:
-          				// object 
-          				// dynamic lib
+					// For:
+					// object
+					// dynamic lib
 					// static libs, absolute full path relative to the file in which the lib was imported from
 					lib_str = gb_string_append_fmt(lib_str, " %.*s ", LIT(lib));
 				} else {
@@ -2171,22 +2174,36 @@ int main(int arg_count, char const **arg_ptr) {
 			// Unlike the Win32 linker code, the output_ext includes the dot, because
 			// typically executable files on *NIX systems don't have extensions.
 			String output_ext = {};
-			char const *link_settings = "";
+			gbString link_settings = gb_string_make_reserve(heap_allocator(), 32);
 			char const *linker;
 			if (build_context.build_mode == BuildMode_DynamicLibrary) {
+				// NOTE(tetra, 2020-11-06): __$startup_runtime must be called at DLL load time.
+				// Clang, for some reason, won't let us pass the '-init' flag that lets us do this,
+				// so use ld instead.
+				// :UseLDForShared
+				linker = "ld";
+				link_settings = gb_string_appendc(link_settings, "-init '__$startup_runtime' ");
 				// Shared libraries are .dylib on MacOS and .so on Linux.
 				#if defined(GB_SYSTEM_OSX)
 					output_ext = STR_LIT(".dylib");
-					link_settings = "-dylib -dynamic";
+					link_settings = gb_string_appendc(link_settings, "-dylib -dynamic ");
 				#else
 					output_ext = STR_LIT(".so");
-					link_settings = "-shared";
+					link_settings = gb_string_appendc(link_settings, "-shared ");
 				#endif
 			} else {
-				// TODO: Do I need anything here?
-				link_settings = "";
+				#if defined(GB_SYSTEM_OSX)
+					linker = "ld";
+				#else
+					// TODO(zangent): Figure out how to make ld work on Linux.
+					//   It probably has to do with including the entire CRT, but
+					//   that's quite a complicated issue to solve while remaining distro-agnostic.
+					//   Clang can figure out linker flags for us, and that's good enough _for now_.
+					linker = "clang -Wno-unused-command-line-argument";
+				#endif
 			}
 
+
 			if (build_context.out_filepath.len > 0) {
 				//NOTE(thebirk): We have a custom -out arguments, so we should use the extension from that
 				isize pos = string_extension_position(build_context.out_filepath);
@@ -2195,15 +2212,6 @@ int main(int arg_count, char const **arg_ptr) {
 				}
 			}
 
-			#if defined(GB_SYSTEM_OSX)
-				linker = "ld";
-			#else
-				// TODO(zangent): Figure out how to make ld work on Linux.
-				//   It probably has to do with including the entire CRT, but
-				//   that's quite a complicated issue to solve while remaining distro-agnostic.
-				//   Clang can figure out linker flags for us, and that's good enough _for now_.
-				linker = "clang -Wno-unused-command-line-argument";
-			#endif
 
 			exit_code = system_exec_command_line_app("ld-link",
 				"%s \"%.*s.o\" -o \"%.*s%.*s\" %s "