Commit 80790be309

Jakub Konka <kubkon@jakubkonka.com>
2022-06-10 10:25:59
compiler_rt: compile each unit separately for improved archiving
1 parent 33cf6ef
lib/compiler_rt/absv.zig
@@ -1,6 +1,16 @@
 // absv - absolute oVerflow
 // * @panic, if value can not be represented
 // - absvXi4_generic for unoptimized version
+const std = @import("std");
+const builtin = @import("builtin");
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__absvsi2, .{ .name = "__absvsi2", .linkage = linkage });
+    @export(__absvdi2, .{ .name = "__absvdi2", .linkage = linkage });
+    @export(__absvti2, .{ .name = "__absvti2", .linkage = linkage });
+}
 
 inline fn absvXi(comptime ST: type, a: ST) ST {
     const UT = switch (ST) {
lib/compiler_rt/addo.zig
@@ -1,4 +1,14 @@
+const std = @import("std");
 const builtin = @import("builtin");
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__addosi4, .{ .name = "__addosi4", .linkage = linkage });
+    @export(__addodi4, .{ .name = "__addodi4", .linkage = linkage });
+    @export(__addoti4, .{ .name = "__addoti4", .linkage = linkage });
+}
 
 // addo - add overflow
 // * return a+%b.
lib/compiler_rt/addXf3.zig
@@ -3,9 +3,41 @@
 // https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc
 
 const std = @import("std");
-const math = std.math;
 const builtin = @import("builtin");
-const compiler_rt = @import("../compiler_rt.zig");
+const math = std.math;
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+
+const common = @import("common.zig");
+const normalize = common.normalize;
+pub const panic = common.panic;
+
+comptime {
+    @export(__addsf3, .{ .name = "__addsf3", .linkage = linkage });
+    @export(__adddf3, .{ .name = "__adddf3", .linkage = linkage });
+    @export(__addxf3, .{ .name = "__addxf3", .linkage = linkage });
+    @export(__addtf3, .{ .name = "__addtf3", .linkage = linkage });
+
+    @export(__subsf3, .{ .name = "__subsf3", .linkage = linkage });
+    @export(__subdf3, .{ .name = "__subdf3", .linkage = linkage });
+    @export(__subxf3, .{ .name = "__subxf3", .linkage = linkage });
+    @export(__subtf3, .{ .name = "__subtf3", .linkage = linkage });
+
+    if (!is_test) {
+        if (arch.isARM() or arch.isThumb()) {
+            @export(__aeabi_fadd, .{ .name = "__aeabi_fadd", .linkage = linkage });
+            @export(__aeabi_dadd, .{ .name = "__aeabi_dadd", .linkage = linkage });
+            @export(__aeabi_fsub, .{ .name = "__aeabi_fsub", .linkage = linkage });
+            @export(__aeabi_dsub, .{ .name = "__aeabi_dsub", .linkage = linkage });
+        }
+
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(__addkf3, .{ .name = "__addkf3", .linkage = linkage });
+            @export(__subkf3, .{ .name = "__subkf3", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __addsf3(a: f32, b: f32) callconv(.C) f32 {
     return addXf3(f32, a, b);
@@ -29,6 +61,10 @@ pub fn __addtf3(a: f128, b: f128) callconv(.C) f128 {
     return addXf3(f128, a, b);
 }
 
+pub fn __addkf3(a: f128, b: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, __addtf3, .{ a, b });
+}
+
 pub fn __subsf3(a: f32, b: f32) callconv(.C) f32 {
     const neg_b = @bitCast(f32, @bitCast(u32, b) ^ (@as(u32, 1) << 31));
     return addXf3(f32, a, neg_b);
@@ -44,6 +80,10 @@ pub fn __subtf3(a: f128, b: f128) callconv(.C) f128 {
     return addXf3(f128, a, neg_b);
 }
 
+pub fn __subkf3(a: f128, b: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, __subtf3, .{ a, b });
+}
+
 pub fn __aeabi_fadd(a: f32, b: f32) callconv(.AAPCS) f32 {
     @setRuntimeSafety(false);
     return @call(.{ .modifier = .always_inline }, __addsf3, .{ a, b });
@@ -65,20 +105,7 @@ pub fn __aeabi_dsub(a: f64, b: f64) callconv(.AAPCS) f64 {
 }
 
 // TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
-fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T).Float.bits)) i32 {
-    const bits = @typeInfo(T).Float.bits;
-    const Z = std.meta.Int(.unsigned, bits);
-    const S = std.meta.Int(.unsigned, bits - @clz(Z, @as(Z, bits) - 1));
-    const fractionalBits = math.floatFractionalBits(T);
-    const integerBit = @as(Z, 1) << fractionalBits;
-
-    const shift = @clz(std.meta.Int(.unsigned, bits), significand.*) - @clz(Z, integerBit);
-    significand.* <<= @intCast(S, shift);
-    return @as(i32, 1) - shift;
-}
-
-// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
-fn addXf3(comptime T: type, a: T, b: T) T {
+pub fn addXf3(comptime T: type, a: T, b: T) T {
     const bits = @typeInfo(T).Float.bits;
     const Z = std.meta.Int(.unsigned, bits);
     const S = std.meta.Int(.unsigned, bits - @clz(Z, @as(Z, bits) - 1));
lib/compiler_rt/arm.zig
@@ -1,5 +1,45 @@
 // ARM specific builtins
+const std = @import("std");
 const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    if (!builtin.is_test) {
+        if (arch.isARM() or arch.isThumb()) {
+            @export(__aeabi_unwind_cpp_pr0, .{ .name = "__aeabi_unwind_cpp_pr0", .linkage = linkage });
+            @export(__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = linkage });
+            @export(__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = linkage });
+
+            @export(__aeabi_ldivmod, .{ .name = "__aeabi_ldivmod", .linkage = linkage });
+            @export(__aeabi_uldivmod, .{ .name = "__aeabi_uldivmod", .linkage = linkage });
+
+            @export(__aeabi_idivmod, .{ .name = "__aeabi_idivmod", .linkage = linkage });
+            @export(__aeabi_uidivmod, .{ .name = "__aeabi_uidivmod", .linkage = linkage });
+
+            @export(__aeabi_memcpy, .{ .name = "__aeabi_memcpy", .linkage = linkage });
+            @export(__aeabi_memcpy4, .{ .name = "__aeabi_memcpy4", .linkage = linkage });
+            @export(__aeabi_memcpy8, .{ .name = "__aeabi_memcpy8", .linkage = linkage });
+
+            @export(__aeabi_memmove, .{ .name = "__aeabi_memmove", .linkage = linkage });
+            @export(__aeabi_memmove4, .{ .name = "__aeabi_memmove4", .linkage = linkage });
+            @export(__aeabi_memmove8, .{ .name = "__aeabi_memmove8", .linkage = linkage });
+
+            @export(__aeabi_memset, .{ .name = "__aeabi_memset", .linkage = linkage });
+            @export(__aeabi_memset4, .{ .name = "__aeabi_memset4", .linkage = linkage });
+            @export(__aeabi_memset8, .{ .name = "__aeabi_memset8", .linkage = linkage });
+
+            @export(__aeabi_memclr, .{ .name = "__aeabi_memclr", .linkage = linkage });
+            @export(__aeabi_memclr4, .{ .name = "__aeabi_memclr4", .linkage = linkage });
+            @export(__aeabi_memclr8, .{ .name = "__aeabi_memclr8", .linkage = linkage });
+
+            if (builtin.os.tag == .linux) {
+                @export(__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = linkage });
+            }
+        }
+    }
+}
 
 const __divmodsi4 = @import("int.zig").__divmodsi4;
 const __udivmodsi4 = @import("int.zig").__udivmodsi4;
@@ -14,11 +54,27 @@ pub fn __aeabi_memcpy(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
     @setRuntimeSafety(false);
     _ = memcpy(dest, src, n);
 }
+pub fn __aeabi_memcpy4(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
+    @setRuntimeSafety(false);
+    _ = memcpy(dest, src, n);
+}
+pub fn __aeabi_memcpy8(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
+    @setRuntimeSafety(false);
+    _ = memcpy(dest, src, n);
+}
 
 pub fn __aeabi_memmove(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
     @setRuntimeSafety(false);
     _ = memmove(dest, src, n);
 }
+pub fn __aeabi_memmove4(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
+    @setRuntimeSafety(false);
+    _ = memmove(dest, src, n);
+}
+pub fn __aeabi_memmove8(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
+    @setRuntimeSafety(false);
+    _ = memmove(dest, src, n);
+}
 
 pub fn __aeabi_memset(dest: [*]u8, n: usize, c: u8) callconv(.AAPCS) void {
     @setRuntimeSafety(false);
@@ -26,11 +82,27 @@ pub fn __aeabi_memset(dest: [*]u8, n: usize, c: u8) callconv(.AAPCS) void {
     // two arguments swapped
     _ = memset(dest, c, n);
 }
+pub fn __aeabi_memset4(dest: [*]u8, n: usize, c: u8) callconv(.AAPCS) void {
+    @setRuntimeSafety(false);
+    _ = memset(dest, c, n);
+}
+pub fn __aeabi_memset8(dest: [*]u8, n: usize, c: u8) callconv(.AAPCS) void {
+    @setRuntimeSafety(false);
+    _ = memset(dest, c, n);
+}
 
 pub fn __aeabi_memclr(dest: [*]u8, n: usize) callconv(.AAPCS) void {
     @setRuntimeSafety(false);
     _ = memset(dest, 0, n);
 }
+pub fn __aeabi_memclr4(dest: [*]u8, n: usize) callconv(.AAPCS) void {
+    @setRuntimeSafety(false);
+    _ = memset(dest, 0, n);
+}
+pub fn __aeabi_memclr8(dest: [*]u8, n: usize) callconv(.AAPCS) void {
+    @setRuntimeSafety(false);
+    _ = memset(dest, 0, n);
+}
 
 // Dummy functions to avoid errors during the linking phase
 pub fn __aeabi_unwind_cpp_pr0() callconv(.C) void {}
lib/compiler_rt/atomics.zig
@@ -2,8 +2,8 @@ const std = @import("std");
 const builtin = @import("builtin");
 const cpu = builtin.cpu;
 const arch = cpu.arch;
-
 const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
 
 // This parameter is true iff the target architecture supports the bare minimum
 // to implement the atomic load/store intrinsics.
lib/compiler_rt/aulldiv.zig
@@ -1,4 +1,19 @@
+const std = @import("std");
 const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
+const abi = builtin.abi;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Strong;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    if (arch == .i386 and abi == .msvc) {
+        // Don't let LLVM apply the stdcall name mangling on those MSVC builtins
+        @export(_alldiv, .{ .name = "\x01__alldiv", .linkage = linkage });
+        @export(_aulldiv, .{ .name = "\x01__aulldiv", .linkage = linkage });
+        @export(_allrem, .{ .name = "\x01__allrem", .linkage = linkage });
+        @export(_aullrem, .{ .name = "\x01__aullrem", .linkage = linkage });
+    }
+}
 
 pub fn _alldiv(a: i64, b: i64) callconv(.Stdcall) i64 {
     @setRuntimeSafety(builtin.is_test);
lib/compiler_rt/bswap.zig
@@ -1,5 +1,14 @@
 const std = @import("std");
 const builtin = @import("builtin");
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__bswapsi2, .{ .name = "__bswapsi2", .linkage = linkage });
+    @export(__bswapdi2, .{ .name = "__bswapdi2", .linkage = linkage });
+    @export(__bswapti2, .{ .name = "__bswapti2", .linkage = linkage });
+}
 
 // bswap - byteswap
 // - bswapXi2 for unoptimized big and little endian
lib/compiler_rt/ceil.zig
@@ -5,8 +5,27 @@
 // https://git.musl-libc.org/cgit/musl/tree/src/math/ceil.c
 
 const std = @import("std");
+const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
 const math = std.math;
 const expect = std.testing.expect;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__ceilh, .{ .name = "__ceilh", .linkage = linkage });
+    @export(ceilf, .{ .name = "ceilf", .linkage = linkage });
+    @export(ceil, .{ .name = "ceil", .linkage = linkage });
+    @export(__ceilx, .{ .name = "__ceilx", .linkage = linkage });
+    @export(ceilq, .{ .name = "ceilq", .linkage = linkage });
+    @export(ceill, .{ .name = "ceill", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(ceilf128, .{ .name = "ceilf128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __ceilh(x: f16) callconv(.C) f16 {
     // TODO: more efficient implementation
@@ -111,6 +130,10 @@ pub fn ceilq(x: f128) callconv(.C) f128 {
     }
 }
 
+pub fn ceilf128(x: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, ceilq, .{x});
+}
+
 pub fn ceill(x: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __ceilh(x),
lib/compiler_rt/clear_cache.zig
@@ -2,6 +2,7 @@ const std = @import("std");
 const builtin = @import("builtin");
 const arch = builtin.cpu.arch;
 const os = builtin.os.tag;
+pub const panic = @import("common.zig").panic;
 
 // Ported from llvm-project d32170dbd5b0d54436537b6b75beaf44324e0c28
 
@@ -10,7 +11,13 @@ const os = builtin.os.tag;
 // It is expected to invalidate the instruction cache for the
 // specified range.
 
-pub fn clear_cache(start: usize, end: usize) callconv(.C) void {
+comptime {
+    if (builtin.zig_backend != .stage2_llvm) {
+        _ = clear_cache;
+    }
+}
+
+fn clear_cache(start: usize, end: usize) callconv(.C) void {
     const x86 = switch (arch) {
         .i386, .x86_64 => true,
         else => false,
lib/compiler_rt/cmp.zig
@@ -1,5 +1,17 @@
 const std = @import("std");
 const builtin = @import("builtin");
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__cmpsi2, .{ .name = "__cmpsi2", .linkage = linkage });
+    @export(__cmpdi2, .{ .name = "__cmpdi2", .linkage = linkage });
+    @export(__cmpti2, .{ .name = "__cmpti2", .linkage = linkage });
+    @export(__ucmpsi2, .{ .name = "__ucmpsi2", .linkage = linkage });
+    @export(__ucmpdi2, .{ .name = "__ucmpdi2", .linkage = linkage });
+    @export(__ucmpti2, .{ .name = "__ucmpti2", .linkage = linkage });
+}
 
 // cmp - signed compare
 // - cmpXi2_generic for unoptimized little and big endian
lib/compiler_rt/common.zig
@@ -0,0 +1,144 @@
+const std = @import("std");
+const builtin = @import("builtin");
+const math = std.math;
+const is_test = builtin.is_test;
+
+// Avoid dragging in the runtime safety mechanisms into this .o file,
+// unless we're trying to test this file.
+pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn {
+    _ = error_return_trace;
+    @setCold(true);
+    if (is_test) {
+        std.debug.panic("{s}", .{msg});
+    } else {
+        unreachable;
+    }
+}
+
+pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
+    @setRuntimeSafety(is_test);
+    switch (Z) {
+        u16 => {
+            // 16x16 --> 32 bit multiply
+            const product = @as(u32, a) * @as(u32, b);
+            hi.* = @intCast(u16, product >> 16);
+            lo.* = @truncate(u16, product);
+        },
+        u32 => {
+            // 32x32 --> 64 bit multiply
+            const product = @as(u64, a) * @as(u64, b);
+            hi.* = @truncate(u32, product >> 32);
+            lo.* = @truncate(u32, product);
+        },
+        u64 => {
+            const S = struct {
+                fn loWord(x: u64) u64 {
+                    return @truncate(u32, x);
+                }
+                fn hiWord(x: u64) u64 {
+                    return @truncate(u32, x >> 32);
+                }
+            };
+            // 64x64 -> 128 wide multiply for platforms that don't have such an operation;
+            // many 64-bit platforms have this operation, but they tend to have hardware
+            // floating-point, so we don't bother with a special case for them here.
+            // Each of the component 32x32 -> 64 products
+            const plolo: u64 = S.loWord(a) * S.loWord(b);
+            const plohi: u64 = S.loWord(a) * S.hiWord(b);
+            const philo: u64 = S.hiWord(a) * S.loWord(b);
+            const phihi: u64 = S.hiWord(a) * S.hiWord(b);
+            // Sum terms that contribute to lo in a way that allows us to get the carry
+            const r0: u64 = S.loWord(plolo);
+            const r1: u64 = S.hiWord(plolo) +% S.loWord(plohi) +% S.loWord(philo);
+            lo.* = r0 +% (r1 << 32);
+            // Sum terms contributing to hi with the carry from lo
+            hi.* = S.hiWord(plohi) +% S.hiWord(philo) +% S.hiWord(r1) +% phihi;
+        },
+        u128 => {
+            const Word_LoMask = @as(u64, 0x00000000ffffffff);
+            const Word_HiMask = @as(u64, 0xffffffff00000000);
+            const Word_FullMask = @as(u64, 0xffffffffffffffff);
+            const S = struct {
+                fn Word_1(x: u128) u64 {
+                    return @truncate(u32, x >> 96);
+                }
+                fn Word_2(x: u128) u64 {
+                    return @truncate(u32, x >> 64);
+                }
+                fn Word_3(x: u128) u64 {
+                    return @truncate(u32, x >> 32);
+                }
+                fn Word_4(x: u128) u64 {
+                    return @truncate(u32, x);
+                }
+            };
+            // 128x128 -> 256 wide multiply for platforms that don't have such an operation;
+            // many 64-bit platforms have this operation, but they tend to have hardware
+            // floating-point, so we don't bother with a special case for them here.
+
+            const product11: u64 = S.Word_1(a) * S.Word_1(b);
+            const product12: u64 = S.Word_1(a) * S.Word_2(b);
+            const product13: u64 = S.Word_1(a) * S.Word_3(b);
+            const product14: u64 = S.Word_1(a) * S.Word_4(b);
+            const product21: u64 = S.Word_2(a) * S.Word_1(b);
+            const product22: u64 = S.Word_2(a) * S.Word_2(b);
+            const product23: u64 = S.Word_2(a) * S.Word_3(b);
+            const product24: u64 = S.Word_2(a) * S.Word_4(b);
+            const product31: u64 = S.Word_3(a) * S.Word_1(b);
+            const product32: u64 = S.Word_3(a) * S.Word_2(b);
+            const product33: u64 = S.Word_3(a) * S.Word_3(b);
+            const product34: u64 = S.Word_3(a) * S.Word_4(b);
+            const product41: u64 = S.Word_4(a) * S.Word_1(b);
+            const product42: u64 = S.Word_4(a) * S.Word_2(b);
+            const product43: u64 = S.Word_4(a) * S.Word_3(b);
+            const product44: u64 = S.Word_4(a) * S.Word_4(b);
+
+            const sum0: u128 = @as(u128, product44);
+            const sum1: u128 = @as(u128, product34) +%
+                @as(u128, product43);
+            const sum2: u128 = @as(u128, product24) +%
+                @as(u128, product33) +%
+                @as(u128, product42);
+            const sum3: u128 = @as(u128, product14) +%
+                @as(u128, product23) +%
+                @as(u128, product32) +%
+                @as(u128, product41);
+            const sum4: u128 = @as(u128, product13) +%
+                @as(u128, product22) +%
+                @as(u128, product31);
+            const sum5: u128 = @as(u128, product12) +%
+                @as(u128, product21);
+            const sum6: u128 = @as(u128, product11);
+
+            const r0: u128 = (sum0 & Word_FullMask) +%
+                ((sum1 & Word_LoMask) << 32);
+            const r1: u128 = (sum0 >> 64) +%
+                ((sum1 >> 32) & Word_FullMask) +%
+                (sum2 & Word_FullMask) +%
+                ((sum3 << 32) & Word_HiMask);
+
+            lo.* = r0 +% (r1 << 64);
+            hi.* = (r1 >> 64) +%
+                (sum1 >> 96) +%
+                (sum2 >> 64) +%
+                (sum3 >> 32) +%
+                sum4 +%
+                (sum5 << 32) +%
+                (sum6 << 64);
+        },
+        else => @compileError("unsupported"),
+    }
+}
+
+// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
+pub fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T).Float.bits)) i32 {
+    const bits = @typeInfo(T).Float.bits;
+    const Z = std.meta.Int(.unsigned, bits);
+    const S = std.meta.Int(.unsigned, bits - @clz(Z, @as(Z, bits) - 1));
+    const fractionalBits = math.floatFractionalBits(T);
+    const integerBit = @as(Z, 1) << fractionalBits;
+
+    const shift = @clz(std.meta.Int(.unsigned, bits), significand.*) - @clz(Z, integerBit);
+    significand.* <<= @intCast(S, shift);
+    return @as(i32, 1) - shift;
+}
lib/compiler_rt/compareXf2.zig
@@ -4,6 +4,78 @@
 
 const std = @import("std");
 const builtin = @import("builtin");
+const is_test = builtin.is_test;
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__lesf2, .{ .name = "__lesf2", .linkage = linkage });
+    @export(__ledf2, .{ .name = "__ledf2", .linkage = linkage });
+    @export(__letf2, .{ .name = "__letf2", .linkage = linkage });
+    @export(__lexf2, .{ .name = "__lexf2", .linkage = linkage });
+
+    @export(__gesf2, .{ .name = "__gesf2", .linkage = linkage });
+    @export(__gedf2, .{ .name = "__gedf2", .linkage = linkage });
+    @export(__getf2, .{ .name = "__getf2", .linkage = linkage });
+    @export(__gexf2, .{ .name = "__gexf2", .linkage = linkage });
+
+    @export(__eqsf2, .{ .name = "__eqsf2", .linkage = linkage });
+    @export(__eqdf2, .{ .name = "__eqdf2", .linkage = linkage });
+    @export(__eqxf2, .{ .name = "__eqxf2", .linkage = linkage });
+
+    @export(__ltsf2, .{ .name = "__ltsf2", .linkage = linkage });
+    @export(__ltdf2, .{ .name = "__ltdf2", .linkage = linkage });
+    @export(__ltxf2, .{ .name = "__ltxf2", .linkage = linkage });
+
+    @export(__nesf2, .{ .name = "__nesf2", .linkage = linkage });
+    @export(__nedf2, .{ .name = "__nedf2", .linkage = linkage });
+    @export(__nexf2, .{ .name = "__nexf2", .linkage = linkage });
+
+    @export(__gtsf2, .{ .name = "__gtsf2", .linkage = linkage });
+    @export(__gtdf2, .{ .name = "__gtdf2", .linkage = linkage });
+    @export(__gtxf2, .{ .name = "__gtxf2", .linkage = linkage });
+
+    @export(__unordsf2, .{ .name = "__unordsf2", .linkage = linkage });
+    @export(__unorddf2, .{ .name = "__unorddf2", .linkage = linkage });
+    @export(__unordtf2, .{ .name = "__unordtf2", .linkage = linkage });
+
+    if (!is_test) {
+        @export(__cmpsf2, .{ .name = "__cmpsf2", .linkage = linkage });
+        @export(__cmpdf2, .{ .name = "__cmpdf2", .linkage = linkage });
+        @export(__cmptf2, .{ .name = "__cmptf2", .linkage = linkage });
+        @export(__eqtf2, .{ .name = "__eqtf2", .linkage = linkage });
+        @export(__lttf2, .{ .name = "__lttf2", .linkage = linkage });
+        @export(__gttf2, .{ .name = "__gttf2", .linkage = linkage });
+        @export(__netf2, .{ .name = "__netf2", .linkage = linkage });
+
+        if (arch.isARM() or arch.isThumb()) {
+            @export(__aeabi_fcmpeq, .{ .name = "__aeabi_fcmpeq", .linkage = linkage });
+            @export(__aeabi_fcmplt, .{ .name = "__aeabi_fcmplt", .linkage = linkage });
+            @export(__aeabi_fcmple, .{ .name = "__aeabi_fcmple", .linkage = linkage });
+            @export(__aeabi_fcmpge, .{ .name = "__aeabi_fcmpge", .linkage = linkage });
+            @export(__aeabi_fcmpgt, .{ .name = "__aeabi_fcmpgt", .linkage = linkage });
+            @export(__aeabi_fcmpun, .{ .name = "__aeabi_fcmpun", .linkage = linkage });
+
+            @export(__aeabi_dcmpeq, .{ .name = "__aeabi_dcmpeq", .linkage = linkage });
+            @export(__aeabi_dcmplt, .{ .name = "__aeabi_dcmplt", .linkage = linkage });
+            @export(__aeabi_dcmple, .{ .name = "__aeabi_dcmple", .linkage = linkage });
+            @export(__aeabi_dcmpge, .{ .name = "__aeabi_dcmpge", .linkage = linkage });
+            @export(__aeabi_dcmpgt, .{ .name = "__aeabi_dcmpgt", .linkage = linkage });
+            @export(__aeabi_dcmpun, .{ .name = "__aeabi_dcmpun", .linkage = linkage });
+        }
+
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(__eqkf2, .{ .name = "__eqkf2", .linkage = linkage });
+            @export(__nekf2, .{ .name = "__nekf2", .linkage = linkage });
+            @export(__gekf2, .{ .name = "__gekf2", .linkage = linkage });
+            @export(__ltkf2, .{ .name = "__ltkf2", .linkage = linkage });
+            @export(__lekf2, .{ .name = "__lekf2", .linkage = linkage });
+            @export(__gtkf2, .{ .name = "__gtkf2", .linkage = linkage });
+            @export(__unordkf2, .{ .name = "__unordkf2", .linkage = linkage });
+        }
+    }
+}
 
 const LE = enum(i32) {
     Less = -1,
@@ -98,20 +170,24 @@ pub fn __gesf2(a: f32, b: f32) callconv(.C) i32 {
     return @bitCast(i32, float);
 }
 
+pub fn __cmpsf2(a: f32, b: f32) callconv(.C) i32 {
+    return @call(.{ .modifier = .always_inline }, __lesf2, .{ a, b });
+}
+
 pub fn __eqsf2(a: f32, b: f32) callconv(.C) i32 {
-    return __lesf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __lesf2, .{ a, b });
 }
 
 pub fn __ltsf2(a: f32, b: f32) callconv(.C) i32 {
-    return __lesf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __lesf2, .{ a, b });
 }
 
 pub fn __nesf2(a: f32, b: f32) callconv(.C) i32 {
-    return __lesf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __lesf2, .{ a, b });
 }
 
 pub fn __gtsf2(a: f32, b: f32) callconv(.C) i32 {
-    return __gesf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __gesf2, .{ a, b });
 }
 
 // Comparison between f64
@@ -128,20 +204,24 @@ pub fn __gedf2(a: f64, b: f64) callconv(.C) i32 {
     return @bitCast(i32, float);
 }
 
+pub fn __cmpdf2(a: f64, b: f64) callconv(.C) i32 {
+    return @call(.{ .modifier = .always_inline }, __ledf2, .{ a, b });
+}
+
 pub fn __eqdf2(a: f64, b: f64) callconv(.C) i32 {
-    return __ledf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __ledf2, .{ a, b });
 }
 
 pub fn __ltdf2(a: f64, b: f64) callconv(.C) i32 {
-    return __ledf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __ledf2, .{ a, b });
 }
 
 pub fn __nedf2(a: f64, b: f64) callconv(.C) i32 {
-    return __ledf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __ledf2, .{ a, b });
 }
 
 pub fn __gtdf2(a: f64, b: f64) callconv(.C) i32 {
-    return __gedf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __gedf2, .{ a, b });
 }
 
 // Comparison between f80
@@ -196,19 +276,19 @@ pub fn __gexf2(a: f80, b: f80) callconv(.C) i32 {
 }
 
 pub fn __eqxf2(a: f80, b: f80) callconv(.C) i32 {
-    return __lexf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __lexf2, .{ a, b });
 }
 
 pub fn __ltxf2(a: f80, b: f80) callconv(.C) i32 {
-    return __lexf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __lexf2, .{ a, b });
 }
 
 pub fn __nexf2(a: f80, b: f80) callconv(.C) i32 {
-    return __lexf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __lexf2, .{ a, b });
 }
 
 pub fn __gtxf2(a: f80, b: f80) callconv(.C) i32 {
-    return __gexf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __gexf2, .{ a, b });
 }
 
 // Comparison between f128
@@ -225,20 +305,48 @@ pub fn __getf2(a: f128, b: f128) callconv(.C) i32 {
     return @bitCast(i32, float);
 }
 
+pub fn __cmptf2(a: f128, b: f128) callconv(.C) i32 {
+    return @call(.{ .modifier = .always_inline }, __letf2, .{ a, b });
+}
+
 pub fn __eqtf2(a: f128, b: f128) callconv(.C) i32 {
-    return __letf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __letf2, .{ a, b });
 }
 
 pub fn __lttf2(a: f128, b: f128) callconv(.C) i32 {
-    return __letf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __letf2, .{ a, b });
 }
 
 pub fn __netf2(a: f128, b: f128) callconv(.C) i32 {
-    return __letf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __letf2, .{ a, b });
 }
 
 pub fn __gttf2(a: f128, b: f128) callconv(.C) i32 {
-    return __getf2(a, b);
+    return @call(.{ .modifier = .always_inline }, __getf2, .{ a, b });
+}
+
+pub fn __eqkf2(a: f128, b: f128) callconv(.C) i32 {
+    return @call(.{ .modifier = .always_inline }, __letf2, .{ a, b });
+}
+
+pub fn __nekf2(a: f128, b: f128) callconv(.C) i32 {
+    return @call(.{ .modifier = .always_inline }, __letf2, .{ a, b });
+}
+
+pub fn __gekf2(a: f128, b: f128) callconv(.C) i32 {
+    return @call(.{ .modifier = .always_inline }, __getf2, .{ a, b });
+}
+
+pub fn __ltkf2(a: f128, b: f128) callconv(.C) i32 {
+    return @call(.{ .modifier = .always_inline }, __letf2, .{ a, b });
+}
+
+pub fn __lekf2(a: f128, b: f128) callconv(.C) i32 {
+    return @call(.{ .modifier = .always_inline }, __letf2, .{ a, b });
+}
+
+pub fn __gtkf2(a: f128, b: f128) callconv(.C) i32 {
+    return @call(.{ .modifier = .always_inline }, __getf2, .{ a, b });
 }
 
 // Unordered comparison between f32/f64/f128
@@ -258,6 +366,10 @@ pub fn __unordtf2(a: f128, b: f128) callconv(.C) i32 {
     return unordcmp(f128, a, b);
 }
 
+pub fn __unordkf2(a: f128, b: f128) callconv(.C) i32 {
+    return @call(.{ .modifier = .always_inline }, __unordtf2, .{ a, b });
+}
+
 // ARM EABI intrinsics
 
 pub fn __aeabi_fcmpeq(a: f32, b: f32) callconv(.AAPCS) i32 {
lib/compiler_rt/cos.zig
@@ -1,11 +1,30 @@
 const std = @import("std");
+const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
 const math = std.math;
 const expect = std.testing.expect;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
 
 const trig = @import("trig.zig");
 const rem_pio2 = @import("rem_pio2.zig").rem_pio2;
 const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;
 
+comptime {
+    @export(__cosh, .{ .name = "__cosh", .linkage = linkage });
+    @export(cosf, .{ .name = "cosf", .linkage = linkage });
+    @export(cos, .{ .name = "cos", .linkage = linkage });
+    @export(__cosx, .{ .name = "__cosx", .linkage = linkage });
+    @export(cosq, .{ .name = "cosq", .linkage = linkage });
+    @export(cosl, .{ .name = "cosl", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(cosf128, .{ .name = "cosf128", .linkage = linkage });
+        }
+    }
+}
+
 pub fn __cosh(a: f16) callconv(.C) f16 {
     // TODO: more efficient implementation
     return @floatCast(f16, cosf(a));
@@ -107,6 +126,10 @@ pub fn cosq(a: f128) callconv(.C) f128 {
     return cos(@floatCast(f64, a));
 }
 
+pub fn cosf128(a: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, cosq, .{a});
+}
+
 pub fn cosl(x: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __cosh(x),
lib/compiler_rt/count0bits.zig
@@ -1,5 +1,20 @@
 const std = @import("std");
 const builtin = @import("builtin");
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__clzsi2, .{ .name = "__clzsi2", .linkage = linkage });
+    @export(__clzdi2, .{ .name = "__clzdi2", .linkage = linkage });
+    @export(__clzti2, .{ .name = "__clzti2", .linkage = linkage });
+    @export(__ctzsi2, .{ .name = "__ctzsi2", .linkage = linkage });
+    @export(__ctzdi2, .{ .name = "__ctzdi2", .linkage = linkage });
+    @export(__ctzti2, .{ .name = "__ctzti2", .linkage = linkage });
+    @export(__ffssi2, .{ .name = "__ffssi2", .linkage = linkage });
+    @export(__ffsdi2, .{ .name = "__ffsdi2", .linkage = linkage });
+    @export(__ffsti2, .{ .name = "__ffsti2", .linkage = linkage });
+}
 
 // clz - count leading zeroes
 // - clzXi2 for unoptimized little and big endian
lib/compiler_rt/divdf3.zig
@@ -4,6 +4,24 @@
 
 const std = @import("std");
 const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+
+const common = @import("common.zig");
+const normalize = common.normalize;
+const wideMultiply = common.wideMultiply;
+pub const panic = common.panic;
+
+comptime {
+    @export(__divdf3, .{ .name = "__divdf3", .linkage = linkage });
+
+    if (!is_test) {
+        if (arch.isARM() or arch.isThumb()) {
+            @export(__aeabi_ddiv, .{ .name = "__aeabi_ddiv", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __divdf3(a: f64, b: f64) callconv(.C) f64 {
     @setRuntimeSafety(builtin.is_test);
@@ -202,125 +220,6 @@ pub fn __divdf3(a: f64, b: f64) callconv(.C) f64 {
     }
 }
 
-pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
-    @setRuntimeSafety(builtin.is_test);
-    switch (Z) {
-        u32 => {
-            // 32x32 --> 64 bit multiply
-            const product = @as(u64, a) * @as(u64, b);
-            hi.* = @truncate(u32, product >> 32);
-            lo.* = @truncate(u32, product);
-        },
-        u64 => {
-            const S = struct {
-                fn loWord(x: u64) u64 {
-                    return @truncate(u32, x);
-                }
-                fn hiWord(x: u64) u64 {
-                    return @truncate(u32, x >> 32);
-                }
-            };
-            // 64x64 -> 128 wide multiply for platforms that don't have such an operation;
-            // many 64-bit platforms have this operation, but they tend to have hardware
-            // floating-point, so we don't bother with a special case for them here.
-            // Each of the component 32x32 -> 64 products
-            const plolo: u64 = S.loWord(a) * S.loWord(b);
-            const plohi: u64 = S.loWord(a) * S.hiWord(b);
-            const philo: u64 = S.hiWord(a) * S.loWord(b);
-            const phihi: u64 = S.hiWord(a) * S.hiWord(b);
-            // Sum terms that contribute to lo in a way that allows us to get the carry
-            const r0: u64 = S.loWord(plolo);
-            const r1: u64 = S.hiWord(plolo) +% S.loWord(plohi) +% S.loWord(philo);
-            lo.* = r0 +% (r1 << 32);
-            // Sum terms contributing to hi with the carry from lo
-            hi.* = S.hiWord(plohi) +% S.hiWord(philo) +% S.hiWord(r1) +% phihi;
-        },
-        u128 => {
-            const Word_LoMask = @as(u64, 0x00000000ffffffff);
-            const Word_HiMask = @as(u64, 0xffffffff00000000);
-            const Word_FullMask = @as(u64, 0xffffffffffffffff);
-            const S = struct {
-                fn Word_1(x: u128) u64 {
-                    return @truncate(u32, x >> 96);
-                }
-                fn Word_2(x: u128) u64 {
-                    return @truncate(u32, x >> 64);
-                }
-                fn Word_3(x: u128) u64 {
-                    return @truncate(u32, x >> 32);
-                }
-                fn Word_4(x: u128) u64 {
-                    return @truncate(u32, x);
-                }
-            };
-            // 128x128 -> 256 wide multiply for platforms that don't have such an operation;
-            // many 64-bit platforms have this operation, but they tend to have hardware
-            // floating-point, so we don't bother with a special case for them here.
-
-            const product11: u64 = S.Word_1(a) * S.Word_1(b);
-            const product12: u64 = S.Word_1(a) * S.Word_2(b);
-            const product13: u64 = S.Word_1(a) * S.Word_3(b);
-            const product14: u64 = S.Word_1(a) * S.Word_4(b);
-            const product21: u64 = S.Word_2(a) * S.Word_1(b);
-            const product22: u64 = S.Word_2(a) * S.Word_2(b);
-            const product23: u64 = S.Word_2(a) * S.Word_3(b);
-            const product24: u64 = S.Word_2(a) * S.Word_4(b);
-            const product31: u64 = S.Word_3(a) * S.Word_1(b);
-            const product32: u64 = S.Word_3(a) * S.Word_2(b);
-            const product33: u64 = S.Word_3(a) * S.Word_3(b);
-            const product34: u64 = S.Word_3(a) * S.Word_4(b);
-            const product41: u64 = S.Word_4(a) * S.Word_1(b);
-            const product42: u64 = S.Word_4(a) * S.Word_2(b);
-            const product43: u64 = S.Word_4(a) * S.Word_3(b);
-            const product44: u64 = S.Word_4(a) * S.Word_4(b);
-
-            const sum0: u128 = @as(u128, product44);
-            const sum1: u128 = @as(u128, product34) +%
-                @as(u128, product43);
-            const sum2: u128 = @as(u128, product24) +%
-                @as(u128, product33) +%
-                @as(u128, product42);
-            const sum3: u128 = @as(u128, product14) +%
-                @as(u128, product23) +%
-                @as(u128, product32) +%
-                @as(u128, product41);
-            const sum4: u128 = @as(u128, product13) +%
-                @as(u128, product22) +%
-                @as(u128, product31);
-            const sum5: u128 = @as(u128, product12) +%
-                @as(u128, product21);
-            const sum6: u128 = @as(u128, product11);
-
-            const r0: u128 = (sum0 & Word_FullMask) +%
-                ((sum1 & Word_LoMask) << 32);
-            const r1: u128 = (sum0 >> 64) +%
-                ((sum1 >> 32) & Word_FullMask) +%
-                (sum2 & Word_FullMask) +%
-                ((sum3 << 32) & Word_HiMask);
-
-            lo.* = r0 +% (r1 << 64);
-            hi.* = (r1 >> 64) +%
-                (sum1 >> 96) +%
-                (sum2 >> 64) +%
-                (sum3 >> 32) +%
-                sum4 +%
-                (sum5 << 32) +%
-                (sum6 << 64);
-        },
-        else => @compileError("unsupported"),
-    }
-}
-
-pub fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T).Float.bits)) i32 {
-    @setRuntimeSafety(builtin.is_test);
-    const Z = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
-    const integerBit = @as(Z, 1) << std.math.floatFractionalBits(T);
-
-    const shift = @clz(Z, significand.*) - @clz(Z, integerBit);
-    significand.* <<= @intCast(std.math.Log2Int(Z), shift);
-    return @as(i32, 1) - shift;
-}
-
 pub fn __aeabi_ddiv(a: f64, b: f64) callconv(.AAPCS) f64 {
     @setRuntimeSafety(false);
     return @call(.{ .modifier = .always_inline }, __divdf3, .{ a, b });
lib/compiler_rt/divsf3.zig
@@ -4,6 +4,23 @@
 
 const std = @import("std");
 const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+
+const common = @import("common.zig");
+const normalize = common.normalize;
+pub const panic = common.panic;
+
+comptime {
+    @export(__divsf3, .{ .name = "__divsf3", .linkage = linkage });
+
+    if (!is_test) {
+        if (arch.isARM() or arch.isThumb()) {
+            @export(__aeabi_fdiv, .{ .name = "__aeabi_fdiv", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 {
     @setRuntimeSafety(builtin.is_test);
@@ -184,17 +201,6 @@ pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 {
     }
 }
 
-fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T).Float.bits)) i32 {
-    @setRuntimeSafety(builtin.is_test);
-    const Z = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
-    const significandBits = std.math.floatMantissaBits(T);
-    const implicitBit = @as(Z, 1) << significandBits;
-
-    const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
-    significand.* <<= @intCast(std.math.Log2Int(Z), shift);
-    return 1 - shift;
-}
-
 pub fn __aeabi_fdiv(a: f32, b: f32) callconv(.AAPCS) f32 {
     @setRuntimeSafety(false);
     return @call(.{ .modifier = .always_inline }, __divsf3, .{ a, b });
lib/compiler_rt/divtf3.zig
@@ -1,8 +1,27 @@
 const std = @import("std");
 const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
 
-const normalize = @import("divdf3.zig").normalize;
-const wideMultiply = @import("divdf3.zig").wideMultiply;
+const common = @import("common.zig");
+const normalize = common.normalize;
+const wideMultiply = common.wideMultiply;
+pub const panic = common.panic;
+
+comptime {
+    @export(__divtf3, .{ .name = "__divtf3", .linkage = linkage });
+
+    if (!is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(__divkf3, .{ .name = "__divkf3", .linkage = linkage });
+        }
+    }
+}
+
+pub fn __divkf3(a: f128, b: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, __divtf3, .{ a, b });
+}
 
 pub fn __divtf3(a: f128, b: f128) callconv(.C) f128 {
     @setRuntimeSafety(builtin.is_test);
lib/compiler_rt/divti3.zig
@@ -1,5 +1,31 @@
-const udivmod = @import("udivmod.zig").udivmod;
+const std = @import("std");
 const builtin = @import("builtin");
+const udivmod = @import("udivmod.zig").udivmod;
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    if (builtin.os.tag == .windows) {
+        switch (arch) {
+            .i386 => {
+                @export(__divti3, .{ .name = "__divti3", .linkage = linkage });
+            },
+            .x86_64 => {
+                // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI
+                // that LLVM expects compiler-rt to have.
+                @export(__divti3_windows_x86_64, .{ .name = "__divti3", .linkage = linkage });
+            },
+            else => {},
+        }
+        if (arch.isAARCH64()) {
+            @export(__divti3, .{ .name = "__divti3", .linkage = linkage });
+        }
+    } else {
+        @export(__divti3, .{ .name = "__divti3", .linkage = linkage });
+    }
+}
 
 pub fn __divti3(a: i128, b: i128) callconv(.C) i128 {
     @setRuntimeSafety(builtin.is_test);
lib/compiler_rt/divxf3.zig
@@ -1,7 +1,17 @@
 const std = @import("std");
 const builtin = @import("builtin");
-const normalize = @import("divdf3.zig").normalize;
-const wideMultiply = @import("divdf3.zig").wideMultiply;
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+
+const common = @import("common.zig");
+const normalize = common.normalize;
+const wideMultiply = common.wideMultiply;
+pub const panic = common.panic;
+
+comptime {
+    @export(__divxf3, .{ .name = "__divxf3", .linkage = linkage });
+}
 
 pub fn __divxf3(a: f80, b: f80) callconv(.C) f80 {
     @setRuntimeSafety(builtin.is_test);
lib/compiler_rt/emutls.zig
@@ -6,6 +6,8 @@
 
 const std = @import("std");
 const builtin = @import("builtin");
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
 
 const abort = std.os.abort;
 const assert = std.debug.assert;
@@ -16,7 +18,9 @@ const expect = std.testing.expect;
 const gcc_word = usize;
 
 comptime {
-    assert(builtin.link_libc);
+    if (builtin.link_libc and builtin.os.tag == .openbsd) {
+        @export(__emutls_get_address, .{ .name = "__emutls_get_address", .linkage = linkage });
+    }
 }
 
 /// public entrypoint for generated code using EmulatedTLS
@@ -319,6 +323,8 @@ const emutls_control = extern struct {
 };
 
 test "simple_allocator" {
+    if (!builtin.link_libc or builtin.os.tag != .openbsd) return error.SkipZigTest;
+
     var data1: *[64]u8 = simple_allocator.alloc([64]u8);
     defer simple_allocator.free(data1);
     for (data1) |*c| {
@@ -333,6 +339,8 @@ test "simple_allocator" {
 }
 
 test "__emutls_get_address zeroed" {
+    if (!builtin.link_libc or builtin.os.tag != .openbsd) return error.SkipZigTest;
+
     var ctl = emutls_control.init(usize, null);
     try expect(ctl.object.index == 0);
 
@@ -352,6 +360,8 @@ test "__emutls_get_address zeroed" {
 }
 
 test "__emutls_get_address with default_value" {
+    if (!builtin.link_libc or builtin.os.tag != .openbsd) return error.SkipZigTest;
+
     var value: usize = 5678; // default value
     var ctl = emutls_control.init(usize, &value);
     try expect(ctl.object.index == 0);
@@ -370,6 +380,8 @@ test "__emutls_get_address with default_value" {
 }
 
 test "test default_value with differents sizes" {
+    if (!builtin.link_libc or builtin.os.tag != .openbsd) return error.SkipZigTest;
+
     const testType = struct {
         fn _testType(comptime T: type, value: T) !void {
             var def: T = value;
lib/compiler_rt/exp.zig
@@ -5,8 +5,27 @@
 // https://git.musl-libc.org/cgit/musl/tree/src/math/exp.c
 
 const std = @import("std");
+const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
 const math = std.math;
 const expect = std.testing.expect;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__exph, .{ .name = "__exph", .linkage = linkage });
+    @export(expf, .{ .name = "expf", .linkage = linkage });
+    @export(exp, .{ .name = "exp", .linkage = linkage });
+    @export(__expx, .{ .name = "__expx", .linkage = linkage });
+    @export(expq, .{ .name = "expq", .linkage = linkage });
+    @export(expl, .{ .name = "expl", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(expf128, .{ .name = "expf128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __exph(a: f16) callconv(.C) f16 {
     // TODO: more efficient implementation
@@ -182,6 +201,10 @@ pub fn expq(a: f128) callconv(.C) f128 {
     return exp(@floatCast(f64, a));
 }
 
+pub fn expf128(a: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, expq, .{a});
+}
+
 pub fn expl(x: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __exph(x),
lib/compiler_rt/exp2.zig
@@ -5,8 +5,27 @@
 // https://git.musl-libc.org/cgit/musl/tree/src/math/exp2.c
 
 const std = @import("std");
+const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
 const math = std.math;
 const expect = std.testing.expect;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__exp2h, .{ .name = "__exp2h", .linkage = linkage });
+    @export(exp2f, .{ .name = "exp2f", .linkage = linkage });
+    @export(exp2, .{ .name = "exp2", .linkage = linkage });
+    @export(__exp2x, .{ .name = "__exp2x", .linkage = linkage });
+    @export(exp2q, .{ .name = "exp2q", .linkage = linkage });
+    @export(exp2l, .{ .name = "exp2l", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(exp2f128, .{ .name = "exp2f128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __exp2h(x: f16) callconv(.C) f16 {
     // TODO: more efficient implementation
@@ -149,6 +168,10 @@ pub fn exp2q(x: f128) callconv(.C) f128 {
     return exp2(@floatCast(f64, x));
 }
 
+pub fn exp2f128(x: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, exp2q, .{x});
+}
+
 pub fn exp2l(x: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __exp2h(x),
lib/compiler_rt/extend_f80.zig
@@ -1,21 +1,30 @@
 const std = @import("std");
 const builtin = @import("builtin");
 const is_test = builtin.is_test;
-const native_arch = builtin.cpu.arch;
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__extendhfxf2, .{ .name = "__extendhfxf2", .linkage = linkage });
+    @export(__extendsfxf2, .{ .name = "__extendsfxf2", .linkage = linkage });
+    @export(__extenddfxf2, .{ .name = "__extenddfxf2", .linkage = linkage });
+    @export(__extendxftf2, .{ .name = "__extendxftf2", .linkage = linkage });
+}
 
 // AArch64 is the only ABI (at the moment) to support f16 arguments without the
 // need for extending them to wider fp types.
-pub const F16T = if (native_arch.isAARCH64()) f16 else u16;
+const F16T = if (arch.isAARCH64()) f16 else u16;
 
-pub fn __extendhfxf2(a: F16T) callconv(.C) f80 {
+fn __extendhfxf2(a: F16T) callconv(.C) f80 {
     return extendF80(f16, @bitCast(u16, a));
 }
 
-pub fn __extendsfxf2(a: f32) callconv(.C) f80 {
+fn __extendsfxf2(a: f32) callconv(.C) f80 {
     return extendF80(f32, @bitCast(u32, a));
 }
 
-pub fn __extenddfxf2(a: f64) callconv(.C) f80 {
+fn __extenddfxf2(a: f64) callconv(.C) f80 {
     return extendF80(f64, @bitCast(u64, a));
 }
 
@@ -86,7 +95,7 @@ inline fn extendF80(comptime src_t: type, a: std.meta.Int(.unsigned, @typeInfo(s
     return std.math.make_f80(dst);
 }
 
-pub fn __extendxftf2(a: f80) callconv(.C) f128 {
+fn __extendxftf2(a: f80) callconv(.C) f128 {
     @setRuntimeSafety(builtin.is_test);
 
     const src_int_bit: u64 = 0x8000000000000000;
lib/compiler_rt/extendXfYf2.zig
@@ -1,7 +1,31 @@
 const std = @import("std");
 const builtin = @import("builtin");
 const is_test = builtin.is_test;
-const native_arch = builtin.cpu.arch;
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__extenddftf2, .{ .name = "__extenddftf2", .linkage = linkage });
+    @export(__extendsftf2, .{ .name = "__extendsftf2", .linkage = linkage });
+    @export(__extendhfsf2, .{ .name = "__extendhfsf2", .linkage = linkage });
+    @export(__extendhftf2, .{ .name = "__extendhftf2", .linkage = linkage });
+    @export(__extendsfdf2, .{ .name = "__extendsfdf2", .linkage = linkage });
+
+    if (!is_test) {
+        @export(__gnu_h2f_ieee, .{ .name = "__gnu_h2f_ieee", .linkage = linkage });
+
+        if (arch.isARM() or arch.isThumb()) {
+            @export(__aeabi_f2d, .{ .name = "__aeabi_f2d", .linkage = linkage });
+            @export(__aeabi_h2f, .{ .name = "__aeabi_h2f", .linkage = linkage });
+        }
+
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(__extendsfkf2, .{ .name = "__extendsfkf2", .linkage = linkage });
+            @export(__extenddfkf2, .{ .name = "__extenddfkf2", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __extendsfdf2(a: f32) callconv(.C) f64 {
     return extendXfYf2(f64, f32, @bitCast(u32, a));
@@ -11,18 +35,30 @@ pub fn __extenddftf2(a: f64) callconv(.C) f128 {
     return extendXfYf2(f128, f64, @bitCast(u64, a));
 }
 
+pub fn __extenddfkf2(a: f64) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, __extenddftf2, .{a});
+}
+
 pub fn __extendsftf2(a: f32) callconv(.C) f128 {
     return extendXfYf2(f128, f32, @bitCast(u32, a));
 }
 
+pub fn __extendsfkf2(a: f32) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, __extendsftf2, .{a});
+}
+
 // AArch64 is the only ABI (at the moment) to support f16 arguments without the
 // need for extending them to wider fp types.
-pub const F16T = if (native_arch.isAARCH64()) f16 else u16;
+pub const F16T = if (arch.isAARCH64()) f16 else u16;
 
 pub fn __extendhfsf2(a: F16T) callconv(.C) f32 {
     return extendXfYf2(f32, f16, @bitCast(u16, a));
 }
 
+pub fn __gnu_h2f_ieee(a: F16T) callconv(.C) f32 {
+    return @call(.{ .modifier = .always_inline }, __extendhfsf2, .{a});
+}
+
 pub fn __extendhftf2(a: F16T) callconv(.C) f128 {
     return extendXfYf2(f128, f16, @bitCast(u16, a));
 }
lib/compiler_rt/fabs.zig
@@ -1,4 +1,23 @@
 const std = @import("std");
+const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__fabsh, .{ .name = "__fabsh", .linkage = linkage });
+    @export(fabsf, .{ .name = "fabsf", .linkage = linkage });
+    @export(fabs, .{ .name = "fabs", .linkage = linkage });
+    @export(__fabsx, .{ .name = "__fabsx", .linkage = linkage });
+    @export(fabsq, .{ .name = "fabsq", .linkage = linkage });
+    @export(fabsl, .{ .name = "fabsl", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(fabsf128, .{ .name = "fabsf128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __fabsh(a: f16) callconv(.C) f16 {
     return generic_fabs(a);
@@ -20,6 +39,10 @@ pub fn fabsq(a: f128) callconv(.C) f128 {
     return generic_fabs(a);
 }
 
+pub fn fabsf128(a: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, fabsq, .{a});
+}
+
 pub fn fabsl(x: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __fabsh(x),
lib/compiler_rt/fixXfYi.zig
@@ -1,7 +1,79 @@
 const std = @import("std");
+const builtin = @import("builtin");
 const math = std.math;
 const Log2Int = math.Log2Int;
-const is_test = @import("builtin").is_test;
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    // Float -> Integral Conversion
+
+    // Conversion from f32
+    @export(__fixsfsi, .{ .name = "__fixsfsi", .linkage = linkage });
+    @export(__fixunssfsi, .{ .name = "__fixunssfsi", .linkage = linkage });
+
+    @export(__fixsfdi, .{ .name = "__fixsfdi", .linkage = linkage });
+    @export(__fixunssfdi, .{ .name = "__fixunssfdi", .linkage = linkage });
+
+    @export(__fixsfti, .{ .name = "__fixsfti", .linkage = linkage });
+    @export(__fixunssfti, .{ .name = "__fixunssfti", .linkage = linkage });
+
+    // Conversion from f64
+    @export(__fixdfsi, .{ .name = "__fixdfsi", .linkage = linkage });
+    @export(__fixunsdfsi, .{ .name = "__fixunsdfsi", .linkage = linkage });
+
+    @export(__fixdfdi, .{ .name = "__fixdfdi", .linkage = linkage });
+    @export(__fixunsdfdi, .{ .name = "__fixunsdfdi", .linkage = linkage });
+
+    @export(__fixdfti, .{ .name = "__fixdfti", .linkage = linkage });
+    @export(__fixunsdfti, .{ .name = "__fixunsdfti", .linkage = linkage });
+
+    // Conversion from f80
+    @export(__fixxfsi, .{ .name = "__fixxfsi", .linkage = linkage });
+    @export(__fixunsxfsi, .{ .name = "__fixunsxfsi", .linkage = linkage });
+
+    @export(__fixxfdi, .{ .name = "__fixxfdi", .linkage = linkage });
+    @export(__fixunsxfdi, .{ .name = "__fixunsxfdi", .linkage = linkage });
+
+    @export(__fixxfti, .{ .name = "__fixxfti", .linkage = linkage });
+    @export(__fixunsxfti, .{ .name = "__fixunsxfti", .linkage = linkage });
+
+    // Conversion from f128
+    @export(__fixtfsi, .{ .name = "__fixtfsi", .linkage = linkage });
+    @export(__fixunstfsi, .{ .name = "__fixunstfsi", .linkage = linkage });
+
+    @export(__fixtfdi, .{ .name = "__fixtfdi", .linkage = linkage });
+    @export(__fixunstfdi, .{ .name = "__fixunstfdi", .linkage = linkage });
+
+    @export(__fixtfti, .{ .name = "__fixtfti", .linkage = linkage });
+    @export(__fixunstfti, .{ .name = "__fixunstfti", .linkage = linkage });
+
+    if (!is_test) {
+        if (arch.isARM() or arch.isThumb()) {
+            @export(__aeabi_f2ulz, .{ .name = "__aeabi_f2ulz", .linkage = linkage });
+            @export(__aeabi_d2ulz, .{ .name = "__aeabi_d2ulz", .linkage = linkage });
+
+            @export(__aeabi_f2lz, .{ .name = "__aeabi_f2lz", .linkage = linkage });
+            @export(__aeabi_d2lz, .{ .name = "__aeabi_d2lz", .linkage = linkage });
+
+            @export(__aeabi_d2uiz, .{ .name = "__aeabi_d2uiz", .linkage = linkage });
+
+            @export(__aeabi_f2uiz, .{ .name = "__aeabi_f2uiz", .linkage = linkage });
+
+            @export(__aeabi_f2iz, .{ .name = "__aeabi_f2iz", .linkage = linkage });
+            @export(__aeabi_d2iz, .{ .name = "__aeabi_d2iz", .linkage = linkage });
+        }
+
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(__fixkfdi, .{ .name = "__fixkfdi", .linkage = linkage });
+            @export(__fixkfsi, .{ .name = "__fixkfsi", .linkage = linkage });
+            @export(__fixunskfsi, .{ .name = "__fixunskfsi", .linkage = linkage });
+            @export(__fixunskfdi, .{ .name = "__fixunskfdi", .linkage = linkage });
+        }
+    }
+}
 
 pub inline fn fixXfYi(comptime I: type, a: anytype) I {
     @setRuntimeSafety(is_test);
@@ -163,18 +235,34 @@ pub fn __fixtfsi(a: f128) callconv(.C) i32 {
     return fixXfYi(i32, a);
 }
 
+pub fn __fixkfsi(a: f128) callconv(.C) i32 {
+    return __fixtfsi(a);
+}
+
 pub fn __fixunstfsi(a: f128) callconv(.C) u32 {
     return fixXfYi(u32, a);
 }
 
+pub fn __fixunskfsi(a: f128) callconv(.C) u32 {
+    return @call(.{ .modifier = .always_inline }, __fixunstfsi, .{a});
+}
+
 pub fn __fixtfdi(a: f128) callconv(.C) i64 {
     return fixXfYi(i64, a);
 }
 
+pub fn __fixkfdi(a: f128) callconv(.C) i64 {
+    return @call(.{ .modifier = .always_inline }, __fixtfdi, .{a});
+}
+
 pub fn __fixunstfdi(a: f128) callconv(.C) u64 {
     return fixXfYi(u64, a);
 }
 
+pub fn __fixunskfdi(a: f128) callconv(.C) u64 {
+    return @call(.{ .modifier = .always_inline }, __fixunstfdi, .{a});
+}
+
 pub fn __fixtfti(a: f128) callconv(.C) i128 {
     return fixXfYi(i128, a);
 }
lib/compiler_rt/floatXiYf.zig
@@ -1,8 +1,77 @@
 const builtin = @import("builtin");
-const is_test = builtin.is_test;
 const std = @import("std");
 const math = std.math;
 const expect = std.testing.expect;
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    // Integral -> Float Conversion
+
+    // Conversion to f32
+    @export(__floatsisf, .{ .name = "__floatsisf", .linkage = linkage });
+    @export(__floatunsisf, .{ .name = "__floatunsisf", .linkage = linkage });
+
+    @export(__floatundisf, .{ .name = "__floatundisf", .linkage = linkage });
+    @export(__floatdisf, .{ .name = "__floatdisf", .linkage = linkage });
+
+    @export(__floattisf, .{ .name = "__floattisf", .linkage = linkage });
+    @export(__floatuntisf, .{ .name = "__floatuntisf", .linkage = linkage });
+
+    // Conversion to f64
+    @export(__floatsidf, .{ .name = "__floatsidf", .linkage = linkage });
+    @export(__floatunsidf, .{ .name = "__floatunsidf", .linkage = linkage });
+
+    @export(__floatdidf, .{ .name = "__floatdidf", .linkage = linkage });
+    @export(__floatundidf, .{ .name = "__floatundidf", .linkage = linkage });
+
+    @export(__floattidf, .{ .name = "__floattidf", .linkage = linkage });
+    @export(__floatuntidf, .{ .name = "__floatuntidf", .linkage = linkage });
+
+    // Conversion to f80
+    @export(__floatsixf, .{ .name = "__floatsixf", .linkage = linkage });
+    @export(__floatunsixf, .{ .name = "__floatunsixf", .linkage = linkage });
+
+    @export(__floatdixf, .{ .name = "__floatdixf", .linkage = linkage });
+    @export(__floatundixf, .{ .name = "__floatundixf", .linkage = linkage });
+
+    @export(__floattixf, .{ .name = "__floattixf", .linkage = linkage });
+    @export(__floatuntixf, .{ .name = "__floatuntixf", .linkage = linkage });
+
+    // Conversion to f128
+    @export(__floatsitf, .{ .name = "__floatsitf", .linkage = linkage });
+    @export(__floatunsitf, .{ .name = "__floatunsitf", .linkage = linkage });
+
+    @export(__floatditf, .{ .name = "__floatditf", .linkage = linkage });
+    @export(__floatunditf, .{ .name = "__floatunditf", .linkage = linkage });
+
+    @export(__floattitf, .{ .name = "__floattitf", .linkage = linkage });
+    @export(__floatuntitf, .{ .name = "__floatuntitf", .linkage = linkage });
+
+    if (!is_test) {
+        if (arch.isARM() or arch.isThumb()) {
+            @export(__aeabi_i2d, .{ .name = "__aeabi_i2d", .linkage = linkage });
+            @export(__aeabi_l2d, .{ .name = "__aeabi_l2d", .linkage = linkage });
+            @export(__aeabi_l2f, .{ .name = "__aeabi_l2f", .linkage = linkage });
+            @export(__aeabi_ui2d, .{ .name = "__aeabi_ui2d", .linkage = linkage });
+            @export(__aeabi_ul2d, .{ .name = "__aeabi_ul2d", .linkage = linkage });
+            @export(__aeabi_ui2f, .{ .name = "__aeabi_ui2f", .linkage = linkage });
+            @export(__aeabi_ul2f, .{ .name = "__aeabi_ul2f", .linkage = linkage });
+
+            @export(__aeabi_i2f, .{ .name = "__aeabi_i2f", .linkage = linkage });
+        }
+
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(__floatsikf, .{ .name = "__floatsikf", .linkage = linkage });
+            @export(__floatdikf, .{ .name = "__floatdikf", .linkage = linkage });
+            @export(__floatundikf, .{ .name = "__floatundikf", .linkage = linkage });
+            @export(__floatunsikf, .{ .name = "__floatunsikf", .linkage = linkage });
+            @export(__floatuntikf, .{ .name = "__floatuntikf", .linkage = linkage });
+        }
+    }
+}
 
 pub fn floatXiYf(comptime T: type, x: anytype) T {
     @setRuntimeSafety(is_test);
@@ -163,18 +232,34 @@ pub fn __floatsitf(a: i32) callconv(.C) f128 {
     return floatXiYf(f128, a);
 }
 
+pub fn __floatsikf(a: i32) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, __floatsitf, .{a});
+}
+
 pub fn __floatunsitf(a: u32) callconv(.C) f128 {
     return floatXiYf(f128, a);
 }
 
+pub fn __floatunsikf(a: u32) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, __floatunsitf, .{a});
+}
+
 pub fn __floatditf(a: i64) callconv(.C) f128 {
     return floatXiYf(f128, a);
 }
 
+pub fn __floatdikf(a: i64) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, __floatditf, .{a});
+}
+
 pub fn __floatunditf(a: u64) callconv(.C) f128 {
     return floatXiYf(f128, a);
 }
 
+pub fn __floatundikf(a: u64) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, __floatunditf, .{a});
+}
+
 pub fn __floattitf(a: i128) callconv(.C) f128 {
     return floatXiYf(f128, a);
 }
@@ -183,6 +268,10 @@ pub fn __floatuntitf(a: u128) callconv(.C) f128 {
     return floatXiYf(f128, a);
 }
 
+pub fn __floatuntikf(a: u128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, __floatuntitf, .{a});
+}
+
 // Conversion to f32
 pub fn __aeabi_ui2f(arg: u32) callconv(.AAPCS) f32 {
     return floatXiYf(f32, arg);
lib/compiler_rt/floor.zig
@@ -5,8 +5,27 @@
 // https://git.musl-libc.org/cgit/musl/tree/src/math/floor.c
 
 const std = @import("std");
+const builtin = @import("builtin");
 const math = std.math;
 const expect = std.testing.expect;
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__floorh, .{ .name = "__floorh", .linkage = linkage });
+    @export(floorf, .{ .name = "floorf", .linkage = linkage });
+    @export(floor, .{ .name = "floor", .linkage = linkage });
+    @export(__floorx, .{ .name = "__floorx", .linkage = linkage });
+    @export(floorq, .{ .name = "floorq", .linkage = linkage });
+    @export(floorl, .{ .name = "floorl", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(floorf128, .{ .name = "floorf128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __floorh(x: f16) callconv(.C) f16 {
     var u = @bitCast(u16, x);
@@ -141,6 +160,10 @@ pub fn floorq(x: f128) callconv(.C) f128 {
     }
 }
 
+pub fn floorf128(x: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, floorq, .{x});
+}
+
 pub fn floorl(x: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __floorh(x),
lib/compiler_rt/fma.zig
@@ -6,8 +6,27 @@
 // https://git.musl-libc.org/cgit/musl/tree/src/math/fma.c
 
 const std = @import("std");
+const builtin = @import("builtin");
 const math = std.math;
 const expect = std.testing.expect;
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__fmah, .{ .name = "__fmah", .linkage = linkage });
+    @export(fmaf, .{ .name = "fmaf", .linkage = linkage });
+    @export(fma, .{ .name = "fma", .linkage = linkage });
+    @export(__fmax, .{ .name = "__fmax", .linkage = linkage });
+    @export(fmaq, .{ .name = "fmaq", .linkage = linkage });
+    @export(fmal, .{ .name = "fmal", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(fmaf128, .{ .name = "fmaf128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __fmah(x: f16, y: f16, z: f16) callconv(.C) f16 {
     // TODO: more efficient implementation
@@ -135,6 +154,10 @@ pub fn fmaq(x: f128, y: f128, z: f128) callconv(.C) f128 {
     }
 }
 
+pub fn fmaf128(x: f128, y: f128, z: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, fmaq, .{ x, y, z });
+}
+
 pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __fmah(x, y, z),
lib/compiler_rt/fmax.zig
@@ -1,5 +1,24 @@
 const std = @import("std");
+const builtin = @import("builtin");
 const math = std.math;
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__fmaxh, .{ .name = "__fmaxh", .linkage = linkage });
+    @export(fmaxf, .{ .name = "fmaxf", .linkage = linkage });
+    @export(fmax, .{ .name = "fmax", .linkage = linkage });
+    @export(__fmaxx, .{ .name = "__fmaxx", .linkage = linkage });
+    @export(fmaxq, .{ .name = "fmaxq", .linkage = linkage });
+    @export(fmaxl, .{ .name = "fmaxl", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(fmaxf128, .{ .name = "fmaxf128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __fmaxh(x: f16, y: f16) callconv(.C) f16 {
     return generic_fmax(f16, x, y);
@@ -21,6 +40,10 @@ pub fn fmaxq(x: f128, y: f128) callconv(.C) f128 {
     return generic_fmax(f128, x, y);
 }
 
+pub fn fmaxf128(x: f128, y: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, fmaxq, .{ x, y });
+}
+
 pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __fmaxh(x, y),
lib/compiler_rt/fmin.zig
@@ -1,5 +1,24 @@
 const std = @import("std");
+const builtin = @import("builtin");
 const math = std.math;
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__fminh, .{ .name = "__fminh", .linkage = linkage });
+    @export(fminf, .{ .name = "fminf", .linkage = linkage });
+    @export(fmin, .{ .name = "fmin", .linkage = linkage });
+    @export(__fminx, .{ .name = "__fminx", .linkage = linkage });
+    @export(fminq, .{ .name = "fminq", .linkage = linkage });
+    @export(fminl, .{ .name = "fminl", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(fminf128, .{ .name = "fminf128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __fminh(x: f16, y: f16) callconv(.C) f16 {
     return generic_fmin(f16, x, y);
@@ -21,6 +40,10 @@ pub fn fminq(x: f128, y: f128) callconv(.C) f128 {
     return generic_fmin(f128, x, y);
 }
 
+pub fn fminf128(x: f128, y: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, fminq, .{ x, y });
+}
+
 pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __fminh(x, y),
lib/compiler_rt/fmod.zig
@@ -2,7 +2,27 @@ const builtin = @import("builtin");
 const std = @import("std");
 const math = std.math;
 const assert = std.debug.assert;
-const normalize = @import("divdf3.zig").normalize;
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+
+const common = @import("common.zig");
+const normalize = common.normalize;
+pub const panic = common.panic;
+
+comptime {
+    @export(__fmodh, .{ .name = "__fmodh", .linkage = linkage });
+    @export(fmodf, .{ .name = "fmodf", .linkage = linkage });
+    @export(fmod, .{ .name = "fmod", .linkage = linkage });
+    @export(__fmodx, .{ .name = "__fmodx", .linkage = linkage });
+    @export(fmodq, .{ .name = "fmodq", .linkage = linkage });
+    @export(fmodl, .{ .name = "fmodl", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(fmodf128, .{ .name = "fmodf128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __fmodh(x: f16, y: f16) callconv(.C) f16 {
     // TODO: more efficient implementation
@@ -237,6 +257,10 @@ pub fn fmodq(a: f128, b: f128) callconv(.C) f128 {
     return amod;
 }
 
+pub fn fmodf128(a: f128, b: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, fmodq, .{ a, b });
+}
+
 pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __fmodh(a, b),
lib/compiler_rt/int.zig
@@ -4,9 +4,36 @@ const std = @import("std");
 const testing = std.testing;
 const maxInt = std.math.maxInt;
 const minInt = std.math.minInt;
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
 
 const udivmod = @import("udivmod.zig").udivmod;
 
+comptime {
+    @export(__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = linkage });
+    @export(__mulsi3, .{ .name = "__mulsi3", .linkage = linkage });
+    @export(__divmoddi4, .{ .name = "__divmoddi4", .linkage = linkage });
+    @export(__divsi3, .{ .name = "__divsi3", .linkage = linkage });
+    @export(__divdi3, .{ .name = "__divdi3", .linkage = linkage });
+    @export(__udivsi3, .{ .name = "__udivsi3", .linkage = linkage });
+    @export(__udivdi3, .{ .name = "__udivdi3", .linkage = linkage });
+    @export(__modsi3, .{ .name = "__modsi3", .linkage = linkage });
+    @export(__moddi3, .{ .name = "__moddi3", .linkage = linkage });
+    @export(__umodsi3, .{ .name = "__umodsi3", .linkage = linkage });
+    @export(__umoddi3, .{ .name = "__umoddi3", .linkage = linkage });
+    @export(__divmodsi4, .{ .name = "__divmodsi4", .linkage = linkage });
+    @export(__udivmodsi4, .{ .name = "__udivmodsi4", .linkage = linkage });
+
+    if (!is_test) {
+        if (arch.isARM() or arch.isThumb()) {
+            @export(__aeabi_idiv, .{ .name = "__aeabi_idiv", .linkage = linkage });
+            @export(__aeabi_uidiv, .{ .name = "__aeabi_uidiv", .linkage = linkage });
+        }
+    }
+}
+
 pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.C) i64 {
     @setRuntimeSafety(builtin.is_test);
 
@@ -187,6 +214,10 @@ pub fn __divsi3(n: i32, d: i32) callconv(.C) i32 {
     return @bitCast(i32, (res ^ sign) -% sign);
 }
 
+pub fn __aeabi_idiv(n: i32, d: i32) callconv(.C) i32 {
+    return @call(.{ .modifier = .always_inline }, __divsi3, .{ n, d });
+}
+
 test "test_divsi3" {
     const cases = [_][3]i32{
         [_]i32{ 0, 1, 0 },
@@ -253,6 +284,10 @@ pub fn __udivsi3(n: u32, d: u32) callconv(.C) u32 {
     return q;
 }
 
+pub fn __aeabi_uidiv(n: u32, d: u32) callconv(.C) u32 {
+    return @call(.{ .modifier = .always_inline }, __udivsi3, .{ n, d });
+}
+
 test "test_udivsi3" {
     const cases = [_][3]u32{
         [_]u32{ 0x00000000, 0x00000001, 0x00000000 },
lib/compiler_rt/log.zig
@@ -5,8 +5,27 @@
 // https://git.musl-libc.org/cgit/musl/tree/src/math/ln.c
 
 const std = @import("std");
+const builtin = @import("builtin");
 const math = std.math;
 const testing = std.testing;
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__logh, .{ .name = "__logh", .linkage = linkage });
+    @export(logf, .{ .name = "logf", .linkage = linkage });
+    @export(log, .{ .name = "log", .linkage = linkage });
+    @export(__logx, .{ .name = "__logx", .linkage = linkage });
+    @export(logq, .{ .name = "logq", .linkage = linkage });
+    @export(logl, .{ .name = "logl", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(logf128, .{ .name = "logf128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __logh(a: f16) callconv(.C) f16 {
     // TODO: more efficient implementation
@@ -131,6 +150,10 @@ pub fn logq(a: f128) callconv(.C) f128 {
     return log(@floatCast(f64, a));
 }
 
+pub fn logf128(a: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, logq, .{a});
+}
+
 pub fn logl(x: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __logh(x),
lib/compiler_rt/log10.zig
@@ -5,9 +5,28 @@
 // https://git.musl-libc.org/cgit/musl/tree/src/math/log10.c
 
 const std = @import("std");
+const builtin = @import("builtin");
 const math = std.math;
 const testing = std.testing;
 const maxInt = std.math.maxInt;
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__log10h, .{ .name = "__log10h", .linkage = linkage });
+    @export(log10f, .{ .name = "log10f", .linkage = linkage });
+    @export(log10, .{ .name = "log10", .linkage = linkage });
+    @export(__log10x, .{ .name = "__log10x", .linkage = linkage });
+    @export(log10q, .{ .name = "log10q", .linkage = linkage });
+    @export(log10l, .{ .name = "log10l", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(log10f128, .{ .name = "log10f128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __log10h(a: f16) callconv(.C) f16 {
     // TODO: more efficient implementation
@@ -159,6 +178,10 @@ pub fn log10q(a: f128) callconv(.C) f128 {
     return log10(@floatCast(f64, a));
 }
 
+pub fn log10f128(a: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, log10q, .{a});
+}
+
 pub fn log10l(x: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __log10h(x),
lib/compiler_rt/log2.zig
@@ -5,9 +5,28 @@
 // https://git.musl-libc.org/cgit/musl/tree/src/math/log2.c
 
 const std = @import("std");
+const builtin = @import("builtin");
 const math = std.math;
 const expect = std.testing.expect;
 const maxInt = std.math.maxInt;
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__log2h, .{ .name = "__log2h", .linkage = linkage });
+    @export(log2f, .{ .name = "log2f", .linkage = linkage });
+    @export(log2, .{ .name = "log2", .linkage = linkage });
+    @export(__log2x, .{ .name = "__log2x", .linkage = linkage });
+    @export(log2q, .{ .name = "log2q", .linkage = linkage });
+    @export(log2l, .{ .name = "log2l", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(log2f128, .{ .name = "log2f128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __log2h(a: f16) callconv(.C) f16 {
     // TODO: more efficient implementation
@@ -151,6 +170,10 @@ pub fn log2q(a: f128) callconv(.C) f128 {
     return log2(@floatCast(f64, a));
 }
 
+pub fn log2f128(a: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, log2q, .{a});
+}
+
 pub fn log2l(x: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __log2h(x),
lib/compiler_rt/modti3.zig
@@ -2,9 +2,34 @@
 //
 // https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/modti3.c
 
-const udivmod = @import("udivmod.zig").udivmod;
+const std = @import("std");
 const builtin = @import("builtin");
-const compiler_rt = @import("../compiler_rt.zig");
+const udivmod = @import("udivmod.zig").udivmod;
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    if (builtin.os.tag == .windows) {
+        switch (arch) {
+            .i386 => {
+                @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
+            },
+            .x86_64 => {
+                // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI
+                // that LLVM expects compiler-rt to have.
+                @export(__modti3_windows_x86_64, .{ .name = "__modti3", .linkage = linkage });
+            },
+            else => {},
+        }
+        if (arch.isAARCH64()) {
+            @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
+        }
+    } else {
+        @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
+    }
+}
 
 pub fn __modti3(a: i128, b: i128) callconv(.C) i128 {
     @setRuntimeSafety(builtin.is_test);
lib/compiler_rt/muldi3.zig
@@ -1,7 +1,20 @@
 const std = @import("std");
 const builtin = @import("builtin");
-const is_test = builtin.is_test;
 const native_endian = builtin.cpu.arch.endian();
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__muldi3, .{ .name = "__muldi3", .linkage = linkage });
+
+    if (!is_test) {
+        if (arch.isARM() or arch.isThumb()) {
+            @export(__aeabi_lmul, .{ .name = "__aeabi_lmul", .linkage = linkage });
+        }
+    }
+}
 
 // Ported from
 // https://github.com/llvm/llvm-project/blob/llvmorg-9.0.0/compiler-rt/lib/builtins/muldi3.c
@@ -20,7 +33,11 @@ const dwords = extern union {
     },
 };
 
-fn __muldsi3(a: u32, b: u32) i64 {
+pub fn __aeabi_lmul(a: i64, b: i64) callconv(.C) i64 {
+    return @call(.{ .modifier = .always_inline }, __muldi3, .{ a, b });
+}
+
+pub fn __muldsi3(a: u32, b: u32) i64 {
     @setRuntimeSafety(is_test);
 
     const bits_in_word_2 = @sizeOf(i32) * 8 / 2;
lib/compiler_rt/mulo.zig
@@ -1,6 +1,15 @@
-const builtin = @import("builtin");
 const std = @import("std");
+const builtin = @import("builtin");
 const math = std.math;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__mulosi4, .{ .name = "__mulosi4", .linkage = linkage });
+    @export(__mulodi4, .{ .name = "__mulodi4", .linkage = linkage });
+    @export(__muloti4, .{ .name = "__muloti4", .linkage = linkage });
+}
 
 // mulo - multiplication overflow
 // * return a*%b.
lib/compiler_rt/multi3.zig
@@ -1,13 +1,33 @@
-const compiler_rt = @import("../compiler_rt.zig");
 const std = @import("std");
 const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
 const is_test = builtin.is_test;
 const native_endian = builtin.cpu.arch.endian();
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
 
 // Ported from git@github.com:llvm-project/llvm-project-20170507.git
 // ae684fad6d34858c014c94da69c15e7774a633c3
 // 2018-08-13
 
+comptime {
+    if (builtin.os.tag == .windows) {
+        switch (arch) {
+            .i386 => {
+                @export(__multi3, .{ .name = "__multi3", .linkage = linkage });
+            },
+            .x86_64 => {
+                // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI
+                // that LLVM expects compiler-rt to have.
+                @export(__multi3_windows_x86_64, .{ .name = "__multi3", .linkage = linkage });
+            },
+            else => {},
+        }
+    } else {
+        @export(__multi3, .{ .name = "__multi3", .linkage = linkage });
+    }
+}
+
 pub fn __multi3(a: i128, b: i128) callconv(.C) i128 {
     @setRuntimeSafety(is_test);
     const x = twords{ .all = a };
@@ -25,7 +45,7 @@ pub fn __multi3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 {
     }));
 }
 
-fn __mulddi3(a: u64, b: u64) i128 {
+pub fn __mulddi3(a: u64, b: u64) i128 {
     const bits_in_dword_2 = (@sizeOf(i64) * 8) / 2;
     const lower_mask = ~@as(u64, 0) >> bits_in_dword_2;
     var r: twords = undefined;
lib/compiler_rt/mulXf3.zig
@@ -5,8 +5,32 @@
 const std = @import("std");
 const math = std.math;
 const builtin = @import("builtin");
-const compiler_rt = @import("../compiler_rt.zig");
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__mulsf3, .{ .name = "__mulsf3", .linkage = linkage });
+    @export(__muldf3, .{ .name = "__muldf3", .linkage = linkage });
+    @export(__mulxf3, .{ .name = "__mulxf3", .linkage = linkage });
+    @export(__multf3, .{ .name = "__multf3", .linkage = linkage });
+
+    if (!is_test) {
+        if (arch.isARM() or arch.isThumb()) {
+            @export(__aeabi_fmul, .{ .name = "__aeabi_fmul", .linkage = linkage });
+            @export(__aeabi_dmul, .{ .name = "__aeabi_dmul", .linkage = linkage });
+        }
+
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(__mulkf3, .{ .name = "__mulkf3", .linkage = linkage });
+        }
+    }
+}
 
+pub fn __mulkf3(a: f128, b: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, __multf3, .{ a, b });
+}
 pub fn __multf3(a: f128, b: f128) callconv(.C) f128 {
     return mulXf3(f128, a, b);
 }
@@ -30,7 +54,7 @@ pub fn __aeabi_dmul(a: f64, b: f64) callconv(.C) f64 {
     return @call(.{ .modifier = .always_inline }, __muldf3, .{ a, b });
 }
 
-fn mulXf3(comptime T: type, a: T, b: T) T {
+pub fn mulXf3(comptime T: type, a: T, b: T) T {
     @setRuntimeSafety(builtin.is_test);
     const typeWidth = @typeInfo(T).Float.bits;
     const significandBits = math.floatMantissaBits(T);
lib/compiler_rt/negv.zig
@@ -1,6 +1,17 @@
 // negv - negate oVerflow
 // * @panic, if result can not be represented
 // - negvXi4_generic for unoptimized version
+const std = @import("std");
+const builtin = @import("builtin");
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__negvsi2, .{ .name = "__negvsi2", .linkage = linkage });
+    @export(__negvdi2, .{ .name = "__negvdi2", .linkage = linkage });
+    @export(__negvti2, .{ .name = "__negvti2", .linkage = linkage });
+}
 
 // assume -0 == 0 is gracefully handled by the hardware
 inline fn negvXi(comptime ST: type, a: ST) ST {
lib/compiler_rt/negXf2.zig
@@ -1,4 +1,21 @@
 const std = @import("std");
+const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__negsf2, .{ .name = "__negsf2", .linkage = linkage });
+    @export(__negdf2, .{ .name = "__negdf2", .linkage = linkage });
+
+    if (!is_test) {
+        if (arch.isARM() or arch.isThumb()) {
+            @export(__aeabi_fneg, .{ .name = "__aeabi_fneg", .linkage = linkage });
+            @export(__aeabi_dneg, .{ .name = "__aeabi_dneg", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __negsf2(a: f32) callconv(.C) f32 {
     return negXf2(f32, a);
lib/compiler_rt/negXi2.zig
@@ -1,5 +1,14 @@
 const std = @import("std");
 const builtin = @import("builtin");
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__negsi2, .{ .name = "__negsi2", .linkage = linkage });
+    @export(__negdi2, .{ .name = "__negdi2", .linkage = linkage });
+    @export(__negti2, .{ .name = "__negti2", .linkage = linkage });
+}
 
 // neg - negate (the number)
 // - negXi2 for unoptimized little and big endian
lib/compiler_rt/os_version_check.zig
@@ -1,5 +1,17 @@
-const testing = @import("std").testing;
+const std = @import("std");
+const testing = std.testing;
 const builtin = @import("builtin");
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    if (builtin.os.tag.isDarwin()) {
+        @export(IsPlatformVersionAtLeast.__isPlatformVersionAtLeast, .{
+            .name = "__isPlatformVersionAtLeast",
+            .linkage = linkage,
+        });
+    }
+}
 
 // Ported from llvm-project 13.0.0 d7b669b3a30345cfcdb2fde2af6f48aa4b94845d
 //
@@ -16,34 +28,36 @@ const builtin = @import("builtin");
 // the newer codepath, which merely calls out to the Darwin _availability_version_check API which is
 // available on macOS 10.15+, iOS 13+, tvOS 13+ and watchOS 6+.
 
-inline fn constructVersion(major: u32, minor: u32, subminor: u32) u32 {
-    return ((major & 0xffff) << 16) | ((minor & 0xff) << 8) | (subminor & 0xff);
-}
+const IsPlatformVersionAtLeast = struct {
+    inline fn constructVersion(major: u32, minor: u32, subminor: u32) u32 {
+        return ((major & 0xffff) << 16) | ((minor & 0xff) << 8) | (subminor & 0xff);
+    }
 
-// Darwin-only
-pub fn __isPlatformVersionAtLeast(platform: u32, major: u32, minor: u32, subminor: u32) callconv(.C) i32 {
-    const build_version = dyld_build_version_t{
-        .platform = platform,
-        .version = constructVersion(major, minor, subminor),
-    };
-    return @boolToInt(_availability_version_check(1, &[_]dyld_build_version_t{build_version}));
-}
+    // Darwin-only
+    fn __isPlatformVersionAtLeast(platform: u32, major: u32, minor: u32, subminor: u32) callconv(.C) i32 {
+        const build_version = dyld_build_version_t{
+            .platform = platform,
+            .version = constructVersion(major, minor, subminor),
+        };
+        return @boolToInt(_availability_version_check(1, &[_]dyld_build_version_t{build_version}));
+    }
 
-// _availability_version_check darwin API support.
-const dyld_platform_t = u32;
-const dyld_build_version_t = extern struct {
-    platform: dyld_platform_t,
-    version: u32,
+    // _availability_version_check darwin API support.
+    const dyld_platform_t = u32;
+    const dyld_build_version_t = extern struct {
+        platform: dyld_platform_t,
+        version: u32,
+    };
+    // Darwin-only
+    extern "c" fn _availability_version_check(count: u32, versions: [*c]const dyld_build_version_t) bool;
 };
-// Darwin-only
-extern "c" fn _availability_version_check(count: u32, versions: [*c]const dyld_build_version_t) bool;
 
 test "isPlatformVersionAtLeast" {
-    if (!builtin.os.tag.isDarwin()) return error.SkipZigTest;
+    if (!comptime builtin.os.tag.isDarwin()) return error.SkipZigTest;
 
     // Note: this test depends on the actual host OS version since it is merely calling into the
     // native Darwin API.
     const macos_platform_constant = 1;
-    try testing.expect(__isPlatformVersionAtLeast(macos_platform_constant, 10, 0, 15) == 1);
-    try testing.expect(__isPlatformVersionAtLeast(macos_platform_constant, 99, 0, 0) == 0);
+    try testing.expect(IsPlatformVersionAtLeast.__isPlatformVersionAtLeast(macos_platform_constant, 10, 0, 15) == 1);
+    try testing.expect(IsPlatformVersionAtLeast.__isPlatformVersionAtLeast(macos_platform_constant, 99, 0, 0) == 0);
 }
lib/compiler_rt/parity.zig
@@ -1,5 +1,14 @@
 const std = @import("std");
 const builtin = @import("builtin");
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__paritysi2, .{ .name = "__paritysi2", .linkage = linkage });
+    @export(__paritydi2, .{ .name = "__paritydi2", .linkage = linkage });
+    @export(__parityti2, .{ .name = "__parityti2", .linkage = linkage });
+}
 
 // parity - if number of bits set is even => 0, else => 1
 // - pariytXi2_generic for big and little endian
lib/compiler_rt/popcount.zig
@@ -1,5 +1,14 @@
 const builtin = @import("builtin");
 const std = @import("std");
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__popcountsi2, .{ .name = "__popcountsi2", .linkage = linkage });
+    @export(__popcountdi2, .{ .name = "__popcountdi2", .linkage = linkage });
+    @export(__popcountti2, .{ .name = "__popcountti2", .linkage = linkage });
+}
 
 // popcount - population count
 // counts the number of 1 bits
lib/compiler_rt/round.zig
@@ -5,8 +5,27 @@
 // https://git.musl-libc.org/cgit/musl/tree/src/math/round.c
 
 const std = @import("std");
+const builtin = @import("builtin");
 const math = std.math;
 const expect = std.testing.expect;
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__roundh, .{ .name = "__roundh", .linkage = linkage });
+    @export(roundf, .{ .name = "roundf", .linkage = linkage });
+    @export(round, .{ .name = "round", .linkage = linkage });
+    @export(__roundx, .{ .name = "__roundx", .linkage = linkage });
+    @export(roundq, .{ .name = "roundq", .linkage = linkage });
+    @export(roundl, .{ .name = "roundl", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(roundf128, .{ .name = "roundf128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __roundh(x: f16) callconv(.C) f16 {
     // TODO: more efficient implementation
@@ -123,6 +142,10 @@ pub fn roundq(x_: f128) callconv(.C) f128 {
     }
 }
 
+pub fn roundf128(x_: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, roundq, .{x_});
+}
+
 pub fn roundl(x: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __roundh(x),
lib/compiler_rt/shift.zig
@@ -1,13 +1,35 @@
 const std = @import("std");
+const builtin = @import("builtin");
 const Log2Int = std.math.Log2Int;
-const native_endian = @import("builtin").cpu.arch.endian();
+const native_endian = builtin.cpu.arch.endian();
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__ashldi3, .{ .name = "__ashldi3", .linkage = linkage });
+    @export(__ashlti3, .{ .name = "__ashlti3", .linkage = linkage });
+    @export(__ashrdi3, .{ .name = "__ashrdi3", .linkage = linkage });
+    @export(__ashrti3, .{ .name = "__ashrti3", .linkage = linkage });
+    @export(__lshrdi3, .{ .name = "__lshrdi3", .linkage = linkage });
+    @export(__lshrti3, .{ .name = "__lshrti3", .linkage = linkage });
+
+    if (!is_test) {
+        if (arch.isARM() or arch.isThumb()) {
+            @export(__aeabi_llsl, .{ .name = "__aeabi_llsl", .linkage = linkage });
+            @export(__aeabi_lasr, .{ .name = "__aeabi_lasr", .linkage = linkage });
+            @export(__aeabi_llsr, .{ .name = "__aeabi_llsr", .linkage = linkage });
+        }
+    }
+}
 
 fn Dwords(comptime T: type, comptime signed_half: bool) type {
     return extern union {
-        pub const bits = @divExact(@typeInfo(T).Int.bits, 2);
-        pub const HalfTU = std.meta.Int(.unsigned, bits);
-        pub const HalfTS = std.meta.Int(.signed, bits);
-        pub const HalfT = if (signed_half) HalfTS else HalfTU;
+        const bits = @divExact(@typeInfo(T).Int.bits, 2);
+        const HalfTU = std.meta.Int(.unsigned, bits);
+        const HalfTS = std.meta.Int(.signed, bits);
+        const HalfT = if (signed_half) HalfTS else HalfTU;
 
         all: T,
         s: if (native_endian == .Little)
@@ -19,7 +41,7 @@ fn Dwords(comptime T: type, comptime signed_half: bool) type {
 
 // Arithmetic shift left
 // Precondition: 0 <= b < bits_in_dword
-pub inline fn ashlXi3(comptime T: type, a: T, b: i32) T {
+inline fn ashlXi3(comptime T: type, a: T, b: i32) T {
     const dwords = Dwords(T, false);
     const S = Log2Int(dwords.HalfT);
 
@@ -42,7 +64,7 @@ pub inline fn ashlXi3(comptime T: type, a: T, b: i32) T {
 
 // Arithmetic shift right
 // Precondition: 0 <= b < T.bit_count
-pub inline fn ashrXi3(comptime T: type, a: T, b: i32) T {
+inline fn ashrXi3(comptime T: type, a: T, b: i32) T {
     const dwords = Dwords(T, true);
     const S = Log2Int(dwords.HalfT);
 
@@ -69,7 +91,7 @@ pub inline fn ashrXi3(comptime T: type, a: T, b: i32) T {
 
 // Logical shift right
 // Precondition: 0 <= b < T.bit_count
-pub inline fn lshrXi3(comptime T: type, a: T, b: i32) T {
+inline fn lshrXi3(comptime T: type, a: T, b: i32) T {
     const dwords = Dwords(T, false);
     const S = Log2Int(dwords.HalfT);
 
lib/compiler_rt/sin.zig
@@ -5,13 +5,32 @@
 // https://git.musl-libc.org/cgit/musl/tree/src/math/sin.c
 
 const std = @import("std");
+const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
 const math = std.math;
 const expect = std.testing.expect;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
 
 const trig = @import("trig.zig");
 const rem_pio2 = @import("rem_pio2.zig").rem_pio2;
 const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;
 
+comptime {
+    @export(__sinh, .{ .name = "__sinh", .linkage = linkage });
+    @export(sinf, .{ .name = "sinf", .linkage = linkage });
+    @export(sin, .{ .name = "sin", .linkage = linkage });
+    @export(__sinx, .{ .name = "__sinx", .linkage = linkage });
+    @export(sinq, .{ .name = "sinq", .linkage = linkage });
+    @export(sinl, .{ .name = "sinl", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(sinf128, .{ .name = "sinf128", .linkage = linkage });
+        }
+    }
+}
+
 pub fn __sinh(x: f16) callconv(.C) f16 {
     // TODO: more efficient implementation
     return @floatCast(f16, sinf(x));
@@ -111,6 +130,10 @@ pub fn sinq(x: f128) callconv(.C) f128 {
     return sin(@floatCast(f64, x));
 }
 
+pub fn sinf128(x: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, sinq, .{x});
+}
+
 pub fn sinl(x: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __sinh(x),
lib/compiler_rt/sincos.zig
@@ -1,10 +1,27 @@
 const std = @import("std");
+const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
 const math = std.math;
-const sin = @import("sin.zig");
-const cos = @import("cos.zig");
 const trig = @import("trig.zig");
 const rem_pio2 = @import("rem_pio2.zig").rem_pio2;
 const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__sincosh, .{ .name = "__sincosh", .linkage = linkage });
+    @export(sincosf, .{ .name = "sincosf", .linkage = linkage });
+    @export(sincos, .{ .name = "sincos", .linkage = linkage });
+    @export(__sincosx, .{ .name = "__sincosx", .linkage = linkage });
+    @export(sincosq, .{ .name = "sincosq", .linkage = linkage });
+    @export(sincosl, .{ .name = "sincosl", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(sincosf128, .{ .name = "sincosf128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __sincosh(x: f16, r_sin: *f16, r_cos: *f16) callconv(.C) void {
     // TODO: more efficient implementation
@@ -181,6 +198,10 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.C) void {
     r_cos.* = small_cos;
 }
 
+pub fn sincosf128(x: f128, r_sin: *f128, r_cos: *f128) callconv(.C) void {
+    return @call(.{ .modifier = .always_inline }, sincosq, .{ x, r_sin, r_cos });
+}
+
 pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.C) void {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __sincosh(x, r_sin, r_cos),
@@ -192,7 +213,7 @@ pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) call
     }
 }
 
-const rem_pio2_generic = @compileError("TODO");
+pub const rem_pio2_generic = @compileError("TODO");
 
 /// Ported from musl sincosl.c. Needs the following dependencies to be complete:
 /// * rem_pio2_generic ported from __rem_pio2l.c
lib/compiler_rt/sparc.zig
@@ -3,6 +3,40 @@
 
 const std = @import("std");
 const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    if (arch.isSPARC()) {
+        // SPARC systems use a different naming scheme
+        @export(_Qp_add, .{ .name = "_Qp_add", .linkage = linkage });
+        @export(_Qp_div, .{ .name = "_Qp_div", .linkage = linkage });
+        @export(_Qp_mul, .{ .name = "_Qp_mul", .linkage = linkage });
+        @export(_Qp_sub, .{ .name = "_Qp_sub", .linkage = linkage });
+
+        @export(_Qp_cmp, .{ .name = "_Qp_cmp", .linkage = linkage });
+        @export(_Qp_feq, .{ .name = "_Qp_feq", .linkage = linkage });
+        @export(_Qp_fne, .{ .name = "_Qp_fne", .linkage = linkage });
+        @export(_Qp_flt, .{ .name = "_Qp_flt", .linkage = linkage });
+        @export(_Qp_fle, .{ .name = "_Qp_fle", .linkage = linkage });
+        @export(_Qp_fgt, .{ .name = "_Qp_fgt", .linkage = linkage });
+        @export(_Qp_fge, .{ .name = "_Qp_fge", .linkage = linkage });
+
+        @export(_Qp_itoq, .{ .name = "_Qp_itoq", .linkage = linkage });
+        @export(_Qp_uitoq, .{ .name = "_Qp_uitoq", .linkage = linkage });
+        @export(_Qp_xtoq, .{ .name = "_Qp_xtoq", .linkage = linkage });
+        @export(_Qp_uxtoq, .{ .name = "_Qp_uxtoq", .linkage = linkage });
+        @export(_Qp_stoq, .{ .name = "_Qp_stoq", .linkage = linkage });
+        @export(_Qp_dtoq, .{ .name = "_Qp_dtoq", .linkage = linkage });
+        @export(_Qp_qtoi, .{ .name = "_Qp_qtoi", .linkage = linkage });
+        @export(_Qp_qtoui, .{ .name = "_Qp_qtoui", .linkage = linkage });
+        @export(_Qp_qtox, .{ .name = "_Qp_qtox", .linkage = linkage });
+        @export(_Qp_qtoux, .{ .name = "_Qp_qtoux", .linkage = linkage });
+        @export(_Qp_qtos, .{ .name = "_Qp_qtos", .linkage = linkage });
+        @export(_Qp_qtod, .{ .name = "_Qp_qtod", .linkage = linkage });
+    }
+}
 
 // The SPARC Architecture Manual, Version 9:
 // A.13 Floating-Point Compare
lib/compiler_rt/sqrt.zig
@@ -1,5 +1,24 @@
 const std = @import("std");
+const builtin = @import("builtin");
+const arch = builtin.cpu.arch;
 const math = std.math;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__sqrth, .{ .name = "__sqrth", .linkage = linkage });
+    @export(sqrtf, .{ .name = "sqrtf", .linkage = linkage });
+    @export(sqrt, .{ .name = "sqrt", .linkage = linkage });
+    @export(__sqrtx, .{ .name = "__sqrtx", .linkage = linkage });
+    @export(sqrtq, .{ .name = "sqrtq", .linkage = linkage });
+    @export(sqrtl, .{ .name = "sqrtl", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(sqrtf128, .{ .name = "sqrtf128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __sqrth(x: f16) callconv(.C) f16 {
     // TODO: more efficient implementation
@@ -236,6 +255,10 @@ pub fn sqrtl(x: c_longdouble) callconv(.C) c_longdouble {
     }
 }
 
+pub fn sqrtf128(x: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, sqrtq, .{x});
+}
+
 test "sqrtf" {
     const V = [_]f32{
         0.0,
lib/compiler_rt/stack_probe.zig
@@ -1,4 +1,43 @@
-const native_arch = @import("builtin").cpu.arch;
+const std = @import("std");
+const builtin = @import("builtin");
+const os_tag = builtin.os.tag;
+const arch = builtin.cpu.arch;
+const abi = builtin.abi;
+const is_test = builtin.is_test;
+
+const is_gnu = abi.isGnu();
+const is_mingw = os_tag == .windows and is_gnu;
+
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+const strong_linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Strong;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    if (builtin.os.tag == .windows) {
+        // Default stack-probe functions emitted by LLVM
+        if (is_mingw) {
+            @export(_chkstk, .{ .name = "_alloca", .linkage = strong_linkage });
+            @export(___chkstk_ms, .{ .name = "___chkstk_ms", .linkage = strong_linkage });
+        } else if (!builtin.link_libc) {
+            // This symbols are otherwise exported by MSVCRT.lib
+            @export(_chkstk, .{ .name = "_chkstk", .linkage = strong_linkage });
+            @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
+        }
+
+        if (arch.isAARCH64()) {
+            @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
+        }
+    }
+
+    switch (arch) {
+        .i386,
+        .x86_64,
+        => {
+            @export(zig_probe_stack, .{ .name = "__zig_probe_stack", .linkage = linkage });
+        },
+        else => {},
+    }
+}
 
 // Zig's own stack-probe routine (available only on x86 and x86_64)
 pub fn zig_probe_stack() callconv(.Naked) void {
@@ -8,7 +47,7 @@ pub fn zig_probe_stack() callconv(.Naked) void {
     // invalid so let's update it on the go, otherwise we'll get a segfault
     // instead of triggering the stack growth.
 
-    switch (native_arch) {
+    switch (arch) {
         .x86_64 => {
             // %rax = probe length, %rsp = stack pointer
             asm volatile (
@@ -60,7 +99,7 @@ pub fn zig_probe_stack() callconv(.Naked) void {
 fn win_probe_stack_only() void {
     @setRuntimeSafety(false);
 
-    switch (native_arch) {
+    switch (arch) {
         .x86_64 => {
             asm volatile (
                 \\         push   %%rcx
@@ -105,7 +144,7 @@ fn win_probe_stack_only() void {
         },
         else => {},
     }
-    if (comptime native_arch.isAARCH64()) {
+    if (comptime arch.isAARCH64()) {
         // NOTE: page size hardcoded to 4096 for now
         asm volatile (
             \\        lsl    x16, x15, #4
@@ -127,7 +166,7 @@ fn win_probe_stack_only() void {
 fn win_probe_stack_adjust_sp() void {
     @setRuntimeSafety(false);
 
-    switch (native_arch) {
+    switch (arch) {
         .x86_64 => {
             asm volatile (
                 \\         push   %%rcx
@@ -201,9 +240,9 @@ pub fn _chkstk() callconv(.Naked) void {
 }
 pub fn __chkstk() callconv(.Naked) void {
     @setRuntimeSafety(false);
-    if (comptime native_arch.isAARCH64()) {
+    if (comptime arch.isAARCH64()) {
         @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{});
-    } else switch (native_arch) {
+    } else switch (arch) {
         .i386 => @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}),
         .x86_64 => @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{}),
         else => unreachable,
lib/compiler_rt/subo.zig
@@ -1,4 +1,14 @@
+const std = @import("std");
 const builtin = @import("builtin");
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__subosi4, .{ .name = "__subosi4", .linkage = linkage });
+    @export(__subodi4, .{ .name = "__subodi4", .linkage = linkage });
+    @export(__suboti4, .{ .name = "__suboti4", .linkage = linkage });
+}
 
 // subo - subtract overflow
 // * return a-%b.
lib/compiler_rt/tan.zig
@@ -6,6 +6,7 @@
 // https://golang.org/src/math/tan.go
 
 const std = @import("std");
+const builtin = @import("builtin");
 const math = std.math;
 const expect = std.testing.expect;
 
@@ -13,6 +14,25 @@ const kernel = @import("trig.zig");
 const rem_pio2 = @import("rem_pio2.zig").rem_pio2;
 const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;
 
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__tanh, .{ .name = "__tanh", .linkage = linkage });
+    @export(tanf, .{ .name = "tanf", .linkage = linkage });
+    @export(tan, .{ .name = "tan", .linkage = linkage });
+    @export(__tanx, .{ .name = "__tanx", .linkage = linkage });
+    @export(tanq, .{ .name = "tanq", .linkage = linkage });
+    @export(tanl, .{ .name = "tanl", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(tanf128, .{ .name = "tanf128", .linkage = linkage });
+        }
+    }
+}
+
 pub fn __tanh(x: f16) callconv(.C) f16 {
     // TODO: more efficient implementation
     return @floatCast(f16, tanf(x));
@@ -96,6 +116,10 @@ pub fn tanq(x: f128) callconv(.C) f128 {
     return tan(@floatCast(f64, x));
 }
 
+pub fn tanf128(x: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, tanq, .{x});
+}
+
 pub fn tanl(x: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __tanh(x),
lib/compiler_rt/trunc.zig
@@ -5,8 +5,27 @@
 // https://git.musl-libc.org/cgit/musl/tree/src/math/trunc.c
 
 const std = @import("std");
+const builtin = @import("builtin");
 const math = std.math;
 const expect = std.testing.expect;
+const arch = builtin.cpu.arch;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__trunch, .{ .name = "__trunch", .linkage = linkage });
+    @export(truncf, .{ .name = "truncf", .linkage = linkage });
+    @export(trunc, .{ .name = "trunc", .linkage = linkage });
+    @export(__truncx, .{ .name = "__truncx", .linkage = linkage });
+    @export(truncq, .{ .name = "truncq", .linkage = linkage });
+    @export(truncl, .{ .name = "truncl", .linkage = linkage });
+
+    if (!builtin.is_test) {
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(truncf128, .{ .name = "truncf128", .linkage = linkage });
+        }
+    }
+}
 
 pub fn __trunch(x: f16) callconv(.C) f16 {
     // TODO: more efficient implementation
@@ -81,6 +100,10 @@ pub fn truncq(x: f128) callconv(.C) f128 {
     }
 }
 
+pub fn truncf128(x: f128) callconv(.C) f128 {
+    return @call(.{ .modifier = .always_inline }, truncq, .{x});
+}
+
 pub fn truncl(x: c_longdouble) callconv(.C) c_longdouble {
     switch (@typeInfo(c_longdouble).Float.bits) {
         16 => return __trunch(x),
lib/compiler_rt/trunc_f80.zig
@@ -1,11 +1,21 @@
 const std = @import("std");
 const builtin = @import("builtin");
-const native_arch = builtin.cpu.arch;
+const arch = builtin.cpu.arch;
 const testing = std.testing;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__truncxfhf2, .{ .name = "__truncxfhf2", .linkage = linkage });
+    @export(__truncxfsf2, .{ .name = "__truncxfsf2", .linkage = linkage });
+    @export(__truncxfdf2, .{ .name = "__truncxfdf2", .linkage = linkage });
+    @export(__trunctfxf2, .{ .name = "__trunctfxf2", .linkage = linkage });
+}
 
 // AArch64 is the only ABI (at the moment) to support f16 arguments without the
 // need for extending them to wider fp types.
-pub const F16T = if (native_arch.isAARCH64()) f16 else u16;
+const F16T = if (arch.isAARCH64()) f16 else u16;
 
 pub fn __truncxfhf2(a: f80) callconv(.C) F16T {
     return @bitCast(F16T, trunc(f16, a));
lib/compiler_rt/truncXfYf2.zig
@@ -1,17 +1,49 @@
 const std = @import("std");
 const builtin = @import("builtin");
-const native_arch = builtin.cpu.arch;
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    @export(__truncdfhf2, .{ .name = "__truncdfhf2", .linkage = linkage });
+    @export(__trunctfhf2, .{ .name = "__trunctfhf2", .linkage = linkage });
+    @export(__trunctfdf2, .{ .name = "__trunctfdf2", .linkage = linkage });
+    @export(__trunctfsf2, .{ .name = "__trunctfsf2", .linkage = linkage });
+
+    @export(__truncdfsf2, .{ .name = "__truncdfsf2", .linkage = linkage });
+    @export(__truncsfhf2, .{ .name = "__truncsfhf2", .linkage = linkage });
+
+    if (!is_test) {
+        @export(__gnu_f2h_ieee, .{ .name = "__gnu_f2h_ieee", .linkage = linkage });
+
+        if (arch.isARM() or arch.isThumb()) {
+            @export(__aeabi_d2h, .{ .name = "__aeabi_d2h", .linkage = linkage });
+            @export(__aeabi_f2h, .{ .name = "__aeabi_f2h", .linkage = linkage });
+            @export(__aeabi_d2f, .{ .name = "__aeabi_d2f", .linkage = linkage });
+        }
+
+        if (arch.isPPC() or arch.isPPC64()) {
+            @export(__trunckfsf2, .{ .name = "__trunckfsf2", .linkage = linkage });
+            @export(__trunckfdf2, .{ .name = "__trunckfdf2", .linkage = linkage });
+        }
+    }
+}
 
 // AArch64 is the only ABI (at the moment) to support f16 arguments without the
 // need for extending them to wider fp types.
 // TODO remove this; do this type selection in the language rather than
 // here in compiler-rt.
-pub const F16T = if (native_arch.isAARCH64()) f16 else u16;
+const F16T = if (arch.isAARCH64()) f16 else u16;
 
 pub fn __truncsfhf2(a: f32) callconv(.C) F16T {
     return @bitCast(F16T, truncXfYf2(f16, f32, a));
 }
 
+pub fn __gnu_f2h_ieee(a: f32) callconv(.C) F16T {
+    return @call(.{ .modifier = .always_inline }, __truncsfhf2, .{a});
+}
+
 pub fn __truncdfhf2(a: f64) callconv(.C) F16T {
     return @bitCast(F16T, truncXfYf2(f16, f64, a));
 }
@@ -24,10 +56,18 @@ pub fn __trunctfsf2(a: f128) callconv(.C) f32 {
     return truncXfYf2(f32, f128, a);
 }
 
+pub fn __trunckfsf2(a: f128) callconv(.C) f32 {
+    return truncXfYf2(f32, f128, a);
+}
+
 pub fn __trunctfdf2(a: f128) callconv(.C) f64 {
     return truncXfYf2(f64, f128, a);
 }
 
+pub fn __trunckfdf2(a: f128) callconv(.C) f64 {
+    return truncXfYf2(f64, f128, a);
+}
+
 pub fn __truncdfsf2(a: f64) callconv(.C) f32 {
     return truncXfYf2(f32, f64, a);
 }
lib/compiler_rt/udivmodti4.zig
@@ -1,13 +1,35 @@
-const udivmod = @import("udivmod.zig").udivmod;
+const std = @import("std");
 const builtin = @import("builtin");
-const compiler_rt = @import("../compiler_rt.zig");
+const udivmod = @import("udivmod.zig").udivmod;
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    if (builtin.os.tag == .windows) {
+        switch (arch) {
+            .i386 => {
+                @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = linkage });
+            },
+            .x86_64 => {
+                // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI
+                // that LLVM expects compiler-rt to have.
+                @export(__udivmodti4_windows_x86_64, .{ .name = "__udivmodti4", .linkage = linkage });
+            },
+            else => {},
+        }
+    } else {
+        @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = linkage });
+    }
+}
 
 pub fn __udivmodti4(a: u128, b: u128, maybe_rem: ?*u128) callconv(.C) u128 {
     @setRuntimeSafety(builtin.is_test);
     return udivmod(u128, a, b, maybe_rem);
 }
 
-const v128 = @import("std").meta.Vector(2, u64);
+const v128 = std.meta.Vector(2, u64);
 pub fn __udivmodti4_windows_x86_64(a: v128, b: v128, maybe_rem: ?*u128) callconv(.C) v128 {
     @setRuntimeSafety(builtin.is_test);
     return @bitCast(v128, udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), maybe_rem));
lib/compiler_rt/udivti3.zig
@@ -1,13 +1,39 @@
-const udivmodti4 = @import("udivmodti4.zig");
+const std = @import("std");
 const builtin = @import("builtin");
+const udivmod = @import("udivmod.zig").udivmod;
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    if (builtin.os.tag == .windows) {
+        switch (arch) {
+            .i386 => {
+                @export(__udivti3, .{ .name = "__udivti3", .linkage = linkage });
+            },
+            .x86_64 => {
+                // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI
+                // that LLVM expects compiler-rt to have.
+                @export(__udivti3_windows_x86_64, .{ .name = "__udivti3", .linkage = linkage });
+            },
+            else => {},
+        }
+        if (arch.isAARCH64()) {
+            @export(__udivti3, .{ .name = "__udivti3", .linkage = linkage });
+        }
+    } else {
+        @export(__udivti3, .{ .name = "__udivti3", .linkage = linkage });
+    }
+}
 
 pub fn __udivti3(a: u128, b: u128) callconv(.C) u128 {
     @setRuntimeSafety(builtin.is_test);
-    return udivmodti4.__udivmodti4(a, b, null);
+    return udivmod(u128, a, b, null);
 }
 
-const v128 = @import("std").meta.Vector(2, u64);
+const v128 = std.meta.Vector(2, u64);
 pub fn __udivti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 {
     @setRuntimeSafety(builtin.is_test);
-    return udivmodti4.__udivmodti4_windows_x86_64(a, b, null);
+    return @bitCast(v128, udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), null));
 }
lib/compiler_rt/umodti3.zig
@@ -1,15 +1,40 @@
-const udivmodti4 = @import("udivmodti4.zig");
+const std = @import("std");
 const builtin = @import("builtin");
-const compiler_rt = @import("../compiler_rt.zig");
+const udivmod = @import("udivmod.zig").udivmod;
+const arch = builtin.cpu.arch;
+const is_test = builtin.is_test;
+const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
+pub const panic = @import("common.zig").panic;
+
+comptime {
+    if (builtin.os.tag == .windows) {
+        switch (arch) {
+            .i386 => {
+                @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
+            },
+            .x86_64 => {
+                // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI
+                // that LLVM expects compiler-rt to have.
+                @export(__umodti3_windows_x86_64, .{ .name = "__umodti3", .linkage = linkage });
+            },
+            else => {},
+        }
+        if (arch.isAARCH64()) {
+            @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
+        }
+    } else {
+        @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
+    }
+}
 
 pub fn __umodti3(a: u128, b: u128) callconv(.C) u128 {
     @setRuntimeSafety(builtin.is_test);
     var r: u128 = undefined;
-    _ = udivmodti4.__udivmodti4(a, b, &r);
+    _ = udivmod(u128, a, b, &r);
     return r;
 }
 
-const v128 = @import("std").meta.Vector(2, u64);
+const v128 = std.meta.Vector(2, u64);
 pub fn __umodti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 {
     return @bitCast(v128, @call(.{ .modifier = .always_inline }, __umodti3, .{
         @bitCast(u128, a),
lib/compiler_rt.zig
@@ -1,542 +1,69 @@
-const std = @import("std");
 const builtin = @import("builtin");
-const is_test = builtin.is_test;
-const os_tag = builtin.os.tag;
-const arch = builtin.cpu.arch;
-const abi = builtin.abi;
-
-const is_gnu = abi.isGnu();
-const is_mingw = os_tag == .windows and is_gnu;
-const is_darwin = std.Target.Os.Tag.isDarwin(os_tag);
-const is_ppc = arch.isPPC() or arch.isPPC64();
-
-const linkage = if (is_test)
-    std.builtin.GlobalLinkage.Internal
-else
-    std.builtin.GlobalLinkage.Weak;
-
-const strong_linkage = if (is_test)
-    std.builtin.GlobalLinkage.Internal
-else
-    std.builtin.GlobalLinkage.Strong;
+pub const panic = @import("compiler_rt/common.zig").panic;
 
 comptime {
     // These files do their own comptime exporting logic.
     _ = @import("compiler_rt/atomics.zig");
-    if (builtin.zig_backend != .stage2_llvm) { // TODO
-        _ = @import("compiler_rt/clear_cache.zig").clear_cache;
-    }
-
-    const __extenddftf2 = @import("compiler_rt/extendXfYf2.zig").__extenddftf2;
-    @export(__extenddftf2, .{ .name = "__extenddftf2", .linkage = linkage });
-    const __extendsftf2 = @import("compiler_rt/extendXfYf2.zig").__extendsftf2;
-    @export(__extendsftf2, .{ .name = "__extendsftf2", .linkage = linkage });
-    const __extendhfsf2 = @import("compiler_rt/extendXfYf2.zig").__extendhfsf2;
-    @export(__extendhfsf2, .{ .name = "__extendhfsf2", .linkage = linkage });
-    const __extendhftf2 = @import("compiler_rt/extendXfYf2.zig").__extendhftf2;
-    @export(__extendhftf2, .{ .name = "__extendhftf2", .linkage = linkage });
-
-    const __extendhfxf2 = @import("compiler_rt/extend_f80.zig").__extendhfxf2;
-    @export(__extendhfxf2, .{ .name = "__extendhfxf2", .linkage = linkage });
-    const __extendsfxf2 = @import("compiler_rt/extend_f80.zig").__extendsfxf2;
-    @export(__extendsfxf2, .{ .name = "__extendsfxf2", .linkage = linkage });
-    const __extenddfxf2 = @import("compiler_rt/extend_f80.zig").__extenddfxf2;
-    @export(__extenddfxf2, .{ .name = "__extenddfxf2", .linkage = linkage });
-    const __extendxftf2 = @import("compiler_rt/extend_f80.zig").__extendxftf2;
-    @export(__extendxftf2, .{ .name = "__extendxftf2", .linkage = linkage });
-
-    const __lesf2 = @import("compiler_rt/compareXf2.zig").__lesf2;
-    @export(__lesf2, .{ .name = "__lesf2", .linkage = linkage });
-    const __ledf2 = @import("compiler_rt/compareXf2.zig").__ledf2;
-    @export(__ledf2, .{ .name = "__ledf2", .linkage = linkage });
-    const __letf2 = @import("compiler_rt/compareXf2.zig").__letf2;
-    @export(__letf2, .{ .name = "__letf2", .linkage = linkage });
-    const __lexf2 = @import("compiler_rt/compareXf2.zig").__lexf2;
-    @export(__lexf2, .{ .name = "__lexf2", .linkage = linkage });
-
-    const __gesf2 = @import("compiler_rt/compareXf2.zig").__gesf2;
-    @export(__gesf2, .{ .name = "__gesf2", .linkage = linkage });
-    const __gedf2 = @import("compiler_rt/compareXf2.zig").__gedf2;
-    @export(__gedf2, .{ .name = "__gedf2", .linkage = linkage });
-    const __getf2 = @import("compiler_rt/compareXf2.zig").__getf2;
-    @export(__getf2, .{ .name = "__getf2", .linkage = linkage });
-    const __gexf2 = @import("compiler_rt/compareXf2.zig").__gexf2;
-    @export(__gexf2, .{ .name = "__gexf2", .linkage = linkage });
-
-    const __eqsf2 = @import("compiler_rt/compareXf2.zig").__eqsf2;
-    @export(__eqsf2, .{ .name = "__eqsf2", .linkage = linkage });
-    const __eqdf2 = @import("compiler_rt/compareXf2.zig").__eqdf2;
-    @export(__eqdf2, .{ .name = "__eqdf2", .linkage = linkage });
-    const __eqxf2 = @import("compiler_rt/compareXf2.zig").__eqxf2;
-    @export(__eqxf2, .{ .name = "__eqxf2", .linkage = linkage });
-
-    const __ltsf2 = @import("compiler_rt/compareXf2.zig").__ltsf2;
-    @export(__ltsf2, .{ .name = "__ltsf2", .linkage = linkage });
-    const __ltdf2 = @import("compiler_rt/compareXf2.zig").__ltdf2;
-    @export(__ltdf2, .{ .name = "__ltdf2", .linkage = linkage });
-    const __ltxf2 = @import("compiler_rt/compareXf2.zig").__ltxf2;
-    @export(__ltxf2, .{ .name = "__ltxf2", .linkage = linkage });
-
-    const __nesf2 = @import("compiler_rt/compareXf2.zig").__nesf2;
-    @export(__nesf2, .{ .name = "__nesf2", .linkage = linkage });
-    const __nedf2 = @import("compiler_rt/compareXf2.zig").__nedf2;
-    @export(__nedf2, .{ .name = "__nedf2", .linkage = linkage });
-    const __nexf2 = @import("compiler_rt/compareXf2.zig").__nexf2;
-    @export(__nexf2, .{ .name = "__nexf2", .linkage = linkage });
-
-    const __gtsf2 = @import("compiler_rt/compareXf2.zig").__gtsf2;
-    @export(__gtsf2, .{ .name = "__gtsf2", .linkage = linkage });
-    const __gtdf2 = @import("compiler_rt/compareXf2.zig").__gtdf2;
-    @export(__gtdf2, .{ .name = "__gtdf2", .linkage = linkage });
-    const __gtxf2 = @import("compiler_rt/compareXf2.zig").__gtxf2;
-    @export(__gtxf2, .{ .name = "__gtxf2", .linkage = linkage });
-
-    if (!is_test) {
-        @export(__lesf2, .{ .name = "__cmpsf2", .linkage = linkage });
-        @export(__ledf2, .{ .name = "__cmpdf2", .linkage = linkage });
-        @export(__letf2, .{ .name = "__cmptf2", .linkage = linkage });
-        @export(__letf2, .{ .name = "__eqtf2", .linkage = linkage });
-        @export(__letf2, .{ .name = "__lttf2", .linkage = linkage });
-        @export(__getf2, .{ .name = "__gttf2", .linkage = linkage });
-        @export(__letf2, .{ .name = "__netf2", .linkage = linkage });
-        @export(__extendhfsf2, .{ .name = "__gnu_h2f_ieee", .linkage = linkage });
-    }
-
-    if (builtin.os.tag == .windows) {
-        // Default stack-probe functions emitted by LLVM
-        if (is_mingw) {
-            const _chkstk = @import("compiler_rt/stack_probe.zig")._chkstk;
-            @export(_chkstk, .{ .name = "_alloca", .linkage = strong_linkage });
-            const ___chkstk_ms = @import("compiler_rt/stack_probe.zig").___chkstk_ms;
-            @export(___chkstk_ms, .{ .name = "___chkstk_ms", .linkage = strong_linkage });
-        } else if (!builtin.link_libc) {
-            // This symbols are otherwise exported by MSVCRT.lib
-            const _chkstk = @import("compiler_rt/stack_probe.zig")._chkstk;
-            @export(_chkstk, .{ .name = "_chkstk", .linkage = strong_linkage });
-            const __chkstk = @import("compiler_rt/stack_probe.zig").__chkstk;
-            @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
-        }
-
-        switch (arch) {
-            .i386 => {
-                const __divti3 = @import("compiler_rt/divti3.zig").__divti3;
-                @export(__divti3, .{ .name = "__divti3", .linkage = linkage });
-                const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
-                @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
-                const __multi3 = @import("compiler_rt/multi3.zig").__multi3;
-                @export(__multi3, .{ .name = "__multi3", .linkage = linkage });
-                const __udivti3 = @import("compiler_rt/udivti3.zig").__udivti3;
-                @export(__udivti3, .{ .name = "__udivti3", .linkage = linkage });
-                const __udivmodti4 = @import("compiler_rt/udivmodti4.zig").__udivmodti4;
-                @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = linkage });
-                const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
-                @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
-            },
-            .x86_64 => {
-                // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI
-                // that LLVM expects compiler-rt to have.
-                const __divti3_windows_x86_64 = @import("compiler_rt/divti3.zig").__divti3_windows_x86_64;
-                @export(__divti3_windows_x86_64, .{ .name = "__divti3", .linkage = linkage });
-                const __modti3_windows_x86_64 = @import("compiler_rt/modti3.zig").__modti3_windows_x86_64;
-                @export(__modti3_windows_x86_64, .{ .name = "__modti3", .linkage = linkage });
-                const __multi3_windows_x86_64 = @import("compiler_rt/multi3.zig").__multi3_windows_x86_64;
-                @export(__multi3_windows_x86_64, .{ .name = "__multi3", .linkage = linkage });
-                const __udivti3_windows_x86_64 = @import("compiler_rt/udivti3.zig").__udivti3_windows_x86_64;
-                @export(__udivti3_windows_x86_64, .{ .name = "__udivti3", .linkage = linkage });
-                const __udivmodti4_windows_x86_64 = @import("compiler_rt/udivmodti4.zig").__udivmodti4_windows_x86_64;
-                @export(__udivmodti4_windows_x86_64, .{ .name = "__udivmodti4", .linkage = linkage });
-                const __umodti3_windows_x86_64 = @import("compiler_rt/umodti3.zig").__umodti3_windows_x86_64;
-                @export(__umodti3_windows_x86_64, .{ .name = "__umodti3", .linkage = linkage });
-            },
-            else => {},
-        }
-        if (arch.isAARCH64()) {
-            const __chkstk = @import("compiler_rt/stack_probe.zig").__chkstk;
-            @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
-            const __divti3_windows = @import("compiler_rt/divti3.zig").__divti3;
-            @export(__divti3_windows, .{ .name = "__divti3", .linkage = linkage });
-            const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
-            @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
-            const __udivti3_windows = @import("compiler_rt/udivti3.zig").__udivti3;
-            @export(__udivti3_windows, .{ .name = "__udivti3", .linkage = linkage });
-            const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
-            @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
-        }
-    } else {
-        const __divti3 = @import("compiler_rt/divti3.zig").__divti3;
-        @export(__divti3, .{ .name = "__divti3", .linkage = linkage });
-        const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
-        @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
-        const __multi3 = @import("compiler_rt/multi3.zig").__multi3;
-        @export(__multi3, .{ .name = "__multi3", .linkage = linkage });
-        const __udivti3 = @import("compiler_rt/udivti3.zig").__udivti3;
-        @export(__udivti3, .{ .name = "__udivti3", .linkage = linkage });
-        const __udivmodti4 = @import("compiler_rt/udivmodti4.zig").__udivmodti4;
-        @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = linkage });
-        const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
-        @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
-    }
-
-    const __truncdfhf2 = @import("compiler_rt/truncXfYf2.zig").__truncdfhf2;
-    @export(__truncdfhf2, .{ .name = "__truncdfhf2", .linkage = linkage });
-    const __trunctfhf2 = @import("compiler_rt/truncXfYf2.zig").__trunctfhf2;
-    @export(__trunctfhf2, .{ .name = "__trunctfhf2", .linkage = linkage });
-    const __trunctfdf2 = @import("compiler_rt/truncXfYf2.zig").__trunctfdf2;
-    @export(__trunctfdf2, .{ .name = "__trunctfdf2", .linkage = linkage });
-    const __trunctfsf2 = @import("compiler_rt/truncXfYf2.zig").__trunctfsf2;
-    @export(__trunctfsf2, .{ .name = "__trunctfsf2", .linkage = linkage });
-
-    const __truncdfsf2 = @import("compiler_rt/truncXfYf2.zig").__truncdfsf2;
-    @export(__truncdfsf2, .{ .name = "__truncdfsf2", .linkage = linkage });
-
-    const __truncxfhf2 = @import("compiler_rt/trunc_f80.zig").__truncxfhf2;
-    @export(__truncxfhf2, .{ .name = "__truncxfhf2", .linkage = linkage });
-    const __truncxfsf2 = @import("compiler_rt/trunc_f80.zig").__truncxfsf2;
-    @export(__truncxfsf2, .{ .name = "__truncxfsf2", .linkage = linkage });
-    const __truncxfdf2 = @import("compiler_rt/trunc_f80.zig").__truncxfdf2;
-    @export(__truncxfdf2, .{ .name = "__truncxfdf2", .linkage = linkage });
-    const __trunctfxf2 = @import("compiler_rt/trunc_f80.zig").__trunctfxf2;
-    @export(__trunctfxf2, .{ .name = "__trunctfxf2", .linkage = linkage });
-
-    switch (arch) {
-        .i386,
-        .x86_64,
-        => {
-            const zig_probe_stack = @import("compiler_rt/stack_probe.zig").zig_probe_stack;
-            @export(zig_probe_stack, .{
-                .name = "__zig_probe_stack",
-                .linkage = linkage,
-            });
-        },
-        else => {},
-    }
-
-    const __unordsf2 = @import("compiler_rt/compareXf2.zig").__unordsf2;
-    @export(__unordsf2, .{ .name = "__unordsf2", .linkage = linkage });
-    const __unorddf2 = @import("compiler_rt/compareXf2.zig").__unorddf2;
-    @export(__unorddf2, .{ .name = "__unorddf2", .linkage = linkage });
-    const __unordtf2 = @import("compiler_rt/compareXf2.zig").__unordtf2;
-    @export(__unordtf2, .{ .name = "__unordtf2", .linkage = linkage });
-
-    const __addsf3 = @import("compiler_rt/addXf3.zig").__addsf3;
-    @export(__addsf3, .{ .name = "__addsf3", .linkage = linkage });
-    const __adddf3 = @import("compiler_rt/addXf3.zig").__adddf3;
-    @export(__adddf3, .{ .name = "__adddf3", .linkage = linkage });
-    const __addxf3 = @import("compiler_rt/addXf3.zig").__addxf3;
-    @export(__addxf3, .{ .name = "__addxf3", .linkage = linkage });
-    const __addtf3 = @import("compiler_rt/addXf3.zig").__addtf3;
-    @export(__addtf3, .{ .name = "__addtf3", .linkage = linkage });
-
-    const __subsf3 = @import("compiler_rt/addXf3.zig").__subsf3;
-    @export(__subsf3, .{ .name = "__subsf3", .linkage = linkage });
-    const __subdf3 = @import("compiler_rt/addXf3.zig").__subdf3;
-    @export(__subdf3, .{ .name = "__subdf3", .linkage = linkage });
-    const __subxf3 = @import("compiler_rt/addXf3.zig").__subxf3;
-    @export(__subxf3, .{ .name = "__subxf3", .linkage = linkage });
-    const __subtf3 = @import("compiler_rt/addXf3.zig").__subtf3;
-    @export(__subtf3, .{ .name = "__subtf3", .linkage = linkage });
-
-    const __mulsf3 = @import("compiler_rt/mulXf3.zig").__mulsf3;
-    @export(__mulsf3, .{ .name = "__mulsf3", .linkage = linkage });
-    const __muldf3 = @import("compiler_rt/mulXf3.zig").__muldf3;
-    @export(__muldf3, .{ .name = "__muldf3", .linkage = linkage });
-    const __mulxf3 = @import("compiler_rt/mulXf3.zig").__mulxf3;
-    @export(__mulxf3, .{ .name = "__mulxf3", .linkage = linkage });
-    const __multf3 = @import("compiler_rt/mulXf3.zig").__multf3;
-    @export(__multf3, .{ .name = "__multf3", .linkage = linkage });
-
-    const __divsf3 = @import("compiler_rt/divsf3.zig").__divsf3;
-    @export(__divsf3, .{ .name = "__divsf3", .linkage = linkage });
-    const __divdf3 = @import("compiler_rt/divdf3.zig").__divdf3;
-    @export(__divdf3, .{ .name = "__divdf3", .linkage = linkage });
-    const __divxf3 = @import("compiler_rt/divxf3.zig").__divxf3;
-    @export(__divxf3, .{ .name = "__divxf3", .linkage = linkage });
-    const __divtf3 = @import("compiler_rt/divtf3.zig").__divtf3;
-    @export(__divtf3, .{ .name = "__divtf3", .linkage = linkage });
-
-    // Integer Bit operations
-    const __clzsi2 = @import("compiler_rt/count0bits.zig").__clzsi2;
-    @export(__clzsi2, .{ .name = "__clzsi2", .linkage = linkage });
-    const __clzdi2 = @import("compiler_rt/count0bits.zig").__clzdi2;
-    @export(__clzdi2, .{ .name = "__clzdi2", .linkage = linkage });
-    const __clzti2 = @import("compiler_rt/count0bits.zig").__clzti2;
-    @export(__clzti2, .{ .name = "__clzti2", .linkage = linkage });
-    const __ctzsi2 = @import("compiler_rt/count0bits.zig").__ctzsi2;
-    @export(__ctzsi2, .{ .name = "__ctzsi2", .linkage = linkage });
-    const __ctzdi2 = @import("compiler_rt/count0bits.zig").__ctzdi2;
-    @export(__ctzdi2, .{ .name = "__ctzdi2", .linkage = linkage });
-    const __ctzti2 = @import("compiler_rt/count0bits.zig").__ctzti2;
-    @export(__ctzti2, .{ .name = "__ctzti2", .linkage = linkage });
-    const __ffssi2 = @import("compiler_rt/count0bits.zig").__ffssi2;
-    @export(__ffssi2, .{ .name = "__ffssi2", .linkage = linkage });
-    const __ffsdi2 = @import("compiler_rt/count0bits.zig").__ffsdi2;
-    @export(__ffsdi2, .{ .name = "__ffsdi2", .linkage = linkage });
-    const __ffsti2 = @import("compiler_rt/count0bits.zig").__ffsti2;
-    @export(__ffsti2, .{ .name = "__ffsti2", .linkage = linkage });
-    const __paritysi2 = @import("compiler_rt/parity.zig").__paritysi2;
-    @export(__paritysi2, .{ .name = "__paritysi2", .linkage = linkage });
-    const __paritydi2 = @import("compiler_rt/parity.zig").__paritydi2;
-    @export(__paritydi2, .{ .name = "__paritydi2", .linkage = linkage });
-    const __parityti2 = @import("compiler_rt/parity.zig").__parityti2;
-    @export(__parityti2, .{ .name = "__parityti2", .linkage = linkage });
-    const __popcountsi2 = @import("compiler_rt/popcount.zig").__popcountsi2;
-    @export(__popcountsi2, .{ .name = "__popcountsi2", .linkage = linkage });
-    const __popcountdi2 = @import("compiler_rt/popcount.zig").__popcountdi2;
-    @export(__popcountdi2, .{ .name = "__popcountdi2", .linkage = linkage });
-    const __popcountti2 = @import("compiler_rt/popcount.zig").__popcountti2;
-    @export(__popcountti2, .{ .name = "__popcountti2", .linkage = linkage });
-    const __bswapsi2 = @import("compiler_rt/bswap.zig").__bswapsi2;
-    @export(__bswapsi2, .{ .name = "__bswapsi2", .linkage = linkage });
-    const __bswapdi2 = @import("compiler_rt/bswap.zig").__bswapdi2;
-    @export(__bswapdi2, .{ .name = "__bswapdi2", .linkage = linkage });
-    const __bswapti2 = @import("compiler_rt/bswap.zig").__bswapti2;
-    @export(__bswapti2, .{ .name = "__bswapti2", .linkage = linkage });
-
-    // Integral -> Float Conversion
-
-    // Conversion to f32
-    const __floatsisf = @import("compiler_rt/floatXiYf.zig").__floatsisf;
-    @export(__floatsisf, .{ .name = "__floatsisf", .linkage = linkage });
-    const __floatunsisf = @import("compiler_rt/floatXiYf.zig").__floatunsisf;
-    @export(__floatunsisf, .{ .name = "__floatunsisf", .linkage = linkage });
-
-    const __floatundisf = @import("compiler_rt/floatXiYf.zig").__floatundisf;
-    @export(__floatundisf, .{ .name = "__floatundisf", .linkage = linkage });
-    const __floatdisf = @import("compiler_rt/floatXiYf.zig").__floatdisf;
-    @export(__floatdisf, .{ .name = "__floatdisf", .linkage = linkage });
-
-    const __floattisf = @import("compiler_rt/floatXiYf.zig").__floattisf;
-    @export(__floattisf, .{ .name = "__floattisf", .linkage = linkage });
-    const __floatuntisf = @import("compiler_rt/floatXiYf.zig").__floatuntisf;
-    @export(__floatuntisf, .{ .name = "__floatuntisf", .linkage = linkage });
-
-    // Conversion to f64
-    const __floatsidf = @import("compiler_rt/floatXiYf.zig").__floatsidf;
-    @export(__floatsidf, .{ .name = "__floatsidf", .linkage = linkage });
-    const __floatunsidf = @import("compiler_rt/floatXiYf.zig").__floatunsidf;
-    @export(__floatunsidf, .{ .name = "__floatunsidf", .linkage = linkage });
-
-    const __floatdidf = @import("compiler_rt/floatXiYf.zig").__floatdidf;
-    @export(__floatdidf, .{ .name = "__floatdidf", .linkage = linkage });
-    const __floatundidf = @import("compiler_rt/floatXiYf.zig").__floatundidf;
-    @export(__floatundidf, .{ .name = "__floatundidf", .linkage = linkage });
-
-    const __floattidf = @import("compiler_rt/floatXiYf.zig").__floattidf;
-    @export(__floattidf, .{ .name = "__floattidf", .linkage = linkage });
-    const __floatuntidf = @import("compiler_rt/floatXiYf.zig").__floatuntidf;
-    @export(__floatuntidf, .{ .name = "__floatuntidf", .linkage = linkage });
-
-    // Conversion to f80
-    const __floatsixf = @import("compiler_rt/floatXiYf.zig").__floatsixf;
-    @export(__floatsixf, .{ .name = "__floatsixf", .linkage = linkage });
-    const __floatunsixf = @import("compiler_rt/floatXiYf.zig").__floatunsixf;
-    @export(__floatunsixf, .{ .name = "__floatunsixf", .linkage = linkage });
-
-    const __floatdixf = @import("compiler_rt/floatXiYf.zig").__floatdixf;
-    @export(__floatdixf, .{ .name = "__floatdixf", .linkage = linkage });
-    const __floatundixf = @import("compiler_rt/floatXiYf.zig").__floatundixf;
-    @export(__floatundixf, .{ .name = "__floatundixf", .linkage = linkage });
-
-    const __floattixf = @import("compiler_rt/floatXiYf.zig").__floattixf;
-    @export(__floattixf, .{ .name = "__floattixf", .linkage = linkage });
-    const __floatuntixf = @import("compiler_rt/floatXiYf.zig").__floatuntixf;
-    @export(__floatuntixf, .{ .name = "__floatuntixf", .linkage = linkage });
-
-    // Conversion to f128
-    const __floatsitf = @import("compiler_rt/floatXiYf.zig").__floatsitf;
-    @export(__floatsitf, .{ .name = "__floatsitf", .linkage = linkage });
-    const __floatunsitf = @import("compiler_rt/floatXiYf.zig").__floatunsitf;
-    @export(__floatunsitf, .{ .name = "__floatunsitf", .linkage = linkage });
-
-    const __floatditf = @import("compiler_rt/floatXiYf.zig").__floatditf;
-    @export(__floatditf, .{ .name = "__floatditf", .linkage = linkage });
-    const __floatunditf = @import("compiler_rt/floatXiYf.zig").__floatunditf;
-    @export(__floatunditf, .{ .name = "__floatunditf", .linkage = linkage });
-
-    const __floattitf = @import("compiler_rt/floatXiYf.zig").__floattitf;
-    @export(__floattitf, .{ .name = "__floattitf", .linkage = linkage });
-    const __floatuntitf = @import("compiler_rt/floatXiYf.zig").__floatuntitf;
-    @export(__floatuntitf, .{ .name = "__floatuntitf", .linkage = linkage });
-
-    // Float -> Integral Conversion
-
-    // Conversion from f32
-    const __fixsfsi = @import("compiler_rt/fixXfYi.zig").__fixsfsi;
-    @export(__fixsfsi, .{ .name = "__fixsfsi", .linkage = linkage });
-    const __fixunssfsi = @import("compiler_rt/fixXfYi.zig").__fixunssfsi;
-    @export(__fixunssfsi, .{ .name = "__fixunssfsi", .linkage = linkage });
-
-    const __fixsfdi = @import("compiler_rt/fixXfYi.zig").__fixsfdi;
-    @export(__fixsfdi, .{ .name = "__fixsfdi", .linkage = linkage });
-    const __fixunssfdi = @import("compiler_rt/fixXfYi.zig").__fixunssfdi;
-    @export(__fixunssfdi, .{ .name = "__fixunssfdi", .linkage = linkage });
-
-    const __fixsfti = @import("compiler_rt/fixXfYi.zig").__fixsfti;
-    @export(__fixsfti, .{ .name = "__fixsfti", .linkage = linkage });
-    const __fixunssfti = @import("compiler_rt/fixXfYi.zig").__fixunssfti;
-    @export(__fixunssfti, .{ .name = "__fixunssfti", .linkage = linkage });
-
-    // Conversion from f64
-    const __fixdfsi = @import("compiler_rt/fixXfYi.zig").__fixdfsi;
-    @export(__fixdfsi, .{ .name = "__fixdfsi", .linkage = linkage });
-    const __fixunsdfsi = @import("compiler_rt/fixXfYi.zig").__fixunsdfsi;
-    @export(__fixunsdfsi, .{ .name = "__fixunsdfsi", .linkage = linkage });
-
-    const __fixdfdi = @import("compiler_rt/fixXfYi.zig").__fixdfdi;
-    @export(__fixdfdi, .{ .name = "__fixdfdi", .linkage = linkage });
-    const __fixunsdfdi = @import("compiler_rt/fixXfYi.zig").__fixunsdfdi;
-    @export(__fixunsdfdi, .{ .name = "__fixunsdfdi", .linkage = linkage });
-
-    const __fixdfti = @import("compiler_rt/fixXfYi.zig").__fixdfti;
-    @export(__fixdfti, .{ .name = "__fixdfti", .linkage = linkage });
-    const __fixunsdfti = @import("compiler_rt/fixXfYi.zig").__fixunsdfti;
-    @export(__fixunsdfti, .{ .name = "__fixunsdfti", .linkage = linkage });
-
-    // Conversion from f80
-    const __fixxfsi = @import("compiler_rt/fixXfYi.zig").__fixxfsi;
-    @export(__fixxfsi, .{ .name = "__fixxfsi", .linkage = linkage });
-    const __fixunsxfsi = @import("compiler_rt/fixXfYi.zig").__fixunsxfsi;
-    @export(__fixunsxfsi, .{ .name = "__fixunsxfsi", .linkage = linkage });
-
-    const __fixxfdi = @import("compiler_rt/fixXfYi.zig").__fixxfdi;
-    @export(__fixxfdi, .{ .name = "__fixxfdi", .linkage = linkage });
-    const __fixunsxfdi = @import("compiler_rt/fixXfYi.zig").__fixunsxfdi;
-    @export(__fixunsxfdi, .{ .name = "__fixunsxfdi", .linkage = linkage });
-
-    const __fixxfti = @import("compiler_rt/fixXfYi.zig").__fixxfti;
-    @export(__fixxfti, .{ .name = "__fixxfti", .linkage = linkage });
-    const __fixunsxfti = @import("compiler_rt/fixXfYi.zig").__fixunsxfti;
-    @export(__fixunsxfti, .{ .name = "__fixunsxfti", .linkage = linkage });
-
-    // Conversion from f128
-    const __fixtfsi = @import("compiler_rt/fixXfYi.zig").__fixtfsi;
-    @export(__fixtfsi, .{ .name = "__fixtfsi", .linkage = linkage });
-    const __fixunstfsi = @import("compiler_rt/fixXfYi.zig").__fixunstfsi;
-    @export(__fixunstfsi, .{ .name = "__fixunstfsi", .linkage = linkage });
-
-    const __fixtfdi = @import("compiler_rt/fixXfYi.zig").__fixtfdi;
-    @export(__fixtfdi, .{ .name = "__fixtfdi", .linkage = linkage });
-    const __fixunstfdi = @import("compiler_rt/fixXfYi.zig").__fixunstfdi;
-    @export(__fixunstfdi, .{ .name = "__fixunstfdi", .linkage = linkage });
-
-    const __fixtfti = @import("compiler_rt/fixXfYi.zig").__fixtfti;
-    @export(__fixtfti, .{ .name = "__fixtfti", .linkage = linkage });
-    const __fixunstfti = @import("compiler_rt/fixXfYi.zig").__fixunstfti;
-    @export(__fixunstfti, .{ .name = "__fixunstfti", .linkage = linkage });
-
-    const __udivmoddi4 = @import("compiler_rt/int.zig").__udivmoddi4;
-    @export(__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = linkage });
-
-    const __truncsfhf2 = @import("compiler_rt/truncXfYf2.zig").__truncsfhf2;
-    @export(__truncsfhf2, .{ .name = "__truncsfhf2", .linkage = linkage });
-    if (!is_test) {
-        @export(__truncsfhf2, .{ .name = "__gnu_f2h_ieee", .linkage = linkage });
-    }
-    const __extendsfdf2 = @import("compiler_rt/extendXfYf2.zig").__extendsfdf2;
-    @export(__extendsfdf2, .{ .name = "__extendsfdf2", .linkage = linkage });
-
-    if (is_darwin) {
-        const __isPlatformVersionAtLeast = @import("compiler_rt/os_version_check.zig").__isPlatformVersionAtLeast;
-        @export(__isPlatformVersionAtLeast, .{ .name = "__isPlatformVersionAtLeast", .linkage = linkage });
-    }
-
-    // Integer Arithmetic
-    const __ashldi3 = @import("compiler_rt/shift.zig").__ashldi3;
-    @export(__ashldi3, .{ .name = "__ashldi3", .linkage = linkage });
-    const __ashlti3 = @import("compiler_rt/shift.zig").__ashlti3;
-    @export(__ashlti3, .{ .name = "__ashlti3", .linkage = linkage });
-    const __ashrdi3 = @import("compiler_rt/shift.zig").__ashrdi3;
-    @export(__ashrdi3, .{ .name = "__ashrdi3", .linkage = linkage });
-    const __ashrti3 = @import("compiler_rt/shift.zig").__ashrti3;
-    @export(__ashrti3, .{ .name = "__ashrti3", .linkage = linkage });
-    const __lshrdi3 = @import("compiler_rt/shift.zig").__lshrdi3;
-    @export(__lshrdi3, .{ .name = "__lshrdi3", .linkage = linkage });
-    const __lshrti3 = @import("compiler_rt/shift.zig").__lshrti3;
-    @export(__lshrti3, .{ .name = "__lshrti3", .linkage = linkage });
-    const __negsi2 = @import("compiler_rt/negXi2.zig").__negsi2;
-    @export(__negsi2, .{ .name = "__negsi2", .linkage = linkage });
-    const __negdi2 = @import("compiler_rt/negXi2.zig").__negdi2;
-    @export(__negdi2, .{ .name = "__negdi2", .linkage = linkage });
-    const __negti2 = @import("compiler_rt/negXi2.zig").__negti2;
-    @export(__negti2, .{ .name = "__negti2", .linkage = linkage });
-
-    const __mulsi3 = @import("compiler_rt/int.zig").__mulsi3;
-    @export(__mulsi3, .{ .name = "__mulsi3", .linkage = linkage });
-    const __muldi3 = @import("compiler_rt/muldi3.zig").__muldi3;
-    @export(__muldi3, .{ .name = "__muldi3", .linkage = linkage });
-    const __divmoddi4 = @import("compiler_rt/int.zig").__divmoddi4;
-    @export(__divmoddi4, .{ .name = "__divmoddi4", .linkage = linkage });
-    const __divsi3 = @import("compiler_rt/int.zig").__divsi3;
-    @export(__divsi3, .{ .name = "__divsi3", .linkage = linkage });
-    const __divdi3 = @import("compiler_rt/int.zig").__divdi3;
-    @export(__divdi3, .{ .name = "__divdi3", .linkage = linkage });
-    const __udivsi3 = @import("compiler_rt/int.zig").__udivsi3;
-    @export(__udivsi3, .{ .name = "__udivsi3", .linkage = linkage });
-    const __udivdi3 = @import("compiler_rt/int.zig").__udivdi3;
-    @export(__udivdi3, .{ .name = "__udivdi3", .linkage = linkage });
-    const __modsi3 = @import("compiler_rt/int.zig").__modsi3;
-    @export(__modsi3, .{ .name = "__modsi3", .linkage = linkage });
-    const __moddi3 = @import("compiler_rt/int.zig").__moddi3;
-    @export(__moddi3, .{ .name = "__moddi3", .linkage = linkage });
-    const __umodsi3 = @import("compiler_rt/int.zig").__umodsi3;
-    @export(__umodsi3, .{ .name = "__umodsi3", .linkage = linkage });
-    const __umoddi3 = @import("compiler_rt/int.zig").__umoddi3;
-    @export(__umoddi3, .{ .name = "__umoddi3", .linkage = linkage });
-    const __divmodsi4 = @import("compiler_rt/int.zig").__divmodsi4;
-    @export(__divmodsi4, .{ .name = "__divmodsi4", .linkage = linkage });
-    const __udivmodsi4 = @import("compiler_rt/int.zig").__udivmodsi4;
-    @export(__udivmodsi4, .{ .name = "__udivmodsi4", .linkage = linkage });
-
-    // Integer Arithmetic with trapping overflow
-    const __absvsi2 = @import("compiler_rt/absv.zig").__absvsi2;
-    @export(__absvsi2, .{ .name = "__absvsi2", .linkage = linkage });
-    const __absvdi2 = @import("compiler_rt/absv.zig").__absvdi2;
-    @export(__absvdi2, .{ .name = "__absvdi2", .linkage = linkage });
-    const __absvti2 = @import("compiler_rt/absv.zig").__absvti2;
-    @export(__absvti2, .{ .name = "__absvti2", .linkage = linkage });
-    const __negvsi2 = @import("compiler_rt/negv.zig").__negvsi2;
-    @export(__negvsi2, .{ .name = "__negvsi2", .linkage = linkage });
-    const __negvdi2 = @import("compiler_rt/negv.zig").__negvdi2;
-    @export(__negvdi2, .{ .name = "__negvdi2", .linkage = linkage });
-    const __negvti2 = @import("compiler_rt/negv.zig").__negvti2;
-    @export(__negvti2, .{ .name = "__negvti2", .linkage = linkage });
-
-    // Integer arithmetic which returns if overflow
-    const __addosi4 = @import("compiler_rt/addo.zig").__addosi4;
-    @export(__addosi4, .{ .name = "__addosi4", .linkage = linkage });
-    const __addodi4 = @import("compiler_rt/addo.zig").__addodi4;
-    @export(__addodi4, .{ .name = "__addodi4", .linkage = linkage });
-    const __addoti4 = @import("compiler_rt/addo.zig").__addoti4;
-    @export(__addoti4, .{ .name = "__addoti4", .linkage = linkage });
-    const __subosi4 = @import("compiler_rt/subo.zig").__subosi4;
-    @export(__subosi4, .{ .name = "__subosi4", .linkage = linkage });
-    const __subodi4 = @import("compiler_rt/subo.zig").__subodi4;
-    @export(__subodi4, .{ .name = "__subodi4", .linkage = linkage });
-    const __suboti4 = @import("compiler_rt/subo.zig").__suboti4;
-    @export(__suboti4, .{ .name = "__suboti4", .linkage = linkage });
-    const __mulosi4 = @import("compiler_rt/mulo.zig").__mulosi4;
-    @export(__mulosi4, .{ .name = "__mulosi4", .linkage = linkage });
-    const __mulodi4 = @import("compiler_rt/mulo.zig").__mulodi4;
-    @export(__mulodi4, .{ .name = "__mulodi4", .linkage = linkage });
-    const __muloti4 = @import("compiler_rt/mulo.zig").__muloti4;
-    @export(__muloti4, .{ .name = "__muloti4", .linkage = linkage });
-
-    // Integer Comparison
-    // (a <  b) => 0
-    // (a == b) => 1
-    // (a >  b) => 2
-    const __cmpsi2 = @import("compiler_rt/cmp.zig").__cmpsi2;
-    @export(__cmpsi2, .{ .name = "__cmpsi2", .linkage = linkage });
-    const __cmpdi2 = @import("compiler_rt/cmp.zig").__cmpdi2;
-    @export(__cmpdi2, .{ .name = "__cmpdi2", .linkage = linkage });
-    const __cmpti2 = @import("compiler_rt/cmp.zig").__cmpti2;
-    @export(__cmpti2, .{ .name = "__cmpti2", .linkage = linkage });
-    const __ucmpsi2 = @import("compiler_rt/cmp.zig").__ucmpsi2;
-    @export(__ucmpsi2, .{ .name = "__ucmpsi2", .linkage = linkage });
-    const __ucmpdi2 = @import("compiler_rt/cmp.zig").__ucmpdi2;
-    @export(__ucmpdi2, .{ .name = "__ucmpdi2", .linkage = linkage });
-    const __ucmpti2 = @import("compiler_rt/cmp.zig").__ucmpti2;
-    @export(__ucmpti2, .{ .name = "__ucmpti2", .linkage = linkage });
+    _ = @import("compiler_rt/sin.zig");
+    _ = @import("compiler_rt/cos.zig");
+    _ = @import("compiler_rt/sincos.zig");
+    _ = @import("compiler_rt/ceil.zig");
+    _ = @import("compiler_rt/exp.zig");
+    _ = @import("compiler_rt/exp2.zig");
+    _ = @import("compiler_rt/fabs.zig");
+    _ = @import("compiler_rt/floor.zig");
+    _ = @import("compiler_rt/fma.zig");
+    _ = @import("compiler_rt/fmax.zig");
+    _ = @import("compiler_rt/fmin.zig");
+    _ = @import("compiler_rt/fmod.zig");
+    _ = @import("compiler_rt/log.zig");
+    _ = @import("compiler_rt/log10.zig");
+    _ = @import("compiler_rt/log2.zig");
+    _ = @import("compiler_rt/round.zig");
+    _ = @import("compiler_rt/sqrt.zig");
+    _ = @import("compiler_rt/tan.zig");
+    _ = @import("compiler_rt/trunc.zig");
+    _ = @import("compiler_rt/extendXfYf2.zig");
+    _ = @import("compiler_rt/extend_f80.zig");
+    _ = @import("compiler_rt/compareXf2.zig");
+    _ = @import("compiler_rt/stack_probe.zig");
+    _ = @import("compiler_rt/divti3.zig");
+    _ = @import("compiler_rt/modti3.zig");
+    _ = @import("compiler_rt/multi3.zig");
+    _ = @import("compiler_rt/udivti3.zig");
+    _ = @import("compiler_rt/udivmodti4.zig");
+    _ = @import("compiler_rt/umodti3.zig");
+    _ = @import("compiler_rt/truncXfYf2.zig");
+    _ = @import("compiler_rt/trunc_f80.zig");
+    _ = @import("compiler_rt/addXf3.zig");
+    _ = @import("compiler_rt/mulXf3.zig");
+    _ = @import("compiler_rt/divsf3.zig");
+    _ = @import("compiler_rt/divdf3.zig");
+    _ = @import("compiler_rt/divxf3.zig");
+    _ = @import("compiler_rt/divtf3.zig");
+    _ = @import("compiler_rt/floatXiYf.zig");
+    _ = @import("compiler_rt/fixXfYi.zig");
+    _ = @import("compiler_rt/count0bits.zig");
+    _ = @import("compiler_rt/parity.zig");
+    _ = @import("compiler_rt/popcount.zig");
+    _ = @import("compiler_rt/bswap.zig");
+    _ = @import("compiler_rt/int.zig");
+    _ = @import("compiler_rt/shift.zig");
+    _ = @import("compiler_rt/negXi2.zig");
+    _ = @import("compiler_rt/muldi3.zig");
+    _ = @import("compiler_rt/absv.zig");
+    _ = @import("compiler_rt/negv.zig");
+    _ = @import("compiler_rt/addo.zig");
+    _ = @import("compiler_rt/subo.zig");
+    _ = @import("compiler_rt/mulo.zig");
+    _ = @import("compiler_rt/cmp.zig");
+    _ = @import("compiler_rt/negXf2.zig");
+    _ = @import("compiler_rt/os_version_check.zig");
+    _ = @import("compiler_rt/emutls.zig");
+    _ = @import("compiler_rt/arm.zig");
+    _ = @import("compiler_rt/aulldiv.zig");
+    _ = @import("compiler_rt/sparc.zig");
+    _ = @import("compiler_rt/clear_cache.zig");
 
     // missing: Floating point raised to integer power
 
@@ -544,342 +71,4 @@ comptime {
     // (a + ib) * (c + id)
     // (a + ib) / (c + id)
 
-    const __negsf2 = @import("compiler_rt/negXf2.zig").__negsf2;
-    @export(__negsf2, .{ .name = "__negsf2", .linkage = linkage });
-    const __negdf2 = @import("compiler_rt/negXf2.zig").__negdf2;
-    @export(__negdf2, .{ .name = "__negdf2", .linkage = linkage });
-
-    if (builtin.link_libc and os_tag == .openbsd) {
-        const __emutls_get_address = @import("compiler_rt/emutls.zig").__emutls_get_address;
-        @export(__emutls_get_address, .{ .name = "__emutls_get_address", .linkage = linkage });
-    }
-
-    if ((arch.isARM() or arch.isThumb()) and !is_test) {
-        const __aeabi_unwind_cpp_pr0 = @import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr0;
-        @export(__aeabi_unwind_cpp_pr0, .{ .name = "__aeabi_unwind_cpp_pr0", .linkage = linkage });
-        const __aeabi_unwind_cpp_pr1 = @import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr1;
-        @export(__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = linkage });
-        const __aeabi_unwind_cpp_pr2 = @import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr2;
-        @export(__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = linkage });
-
-        @export(__muldi3, .{ .name = "__aeabi_lmul", .linkage = linkage });
-
-        const __aeabi_ldivmod = @import("compiler_rt/arm.zig").__aeabi_ldivmod;
-        @export(__aeabi_ldivmod, .{ .name = "__aeabi_ldivmod", .linkage = linkage });
-        const __aeabi_uldivmod = @import("compiler_rt/arm.zig").__aeabi_uldivmod;
-        @export(__aeabi_uldivmod, .{ .name = "__aeabi_uldivmod", .linkage = linkage });
-
-        @export(__divsi3, .{ .name = "__aeabi_idiv", .linkage = linkage });
-        const __aeabi_idivmod = @import("compiler_rt/arm.zig").__aeabi_idivmod;
-        @export(__aeabi_idivmod, .{ .name = "__aeabi_idivmod", .linkage = linkage });
-        @export(__udivsi3, .{ .name = "__aeabi_uidiv", .linkage = linkage });
-        const __aeabi_uidivmod = @import("compiler_rt/arm.zig").__aeabi_uidivmod;
-        @export(__aeabi_uidivmod, .{ .name = "__aeabi_uidivmod", .linkage = linkage });
-
-        const __aeabi_memcpy = @import("compiler_rt/arm.zig").__aeabi_memcpy;
-        @export(__aeabi_memcpy, .{ .name = "__aeabi_memcpy", .linkage = linkage });
-        @export(__aeabi_memcpy, .{ .name = "__aeabi_memcpy4", .linkage = linkage });
-        @export(__aeabi_memcpy, .{ .name = "__aeabi_memcpy8", .linkage = linkage });
-
-        const __aeabi_memmove = @import("compiler_rt/arm.zig").__aeabi_memmove;
-        @export(__aeabi_memmove, .{ .name = "__aeabi_memmove", .linkage = linkage });
-        @export(__aeabi_memmove, .{ .name = "__aeabi_memmove4", .linkage = linkage });
-        @export(__aeabi_memmove, .{ .name = "__aeabi_memmove8", .linkage = linkage });
-
-        const __aeabi_memset = @import("compiler_rt/arm.zig").__aeabi_memset;
-        @export(__aeabi_memset, .{ .name = "__aeabi_memset", .linkage = linkage });
-        @export(__aeabi_memset, .{ .name = "__aeabi_memset4", .linkage = linkage });
-        @export(__aeabi_memset, .{ .name = "__aeabi_memset8", .linkage = linkage });
-
-        const __aeabi_memclr = @import("compiler_rt/arm.zig").__aeabi_memclr;
-        @export(__aeabi_memclr, .{ .name = "__aeabi_memclr", .linkage = linkage });
-        @export(__aeabi_memclr, .{ .name = "__aeabi_memclr4", .linkage = linkage });
-        @export(__aeabi_memclr, .{ .name = "__aeabi_memclr8", .linkage = linkage });
-
-        if (os_tag == .linux) {
-            const __aeabi_read_tp = @import("compiler_rt/arm.zig").__aeabi_read_tp;
-            @export(__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = linkage });
-        }
-
-        const __aeabi_f2d = @import("compiler_rt/extendXfYf2.zig").__aeabi_f2d;
-        @export(__aeabi_f2d, .{ .name = "__aeabi_f2d", .linkage = linkage });
-        const __aeabi_i2d = @import("compiler_rt/floatXiYf.zig").__aeabi_i2d;
-        @export(__aeabi_i2d, .{ .name = "__aeabi_i2d", .linkage = linkage });
-        const __aeabi_l2d = @import("compiler_rt/floatXiYf.zig").__aeabi_l2d;
-        @export(__aeabi_l2d, .{ .name = "__aeabi_l2d", .linkage = linkage });
-        const __aeabi_l2f = @import("compiler_rt/floatXiYf.zig").__aeabi_l2f;
-        @export(__aeabi_l2f, .{ .name = "__aeabi_l2f", .linkage = linkage });
-        const __aeabi_ui2d = @import("compiler_rt/floatXiYf.zig").__aeabi_ui2d;
-        @export(__aeabi_ui2d, .{ .name = "__aeabi_ui2d", .linkage = linkage });
-        const __aeabi_ul2d = @import("compiler_rt/floatXiYf.zig").__aeabi_ul2d;
-        @export(__aeabi_ul2d, .{ .name = "__aeabi_ul2d", .linkage = linkage });
-        const __aeabi_ui2f = @import("compiler_rt/floatXiYf.zig").__aeabi_ui2f;
-        @export(__aeabi_ui2f, .{ .name = "__aeabi_ui2f", .linkage = linkage });
-        const __aeabi_ul2f = @import("compiler_rt/floatXiYf.zig").__aeabi_ul2f;
-        @export(__aeabi_ul2f, .{ .name = "__aeabi_ul2f", .linkage = linkage });
-
-        const __aeabi_fneg = @import("compiler_rt/negXf2.zig").__aeabi_fneg;
-        @export(__aeabi_fneg, .{ .name = "__aeabi_fneg", .linkage = linkage });
-        const __aeabi_dneg = @import("compiler_rt/negXf2.zig").__aeabi_dneg;
-        @export(__aeabi_dneg, .{ .name = "__aeabi_dneg", .linkage = linkage });
-
-        const __aeabi_fmul = @import("compiler_rt/mulXf3.zig").__aeabi_fmul;
-        @export(__aeabi_fmul, .{ .name = "__aeabi_fmul", .linkage = linkage });
-        const __aeabi_dmul = @import("compiler_rt/mulXf3.zig").__aeabi_dmul;
-        @export(__aeabi_dmul, .{ .name = "__aeabi_dmul", .linkage = linkage });
-
-        const __aeabi_d2h = @import("compiler_rt/truncXfYf2.zig").__aeabi_d2h;
-        @export(__aeabi_d2h, .{ .name = "__aeabi_d2h", .linkage = linkage });
-
-        const __aeabi_f2ulz = @import("compiler_rt/fixXfYi.zig").__aeabi_f2ulz;
-        @export(__aeabi_f2ulz, .{ .name = "__aeabi_f2ulz", .linkage = linkage });
-        const __aeabi_d2ulz = @import("compiler_rt/fixXfYi.zig").__aeabi_d2ulz;
-        @export(__aeabi_d2ulz, .{ .name = "__aeabi_d2ulz", .linkage = linkage });
-
-        const __aeabi_f2lz = @import("compiler_rt/fixXfYi.zig").__aeabi_f2lz;
-        @export(__aeabi_f2lz, .{ .name = "__aeabi_f2lz", .linkage = linkage });
-        const __aeabi_d2lz = @import("compiler_rt/fixXfYi.zig").__aeabi_d2lz;
-        @export(__aeabi_d2lz, .{ .name = "__aeabi_d2lz", .linkage = linkage });
-
-        const __aeabi_d2uiz = @import("compiler_rt/fixXfYi.zig").__aeabi_d2uiz;
-        @export(__aeabi_d2uiz, .{ .name = "__aeabi_d2uiz", .linkage = linkage });
-
-        const __aeabi_h2f = @import("compiler_rt/extendXfYf2.zig").__aeabi_h2f;
-        @export(__aeabi_h2f, .{ .name = "__aeabi_h2f", .linkage = linkage });
-        const __aeabi_f2h = @import("compiler_rt/truncXfYf2.zig").__aeabi_f2h;
-        @export(__aeabi_f2h, .{ .name = "__aeabi_f2h", .linkage = linkage });
-
-        const __aeabi_i2f = @import("compiler_rt/floatXiYf.zig").__aeabi_i2f;
-        @export(__aeabi_i2f, .{ .name = "__aeabi_i2f", .linkage = linkage });
-        const __aeabi_d2f = @import("compiler_rt/truncXfYf2.zig").__aeabi_d2f;
-        @export(__aeabi_d2f, .{ .name = "__aeabi_d2f", .linkage = linkage });
-
-        const __aeabi_fadd = @import("compiler_rt/addXf3.zig").__aeabi_fadd;
-        @export(__aeabi_fadd, .{ .name = "__aeabi_fadd", .linkage = linkage });
-        const __aeabi_dadd = @import("compiler_rt/addXf3.zig").__aeabi_dadd;
-        @export(__aeabi_dadd, .{ .name = "__aeabi_dadd", .linkage = linkage });
-        const __aeabi_fsub = @import("compiler_rt/addXf3.zig").__aeabi_fsub;
-        @export(__aeabi_fsub, .{ .name = "__aeabi_fsub", .linkage = linkage });
-        const __aeabi_dsub = @import("compiler_rt/addXf3.zig").__aeabi_dsub;
-        @export(__aeabi_dsub, .{ .name = "__aeabi_dsub", .linkage = linkage });
-
-        const __aeabi_f2uiz = @import("compiler_rt/fixXfYi.zig").__aeabi_f2uiz;
-        @export(__aeabi_f2uiz, .{ .name = "__aeabi_f2uiz", .linkage = linkage });
-
-        const __aeabi_f2iz = @import("compiler_rt/fixXfYi.zig").__aeabi_f2iz;
-        @export(__aeabi_f2iz, .{ .name = "__aeabi_f2iz", .linkage = linkage });
-        const __aeabi_d2iz = @import("compiler_rt/fixXfYi.zig").__aeabi_d2iz;
-        @export(__aeabi_d2iz, .{ .name = "__aeabi_d2iz", .linkage = linkage });
-
-        const __aeabi_fdiv = @import("compiler_rt/divsf3.zig").__aeabi_fdiv;
-        @export(__aeabi_fdiv, .{ .name = "__aeabi_fdiv", .linkage = linkage });
-        const __aeabi_ddiv = @import("compiler_rt/divdf3.zig").__aeabi_ddiv;
-        @export(__aeabi_ddiv, .{ .name = "__aeabi_ddiv", .linkage = linkage });
-
-        const __aeabi_llsl = @import("compiler_rt/shift.zig").__aeabi_llsl;
-        @export(__aeabi_llsl, .{ .name = "__aeabi_llsl", .linkage = linkage });
-        const __aeabi_lasr = @import("compiler_rt/shift.zig").__aeabi_lasr;
-        @export(__aeabi_lasr, .{ .name = "__aeabi_lasr", .linkage = linkage });
-        const __aeabi_llsr = @import("compiler_rt/shift.zig").__aeabi_llsr;
-        @export(__aeabi_llsr, .{ .name = "__aeabi_llsr", .linkage = linkage });
-
-        const __aeabi_fcmpeq = @import("compiler_rt/compareXf2.zig").__aeabi_fcmpeq;
-        @export(__aeabi_fcmpeq, .{ .name = "__aeabi_fcmpeq", .linkage = linkage });
-        const __aeabi_fcmplt = @import("compiler_rt/compareXf2.zig").__aeabi_fcmplt;
-        @export(__aeabi_fcmplt, .{ .name = "__aeabi_fcmplt", .linkage = linkage });
-        const __aeabi_fcmple = @import("compiler_rt/compareXf2.zig").__aeabi_fcmple;
-        @export(__aeabi_fcmple, .{ .name = "__aeabi_fcmple", .linkage = linkage });
-        const __aeabi_fcmpge = @import("compiler_rt/compareXf2.zig").__aeabi_fcmpge;
-        @export(__aeabi_fcmpge, .{ .name = "__aeabi_fcmpge", .linkage = linkage });
-        const __aeabi_fcmpgt = @import("compiler_rt/compareXf2.zig").__aeabi_fcmpgt;
-        @export(__aeabi_fcmpgt, .{ .name = "__aeabi_fcmpgt", .linkage = linkage });
-        const __aeabi_fcmpun = @import("compiler_rt/compareXf2.zig").__aeabi_fcmpun;
-        @export(__aeabi_fcmpun, .{ .name = "__aeabi_fcmpun", .linkage = linkage });
-
-        const __aeabi_dcmpeq = @import("compiler_rt/compareXf2.zig").__aeabi_dcmpeq;
-        @export(__aeabi_dcmpeq, .{ .name = "__aeabi_dcmpeq", .linkage = linkage });
-        const __aeabi_dcmplt = @import("compiler_rt/compareXf2.zig").__aeabi_dcmplt;
-        @export(__aeabi_dcmplt, .{ .name = "__aeabi_dcmplt", .linkage = linkage });
-        const __aeabi_dcmple = @import("compiler_rt/compareXf2.zig").__aeabi_dcmple;
-        @export(__aeabi_dcmple, .{ .name = "__aeabi_dcmple", .linkage = linkage });
-        const __aeabi_dcmpge = @import("compiler_rt/compareXf2.zig").__aeabi_dcmpge;
-        @export(__aeabi_dcmpge, .{ .name = "__aeabi_dcmpge", .linkage = linkage });
-        const __aeabi_dcmpgt = @import("compiler_rt/compareXf2.zig").__aeabi_dcmpgt;
-        @export(__aeabi_dcmpgt, .{ .name = "__aeabi_dcmpgt", .linkage = linkage });
-        const __aeabi_dcmpun = @import("compiler_rt/compareXf2.zig").__aeabi_dcmpun;
-        @export(__aeabi_dcmpun, .{ .name = "__aeabi_dcmpun", .linkage = linkage });
-    }
-
-    if (arch == .i386 and abi == .msvc) {
-        // Don't let LLVM apply the stdcall name mangling on those MSVC builtins
-        const _alldiv = @import("compiler_rt/aulldiv.zig")._alldiv;
-        @export(_alldiv, .{ .name = "\x01__alldiv", .linkage = strong_linkage });
-        const _aulldiv = @import("compiler_rt/aulldiv.zig")._aulldiv;
-        @export(_aulldiv, .{ .name = "\x01__aulldiv", .linkage = strong_linkage });
-        const _allrem = @import("compiler_rt/aullrem.zig")._allrem;
-        @export(_allrem, .{ .name = "\x01__allrem", .linkage = strong_linkage });
-        const _aullrem = @import("compiler_rt/aullrem.zig")._aullrem;
-        @export(_aullrem, .{ .name = "\x01__aullrem", .linkage = strong_linkage });
-    }
-
-    mathExport("ceil", @import("./compiler_rt/ceil.zig"));
-    mathExport("cos", @import("./compiler_rt/cos.zig"));
-    mathExport("exp", @import("./compiler_rt/exp.zig"));
-    mathExport("exp2", @import("./compiler_rt/exp2.zig"));
-    mathExport("fabs", @import("./compiler_rt/fabs.zig"));
-    mathExport("floor", @import("./compiler_rt/floor.zig"));
-    mathExport("fma", @import("./compiler_rt/fma.zig"));
-    mathExport("fmax", @import("./compiler_rt/fmax.zig"));
-    mathExport("fmin", @import("./compiler_rt/fmin.zig"));
-    mathExport("fmod", @import("./compiler_rt/fmod.zig"));
-    mathExport("log", @import("./compiler_rt/log.zig"));
-    mathExport("log10", @import("./compiler_rt/log10.zig"));
-    mathExport("log2", @import("./compiler_rt/log2.zig"));
-    mathExport("round", @import("./compiler_rt/round.zig"));
-    mathExport("sin", @import("./compiler_rt/sin.zig"));
-    mathExport("sincos", @import("./compiler_rt/sincos.zig"));
-    mathExport("sqrt", @import("./compiler_rt/sqrt.zig"));
-    mathExport("tan", @import("./compiler_rt/tan.zig"));
-    mathExport("trunc", @import("./compiler_rt/trunc.zig"));
-
-    if (arch.isSPARC()) {
-        // SPARC systems use a different naming scheme
-        const _Qp_add = @import("compiler_rt/sparc.zig")._Qp_add;
-        @export(_Qp_add, .{ .name = "_Qp_add", .linkage = linkage });
-        const _Qp_div = @import("compiler_rt/sparc.zig")._Qp_div;
-        @export(_Qp_div, .{ .name = "_Qp_div", .linkage = linkage });
-        const _Qp_mul = @import("compiler_rt/sparc.zig")._Qp_mul;
-        @export(_Qp_mul, .{ .name = "_Qp_mul", .linkage = linkage });
-        const _Qp_sub = @import("compiler_rt/sparc.zig")._Qp_sub;
-        @export(_Qp_sub, .{ .name = "_Qp_sub", .linkage = linkage });
-
-        const _Qp_cmp = @import("compiler_rt/sparc.zig")._Qp_cmp;
-        @export(_Qp_cmp, .{ .name = "_Qp_cmp", .linkage = linkage });
-        const _Qp_feq = @import("compiler_rt/sparc.zig")._Qp_feq;
-        @export(_Qp_feq, .{ .name = "_Qp_feq", .linkage = linkage });
-        const _Qp_fne = @import("compiler_rt/sparc.zig")._Qp_fne;
-        @export(_Qp_fne, .{ .name = "_Qp_fne", .linkage = linkage });
-        const _Qp_flt = @import("compiler_rt/sparc.zig")._Qp_flt;
-        @export(_Qp_flt, .{ .name = "_Qp_flt", .linkage = linkage });
-        const _Qp_fle = @import("compiler_rt/sparc.zig")._Qp_fle;
-        @export(_Qp_fle, .{ .name = "_Qp_fle", .linkage = linkage });
-        const _Qp_fgt = @import("compiler_rt/sparc.zig")._Qp_fgt;
-        @export(_Qp_fgt, .{ .name = "_Qp_fgt", .linkage = linkage });
-        const _Qp_fge = @import("compiler_rt/sparc.zig")._Qp_fge;
-        @export(_Qp_fge, .{ .name = "_Qp_fge", .linkage = linkage });
-
-        const _Qp_itoq = @import("compiler_rt/sparc.zig")._Qp_itoq;
-        @export(_Qp_itoq, .{ .name = "_Qp_itoq", .linkage = linkage });
-        const _Qp_uitoq = @import("compiler_rt/sparc.zig")._Qp_uitoq;
-        @export(_Qp_uitoq, .{ .name = "_Qp_uitoq", .linkage = linkage });
-        const _Qp_xtoq = @import("compiler_rt/sparc.zig")._Qp_xtoq;
-        @export(_Qp_xtoq, .{ .name = "_Qp_xtoq", .linkage = linkage });
-        const _Qp_uxtoq = @import("compiler_rt/sparc.zig")._Qp_uxtoq;
-        @export(_Qp_uxtoq, .{ .name = "_Qp_uxtoq", .linkage = linkage });
-        const _Qp_stoq = @import("compiler_rt/sparc.zig")._Qp_stoq;
-        @export(_Qp_stoq, .{ .name = "_Qp_stoq", .linkage = linkage });
-        const _Qp_dtoq = @import("compiler_rt/sparc.zig")._Qp_dtoq;
-        @export(_Qp_dtoq, .{ .name = "_Qp_dtoq", .linkage = linkage });
-        const _Qp_qtoi = @import("compiler_rt/sparc.zig")._Qp_qtoi;
-        @export(_Qp_qtoi, .{ .name = "_Qp_qtoi", .linkage = linkage });
-        const _Qp_qtoui = @import("compiler_rt/sparc.zig")._Qp_qtoui;
-        @export(_Qp_qtoui, .{ .name = "_Qp_qtoui", .linkage = linkage });
-        const _Qp_qtox = @import("compiler_rt/sparc.zig")._Qp_qtox;
-        @export(_Qp_qtox, .{ .name = "_Qp_qtox", .linkage = linkage });
-        const _Qp_qtoux = @import("compiler_rt/sparc.zig")._Qp_qtoux;
-        @export(_Qp_qtoux, .{ .name = "_Qp_qtoux", .linkage = linkage });
-        const _Qp_qtos = @import("compiler_rt/sparc.zig")._Qp_qtos;
-        @export(_Qp_qtos, .{ .name = "_Qp_qtos", .linkage = linkage });
-        const _Qp_qtod = @import("compiler_rt/sparc.zig")._Qp_qtod;
-        @export(_Qp_qtod, .{ .name = "_Qp_qtod", .linkage = linkage });
-    }
-
-    if (is_ppc and !is_test) {
-        @export(__addtf3, .{ .name = "__addkf3", .linkage = linkage });
-        @export(__subtf3, .{ .name = "__subkf3", .linkage = linkage });
-        @export(__multf3, .{ .name = "__mulkf3", .linkage = linkage });
-        @export(__divtf3, .{ .name = "__divkf3", .linkage = linkage });
-        @export(__extendsftf2, .{ .name = "__extendsfkf2", .linkage = linkage });
-        @export(__extenddftf2, .{ .name = "__extenddfkf2", .linkage = linkage });
-        @export(__trunctfsf2, .{ .name = "__trunckfsf2", .linkage = linkage });
-        @export(__trunctfdf2, .{ .name = "__trunckfdf2", .linkage = linkage });
-        @export(__fixtfdi, .{ .name = "__fixkfdi", .linkage = linkage });
-        @export(__fixtfsi, .{ .name = "__fixkfsi", .linkage = linkage });
-        @export(__fixunstfsi, .{ .name = "__fixunskfsi", .linkage = linkage });
-        @export(__fixunstfdi, .{ .name = "__fixunskfdi", .linkage = linkage });
-        @export(__floatsitf, .{ .name = "__floatsikf", .linkage = linkage });
-        @export(__floatditf, .{ .name = "__floatdikf", .linkage = linkage });
-        @export(__floatunditf, .{ .name = "__floatundikf", .linkage = linkage });
-        @export(__floatunsitf, .{ .name = "__floatunsikf", .linkage = linkage });
-        @export(__floatuntitf, .{ .name = "__floatuntikf", .linkage = linkage });
-
-        @export(__letf2, .{ .name = "__eqkf2", .linkage = linkage });
-        @export(__letf2, .{ .name = "__nekf2", .linkage = linkage });
-        @export(__getf2, .{ .name = "__gekf2", .linkage = linkage });
-        @export(__letf2, .{ .name = "__ltkf2", .linkage = linkage });
-        @export(__letf2, .{ .name = "__lekf2", .linkage = linkage });
-        @export(__getf2, .{ .name = "__gtkf2", .linkage = linkage });
-        @export(__unordtf2, .{ .name = "__unordkf2", .linkage = linkage });
-    }
-}
-
-inline fn mathExport(double_name: []const u8, comptime import: type) void {
-    const half_name = "__" ++ double_name ++ "h";
-    const half_fn = @field(import, half_name);
-    const float_name = double_name ++ "f";
-    const float_fn = @field(import, float_name);
-    const double_fn = @field(import, double_name);
-    const long_double_name = double_name ++ "l";
-    const xf80_name = "__" ++ double_name ++ "x";
-    const xf80_fn = @field(import, xf80_name);
-    const quad_name = double_name ++ "q";
-    const quad_fn = @field(import, quad_name);
-
-    @export(half_fn, .{ .name = half_name, .linkage = linkage });
-    @export(float_fn, .{ .name = float_name, .linkage = linkage });
-    @export(double_fn, .{ .name = double_name, .linkage = linkage });
-    @export(xf80_fn, .{ .name = xf80_name, .linkage = linkage });
-    @export(quad_fn, .{ .name = quad_name, .linkage = linkage });
-
-    if (is_test) return;
-
-    const pairs = .{
-        .{ f16, half_fn },
-        .{ f32, float_fn },
-        .{ f64, double_fn },
-        .{ f80, xf80_fn },
-        .{ f128, quad_fn },
-    };
-
-    if (builtin.os.tag == .windows) {
-        // Weak aliases don't work on Windows, so we have to provide the 'l' variants
-        // as additional function definitions that jump to the real definition.
-        const long_double_fn = @field(import, long_double_name);
-        @export(long_double_fn, .{ .name = long_double_name, .linkage = linkage });
-    } else {
-        inline for (pairs) |pair| {
-            const F = pair[0];
-            const func = pair[1];
-            if (builtin.target.longDoubleIs(F)) {
-                @export(func, .{ .name = long_double_name, .linkage = linkage });
-            }
-        }
-    }
-
-    if (is_ppc) {
-        // LLVM PPC backend lowers f128 ops with the suffix `f128` instead of `l`.
-        @export(quad_fn, .{ .name = double_name ++ "f128", .linkage = linkage });
-    }
-}
-
-// Avoid dragging in the runtime safety mechanisms into this .o file,
-// unless we're trying to test this file.
-pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn {
-    _ = error_return_trace;
-    @setCold(true);
-    if (is_test) {
-        std.debug.panic("{s}", .{msg});
-    } else {
-        unreachable;
-    }
 }
src/link/Coff.zig
@@ -1354,7 +1354,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !
             }
             // MSVC compiler_rt is missing some stuff, so we build it unconditionally but
             // and rely on weak linkage to allow MSVC compiler_rt functions to override ours.
-            if (comp.compiler_rt_static_lib) |lib| {
+            if (comp.compiler_rt_static_lib.crt_lib_file) |lib| {
                 try argv.append(lib.full_object_path);
             }
         }
src/link/Elf.zig
@@ -1272,7 +1272,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
     const stack_size = self.base.options.stack_size_override orelse 16777216;
     const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;
     const compiler_rt_path: ?[]const u8 = blk: {
-        if (comp.compiler_rt_static_lib) |x| break :blk x.full_object_path;
+        if (comp.compiler_rt_static_lib.crt_lib_file) |x| break :blk x.full_object_path;
         if (comp.compiler_rt_obj) |x| break :blk x.full_object_path;
         break :blk null;
     };
src/link/MachO.zig
@@ -738,7 +738,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
                 try positionals.append(p);
             }
 
-            if (comp.compiler_rt_static_lib) |lib| {
+            if (comp.compiler_rt_static_lib.crt_lib_file) |lib| {
                 try positionals.append(lib.full_object_path);
             }
 
src/link/Wasm.zig
@@ -2255,7 +2255,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
     const is_obj = self.base.options.output_mode == .Obj;
 
     const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt and !is_obj)
-        comp.compiler_rt_static_lib.?.full_object_path
+        comp.compiler_rt_static_lib.crt_lib_file.?.full_object_path
     else
         null;
 
src/Compilation.zig
@@ -23,6 +23,7 @@ const mingw = @import("mingw.zig");
 const libunwind = @import("libunwind.zig");
 const libcxx = @import("libcxx.zig");
 const wasi_libc = @import("wasi_libc.zig");
+const compiler_rt = @import("compiler_rt.zig");
 const fatal = @import("main.zig").fatal;
 const clangMain = @import("main.zig").clangMain;
 const Module = @import("Module.zig");
@@ -131,7 +132,7 @@ libssp_static_lib: ?CRTFile = null,
 libc_static_lib: ?CRTFile = null,
 /// Populated when we build the libcompiler_rt static library. A Job to build this is placed in the queue
 /// and resolved before calling linker.flush().
-compiler_rt_static_lib: ?CRTFile = null,
+compiler_rt_static_lib: compiler_rt.CompilerRtLib = .{},
 /// Populated when we build the compiler_rt_obj object. A Job to build this is placed in the queue
 /// and resolved before calling linker.flush().
 compiler_rt_obj: ?CRTFile = null,
@@ -175,7 +176,7 @@ pub const CRTFile = struct {
     lock: Cache.Lock,
     full_object_path: []const u8,
 
-    fn deinit(self: *CRTFile, gpa: Allocator) void {
+    pub fn deinit(self: *CRTFile, gpa: Allocator) void {
         self.lock.release();
         gpa.free(self.full_object_path);
         self.* = undefined;
@@ -1978,9 +1979,7 @@ pub fn destroy(self: *Compilation) void {
     if (self.libcxxabi_static_lib) |*crt_file| {
         crt_file.deinit(gpa);
     }
-    if (self.compiler_rt_static_lib) |*crt_file| {
-        crt_file.deinit(gpa);
-    }
+    self.compiler_rt_static_lib.deinit(gpa);
     if (self.compiler_rt_obj) |*crt_file| {
         crt_file.deinit(gpa);
     }
@@ -3138,11 +3137,9 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
             const named_frame = tracy.namedFrame("compiler_rt_lib");
             defer named_frame.end();
 
-            comp.buildOutputFromZig(
-                "compiler_rt.zig",
-                .Lib,
+            compiler_rt.buildCompilerRtLib(
+                comp,
                 &comp.compiler_rt_static_lib,
-                .compiler_rt,
             ) catch |err| switch (err) {
                 error.OutOfMemory => return error.OutOfMemory,
                 error.SubCompilationFailed => return, // error reported already
@@ -4897,7 +4894,7 @@ pub fn updateSubCompilation(sub_compilation: *Compilation) !void {
     }
 }
 
-fn buildOutputFromZig(
+pub fn buildOutputFromZig(
     comp: *Compilation,
     src_basename: []const u8,
     output_mode: std.builtin.OutputMode,
@@ -4914,7 +4911,15 @@ fn buildOutputFromZig(
         .root_src_path = src_basename,
     };
     defer main_pkg.deinitTable(comp.gpa);
-    const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];
+
+    const root_name = root_name: {
+        const basename = if (std.fs.path.dirname(src_basename)) |dirname|
+            src_basename[dirname.len + 1 ..]
+        else
+            src_basename;
+        const root_name = basename[0 .. basename.len - std.fs.path.extension(basename).len];
+        break :root_name root_name;
+    };
     const target = comp.getTarget();
     const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{
         .root_name = root_name,
src/compiler_rt.zig
@@ -0,0 +1,186 @@
+const std = @import("std");
+const builtin = @import("builtin");
+const Allocator = std.mem.Allocator;
+const mem = std.mem;
+const tracy = @import("tracy.zig");
+const trace = tracy.trace;
+
+const Compilation = @import("Compilation.zig");
+const CRTFile = Compilation.CRTFile;
+const LinkObject = Compilation.LinkObject;
+const Package = @import("Package.zig");
+
+pub const CompilerRtLib = struct {
+    crt_object_files: [sources.len]?CRTFile = undefined,
+    crt_lib_file: ?CRTFile = null,
+
+    pub fn deinit(crt_lib: *CompilerRtLib, gpa: Allocator) void {
+        for (crt_lib.crt_object_files) |*crt_file| {
+            if (crt_file.*) |*cf| {
+                cf.deinit(gpa);
+            }
+        }
+        if (crt_lib.crt_lib_file) |*crt_file| {
+            crt_file.deinit(gpa);
+        }
+    }
+};
+
+pub fn buildCompilerRtLib(comp: *Compilation, compiler_rt_lib: *CompilerRtLib) !void {
+    const tracy_trace = trace(@src());
+    defer tracy_trace.end();
+
+    var progress: std.Progress = .{ .dont_print_on_dumb = true };
+    var progress_node = progress.start("Compile Compiler-RT", sources.len + 1);
+    defer progress_node.end();
+    if (comp.color == .off) progress.terminal = null;
+
+    progress_node.activate();
+
+    var link_objects: [sources.len]LinkObject = undefined;
+    for (sources) |source, i| {
+        var obj_progress_node = progress_node.start(source, 0);
+        obj_progress_node.activate();
+        defer obj_progress_node.end();
+
+        try comp.buildOutputFromZig(source, .Obj, &compiler_rt_lib.crt_object_files[i], .compiler_rt);
+        link_objects[i] = .{
+            .path = compiler_rt_lib.crt_object_files[i].?.full_object_path,
+            .must_link = true,
+        };
+    }
+
+    const root_name = "compiler_rt";
+
+    var lib_progress_node = progress_node.start(root_name, 0);
+    lib_progress_node.activate();
+    defer lib_progress_node.end();
+
+    const target = comp.getTarget();
+    const basename = try std.zig.binNameAlloc(comp.gpa, .{
+        .root_name = root_name,
+        .target = target,
+        .output_mode = .Lib,
+    });
+    errdefer comp.gpa.free(basename);
+
+    // TODO: This is extracted into a local variable to work around a stage1 miscompilation.
+    const emit_bin = Compilation.EmitLoc{
+        .directory = null, // Put it in the cache directory.
+        .basename = basename,
+    };
+    const sub_compilation = try Compilation.create(comp.gpa, .{
+        .local_cache_directory = comp.global_cache_directory,
+        .global_cache_directory = comp.global_cache_directory,
+        .zig_lib_directory = comp.zig_lib_directory,
+        .cache_mode = .whole,
+        .target = target,
+        .root_name = root_name,
+        .main_pkg = null,
+        .output_mode = .Lib,
+        .link_mode = .Static,
+        .function_sections = true,
+        .thread_pool = comp.thread_pool,
+        .libc_installation = comp.bin_file.options.libc_installation,
+        .emit_bin = emit_bin,
+        .optimize_mode = comp.compilerRtOptMode(),
+        .want_sanitize_c = false,
+        .want_stack_check = false,
+        .want_red_zone = comp.bin_file.options.red_zone,
+        .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
+        .want_valgrind = false,
+        .want_tsan = false,
+        .want_pic = comp.bin_file.options.pic,
+        .want_pie = comp.bin_file.options.pie,
+        .want_lto = comp.bin_file.options.lto,
+        .emit_h = null,
+        .strip = comp.compilerRtStrip(),
+        .is_native_os = comp.bin_file.options.is_native_os,
+        .is_native_abi = comp.bin_file.options.is_native_abi,
+        .self_exe_path = comp.self_exe_path,
+        .link_objects = &link_objects,
+        .verbose_cc = comp.verbose_cc,
+        .verbose_link = comp.bin_file.options.verbose_link,
+        .verbose_air = comp.verbose_air,
+        .verbose_llvm_ir = comp.verbose_llvm_ir,
+        .verbose_cimport = comp.verbose_cimport,
+        .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
+        .clang_passthrough_mode = comp.clang_passthrough_mode,
+        .skip_linker_dependencies = true,
+        .parent_compilation_link_libc = comp.bin_file.options.link_libc,
+    });
+    defer sub_compilation.destroy();
+
+    try sub_compilation.updateSubCompilation();
+
+    compiler_rt_lib.crt_lib_file = .{
+        .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{
+            sub_compilation.bin_file.options.emit.?.sub_path,
+        }),
+        .lock = sub_compilation.bin_file.toOwnedLock(),
+    };
+}
+
+const sources = &[_][]const u8{
+    "compiler_rt/atomics.zig",
+    "compiler_rt/sin.zig",
+    "compiler_rt/cos.zig",
+    "compiler_rt/sincos.zig",
+    "compiler_rt/ceil.zig",
+    "compiler_rt/exp.zig",
+    "compiler_rt/exp2.zig",
+    "compiler_rt/fabs.zig",
+    "compiler_rt/floor.zig",
+    "compiler_rt/fma.zig",
+    "compiler_rt/fmax.zig",
+    "compiler_rt/fmin.zig",
+    "compiler_rt/fmod.zig",
+    "compiler_rt/log.zig",
+    "compiler_rt/log10.zig",
+    "compiler_rt/log2.zig",
+    "compiler_rt/round.zig",
+    "compiler_rt/sqrt.zig",
+    "compiler_rt/tan.zig",
+    "compiler_rt/trunc.zig",
+    "compiler_rt/extendXfYf2.zig",
+    "compiler_rt/extend_f80.zig",
+    "compiler_rt/compareXf2.zig",
+    "compiler_rt/stack_probe.zig",
+    "compiler_rt/divti3.zig",
+    "compiler_rt/modti3.zig",
+    "compiler_rt/multi3.zig",
+    "compiler_rt/udivti3.zig",
+    "compiler_rt/udivmodti4.zig",
+    "compiler_rt/umodti3.zig",
+    "compiler_rt/truncXfYf2.zig",
+    "compiler_rt/trunc_f80.zig",
+    "compiler_rt/addXf3.zig",
+    "compiler_rt/mulXf3.zig",
+    "compiler_rt/divsf3.zig",
+    "compiler_rt/divdf3.zig",
+    "compiler_rt/divxf3.zig",
+    "compiler_rt/divtf3.zig",
+    "compiler_rt/floatXiYf.zig",
+    "compiler_rt/fixXfYi.zig",
+    "compiler_rt/count0bits.zig",
+    "compiler_rt/parity.zig",
+    "compiler_rt/popcount.zig",
+    "compiler_rt/bswap.zig",
+    "compiler_rt/int.zig",
+    "compiler_rt/shift.zig",
+    "compiler_rt/negXi2.zig",
+    "compiler_rt/muldi3.zig",
+    "compiler_rt/absv.zig",
+    "compiler_rt/negv.zig",
+    "compiler_rt/addo.zig",
+    "compiler_rt/subo.zig",
+    "compiler_rt/mulo.zig",
+    "compiler_rt/cmp.zig",
+    "compiler_rt/negXf2.zig",
+    "compiler_rt/os_version_check.zig",
+    "compiler_rt/emutls.zig",
+    "compiler_rt/arm.zig",
+    "compiler_rt/aulldiv.zig",
+    "compiler_rt/sparc.zig",
+    "compiler_rt/clear_cache.zig",
+};
src/musl.zig
@@ -4,7 +4,6 @@ const mem = std.mem;
 const path = std.fs.path;
 const assert = std.debug.assert;
 
-const target_util = @import("target.zig");
 const Compilation = @import("Compilation.zig");
 const build_options = @import("build_options");