Commit 3532abe0c6

Andrew Kelley <andrew@ziglang.org>
2021-12-15 12:37:49
compiler_rt: reorganize in a way that stage2 understands
Before this commit, stage2 behavior tests are regressed; it cannot build compiler-rt.
1 parent e45680c
Changed files (2)
lib
std
special
lib/std/special/compiler_rt/mulo.zig
@@ -7,60 +7,62 @@ const builtin = @import("builtin");
 // return if a*b overflows => 1 else => 0
 // see https://stackoverflow.com/a/26320664 for possible implementations
 
-fn muloXi4_generic(comptime ST: type) fn (a: ST, b: ST, overflow: *c_int) callconv(.C) ST {
-    return struct {
-        fn f(a: ST, b: ST, overflow: *c_int) callconv(.C) ST {
-            @setRuntimeSafety(builtin.is_test);
-            const BSIZE = @bitSizeOf(ST);
-            comptime var UT = switch (ST) {
-                i32 => u32,
-                i64 => u64,
-                i128 => u128,
-                else => unreachable,
-            };
-            const min = @bitCast(ST, @as(UT, 1 << (BSIZE - 1)));
-            const max = ~min;
-            overflow.* = 0;
-            const result = a *% b;
+inline fn muloXi4_generic(comptime ST: type, a: ST, b: ST, overflow: *c_int) ST {
+    @setRuntimeSafety(builtin.is_test);
+    const BSIZE = @bitSizeOf(ST);
+    comptime var UT = switch (ST) {
+        i32 => u32,
+        i64 => u64,
+        i128 => u128,
+        else => unreachable,
+    };
+    const min = @bitCast(ST, @as(UT, 1 << (BSIZE - 1)));
+    const max = ~min;
+    overflow.* = 0;
+    const result = a *% b;
 
-            // edge cases
-            if (a == min) {
-                if (b != 0 and b != 1) overflow.* = 1;
-                return result;
-            }
-            if (b == min) {
-                if (a != 0 and a != 1) overflow.* = 1;
-                return result;
-            }
+    // edge cases
+    if (a == min) {
+        if (b != 0 and b != 1) overflow.* = 1;
+        return result;
+    }
+    if (b == min) {
+        if (a != 0 and a != 1) overflow.* = 1;
+        return result;
+    }
 
-            // take sign of x sx
-            const sa = a >> (BSIZE - 1);
-            const sb = b >> (BSIZE - 1);
-            // take absolute value of a and b via
-            // abs(x) = (x^sx)) - sx
-            const abs_a = (a ^ sa) -% sa;
-            const abs_b = (b ^ sb) -% sb;
+    // take sign of x sx
+    const sa = a >> (BSIZE - 1);
+    const sb = b >> (BSIZE - 1);
+    // take absolute value of a and b via
+    // abs(x) = (x^sx)) - sx
+    const abs_a = (a ^ sa) -% sa;
+    const abs_b = (b ^ sb) -% sb;
 
-            // unitary magnitude, cannot have overflow
-            if (abs_a < 2 or abs_b < 2) return result;
+    // unitary magnitude, cannot have overflow
+    if (abs_a < 2 or abs_b < 2) return result;
 
-            // compare the signs of operands
-            if ((a ^ b) >> (BSIZE - 1) != 0) {
-                if (abs_a > @divTrunc(max, abs_b)) overflow.* = 1;
-            } else {
-                if (abs_a > @divTrunc(min, -abs_b)) overflow.* = 1;
-            }
+    // compare the signs of operands
+    if ((a ^ b) >> (BSIZE - 1) != 0) {
+        if (abs_a > @divTrunc(max, abs_b)) overflow.* = 1;
+    } else {
+        if (abs_a > @divTrunc(min, -abs_b)) overflow.* = 1;
+    }
 
-            return result;
-        }
-    }.f;
+    return result;
 }
 
-pub const __mulosi4 = muloXi4_generic(i32);
+pub fn __mulosi4(a: i32, b: i32, overflow: *c_int) callconv(.C) i32 {
+    return muloXi4_generic(i32, a, b, overflow);
+}
 
-pub const __mulodi4 = muloXi4_generic(i64);
+pub fn __mulodi4(a: i64, b: i64, overflow: *c_int) callconv(.C) i64 {
+    return muloXi4_generic(i64, a, b, overflow);
+}
 
-pub const __muloti4 = muloXi4_generic(i128);
+pub fn __muloti4(a: i128, b: i128, overflow: *c_int) callconv(.C) i128 {
+    return muloXi4_generic(i128, a, b, overflow);
+}
 
 test {
     _ = @import("mulosi4_test.zig");
lib/std/special/compiler_rt.zig
@@ -45,46 +45,45 @@ comptime {
     const __getf2 = @import("compiler_rt/compareXf2.zig").__getf2;
     @export(__getf2, .{ .name = "__getf2", .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 __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 __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 __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 });
+
     if (!is_test) {
         @export(__lesf2, .{ .name = "__cmpsf2", .linkage = linkage });
         @export(__ledf2, .{ .name = "__cmpdf2", .linkage = linkage });
         @export(__letf2, .{ .name = "__cmptf2", .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 });
         @export(__letf2, .{ .name = "__eqtf2", .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 });
         @export(__letf2, .{ .name = "__lttf2", .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 });
-        @export(__letf2, .{ .name = "__netf2", .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 });
         @export(__getf2, .{ .name = "__gttf2", .linkage = linkage });
-
+        @export(__letf2, .{ .name = "__netf2", .linkage = linkage });
         @export(__extendhfsf2, .{ .name = "__gnu_h2f_ieee", .linkage = linkage });
-
-        // Integral arithmetic which returns if overflow
-        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 });
     }
 
+    // Integral arithmetic which returns if overflow
+    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 });
+
     if (builtin.os.tag == .windows) {
         // Default stack-probe functions emitted by LLVM
         if (is_mingw) {