mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
compiler_rt: reorganize in a way that stage2 understands
Before this commit, stage2 behavior tests are regressed; it cannot build compiler-rt.
This commit is contained in:
parent
e45680cab5
commit
3532abe0c6
@ -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) {
|
||||
|
||||
@ -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");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user