authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-12-15 04:37:49-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-12-15 14:23:28-07:00
log3532abe0c605746e048dae4bf31d0167151bbfd7
tree970e1f45ead535e9279cf61d9efec079a2f42872
parente45680cab5e9f5b28fd73ab58dae0c0f487fca48

compiler_rt: reorganize in a way that stage2 understands

Before this commit, stage2 behavior tests are regressed; it cannot build compiler-rt.

2 files changed, 76 insertions(+), 75 deletions(-)

lib/std/special/compiler_rt.zig+29-30
......@@ -45,46 +45,45 @@ comptime {
4545 const __getf2 = @import("compiler_rt/compareXf2.zig").__getf2;
4646 @export(__getf2, .{ .name = "__getf2", .linkage = linkage });
4747
48 const __eqsf2 = @import("compiler_rt/compareXf2.zig").__eqsf2;
49 @export(__eqsf2, .{ .name = "__eqsf2", .linkage = linkage });
50 const __eqdf2 = @import("compiler_rt/compareXf2.zig").__eqdf2;
51 @export(__eqdf2, .{ .name = "__eqdf2", .linkage = linkage });
52
53 const __ltsf2 = @import("compiler_rt/compareXf2.zig").__ltsf2;
54 @export(__ltsf2, .{ .name = "__ltsf2", .linkage = linkage });
55 const __ltdf2 = @import("compiler_rt/compareXf2.zig").__ltdf2;
56 @export(__ltdf2, .{ .name = "__ltdf2", .linkage = linkage });
57
58 const __nesf2 = @import("compiler_rt/compareXf2.zig").__nesf2;
59 @export(__nesf2, .{ .name = "__nesf2", .linkage = linkage });
60 const __nedf2 = @import("compiler_rt/compareXf2.zig").__nedf2;
61 @export(__nedf2, .{ .name = "__nedf2", .linkage = linkage });
62
63 const __gtsf2 = @import("compiler_rt/compareXf2.zig").__gtsf2;
64 @export(__gtsf2, .{ .name = "__gtsf2", .linkage = linkage });
65 const __gtdf2 = @import("compiler_rt/compareXf2.zig").__gtdf2;
66 @export(__gtdf2, .{ .name = "__gtdf2", .linkage = linkage });
67
4868 if (!is_test) {
4969 @export(__lesf2, .{ .name = "__cmpsf2", .linkage = linkage });
5070 @export(__ledf2, .{ .name = "__cmpdf2", .linkage = linkage });
5171 @export(__letf2, .{ .name = "__cmptf2", .linkage = linkage });
52
53 const __eqsf2 = @import("compiler_rt/compareXf2.zig").__eqsf2;
54 @export(__eqsf2, .{ .name = "__eqsf2", .linkage = linkage });
55 const __eqdf2 = @import("compiler_rt/compareXf2.zig").__eqdf2;
56 @export(__eqdf2, .{ .name = "__eqdf2", .linkage = linkage });
5772 @export(__letf2, .{ .name = "__eqtf2", .linkage = linkage });
58
59 const __ltsf2 = @import("compiler_rt/compareXf2.zig").__ltsf2;
60 @export(__ltsf2, .{ .name = "__ltsf2", .linkage = linkage });
61 const __ltdf2 = @import("compiler_rt/compareXf2.zig").__ltdf2;
62 @export(__ltdf2, .{ .name = "__ltdf2", .linkage = linkage });
6373 @export(__letf2, .{ .name = "__lttf2", .linkage = linkage });
64
65 const __nesf2 = @import("compiler_rt/compareXf2.zig").__nesf2;
66 @export(__nesf2, .{ .name = "__nesf2", .linkage = linkage });
67 const __nedf2 = @import("compiler_rt/compareXf2.zig").__nedf2;
68 @export(__nedf2, .{ .name = "__nedf2", .linkage = linkage });
69 @export(__letf2, .{ .name = "__netf2", .linkage = linkage });
70
71 const __gtsf2 = @import("compiler_rt/compareXf2.zig").__gtsf2;
72 @export(__gtsf2, .{ .name = "__gtsf2", .linkage = linkage });
73 const __gtdf2 = @import("compiler_rt/compareXf2.zig").__gtdf2;
74 @export(__gtdf2, .{ .name = "__gtdf2", .linkage = linkage });
7574 @export(__getf2, .{ .name = "__gttf2", .linkage = linkage });
76
75 @export(__letf2, .{ .name = "__netf2", .linkage = linkage });
7776 @export(__extendhfsf2, .{ .name = "__gnu_h2f_ieee", .linkage = linkage });
78
79 // Integral arithmetic which returns if overflow
80 const __mulosi4 = @import("compiler_rt/mulo.zig").__mulosi4;
81 @export(__mulosi4, .{ .name = "__mulosi4", .linkage = linkage });
82 const __mulodi4 = @import("compiler_rt/mulo.zig").__mulodi4;
83 @export(__mulodi4, .{ .name = "__mulodi4", .linkage = linkage });
84 const __muloti4 = @import("compiler_rt/mulo.zig").__muloti4;
85 @export(__muloti4, .{ .name = "__muloti4", .linkage = linkage });
8677 }
8778
79 // Integral arithmetic which returns if overflow
80 const __mulosi4 = @import("compiler_rt/mulo.zig").__mulosi4;
81 @export(__mulosi4, .{ .name = "__mulosi4", .linkage = linkage });
82 const __mulodi4 = @import("compiler_rt/mulo.zig").__mulodi4;
83 @export(__mulodi4, .{ .name = "__mulodi4", .linkage = linkage });
84 const __muloti4 = @import("compiler_rt/mulo.zig").__muloti4;
85 @export(__muloti4, .{ .name = "__muloti4", .linkage = linkage });
86
8887 if (builtin.os.tag == .windows) {
8988 // Default stack-probe functions emitted by LLVM
9089 if (is_mingw) {
lib/std/special/compiler_rt/mulo.zig+47-45
......@@ -7,60 +7,62 @@ const builtin = @import("builtin");
77// return if a*b overflows => 1 else => 0
88// see https://stackoverflow.com/a/26320664 for possible implementations
99
10fn muloXi4_generic(comptime ST: type) fn (a: ST, b: ST, overflow: *c_int) callconv(.C) ST {
11 return struct {
12 fn f(a: ST, b: ST, overflow: *c_int) callconv(.C) ST {
13 @setRuntimeSafety(builtin.is_test);
14 const BSIZE = @bitSizeOf(ST);
15 comptime var UT = switch (ST) {
16 i32 => u32,
17 i64 => u64,
18 i128 => u128,
19 else => unreachable,
20 };
21 const min = @bitCast(ST, @as(UT, 1 << (BSIZE - 1)));
22 const max = ~min;
23 overflow.* = 0;
24 const result = a *% b;
10inline fn muloXi4_generic(comptime ST: type, a: ST, b: ST, overflow: *c_int) ST {
11 @setRuntimeSafety(builtin.is_test);
12 const BSIZE = @bitSizeOf(ST);
13 comptime var UT = switch (ST) {
14 i32 => u32,
15 i64 => u64,
16 i128 => u128,
17 else => unreachable,
18 };
19 const min = @bitCast(ST, @as(UT, 1 << (BSIZE - 1)));
20 const max = ~min;
21 overflow.* = 0;
22 const result = a *% b;
2523
26 // edge cases
27 if (a == min) {
28 if (b != 0 and b != 1) overflow.* = 1;
29 return result;
30 }
31 if (b == min) {
32 if (a != 0 and a != 1) overflow.* = 1;
33 return result;
34 }
24 // edge cases
25 if (a == min) {
26 if (b != 0 and b != 1) overflow.* = 1;
27 return result;
28 }
29 if (b == min) {
30 if (a != 0 and a != 1) overflow.* = 1;
31 return result;
32 }
3533
36 // take sign of x sx
37 const sa = a >> (BSIZE - 1);
38 const sb = b >> (BSIZE - 1);
39 // take absolute value of a and b via
40 // abs(x) = (x^sx)) - sx
41 const abs_a = (a ^ sa) -% sa;
42 const abs_b = (b ^ sb) -% sb;
34 // take sign of x sx
35 const sa = a >> (BSIZE - 1);
36 const sb = b >> (BSIZE - 1);
37 // take absolute value of a and b via
38 // abs(x) = (x^sx)) - sx
39 const abs_a = (a ^ sa) -% sa;
40 const abs_b = (b ^ sb) -% sb;
4341
44 // unitary magnitude, cannot have overflow
45 if (abs_a < 2 or abs_b < 2) return result;
42 // unitary magnitude, cannot have overflow
43 if (abs_a < 2 or abs_b < 2) return result;
4644
47 // compare the signs of operands
48 if ((a ^ b) >> (BSIZE - 1) != 0) {
49 if (abs_a > @divTrunc(max, abs_b)) overflow.* = 1;
50 } else {
51 if (abs_a > @divTrunc(min, -abs_b)) overflow.* = 1;
52 }
45 // compare the signs of operands
46 if ((a ^ b) >> (BSIZE - 1) != 0) {
47 if (abs_a > @divTrunc(max, abs_b)) overflow.* = 1;
48 } else {
49 if (abs_a > @divTrunc(min, -abs_b)) overflow.* = 1;
50 }
5351
54 return result;
55 }
56 }.f;
52 return result;
5753}
5854
59pub const __mulosi4 = muloXi4_generic(i32);
55pub fn __mulosi4(a: i32, b: i32, overflow: *c_int) callconv(.C) i32 {
56 return muloXi4_generic(i32, a, b, overflow);
57}
6058
61pub const __mulodi4 = muloXi4_generic(i64);
59pub fn __mulodi4(a: i64, b: i64, overflow: *c_int) callconv(.C) i64 {
60 return muloXi4_generic(i64, a, b, overflow);
61}
6262
63pub const __muloti4 = muloXi4_generic(i128);
63pub fn __muloti4(a: i128, b: i128, overflow: *c_int) callconv(.C) i128 {
64 return muloXi4_generic(i128, a, b, overflow);
65}
6466
6567test {
6668 _ = @import("mulosi4_test.zig");