diff --git a/lib/compiler_rt.zig b/lib/compiler_rt.zig index 2ed0bdc5205eb7148142dc2163bb86b80582f6c5..fdf594070246a85bb1838c239c912c3c0a788246 100644 --- a/lib/compiler_rt.zig +++ b/lib/compiler_rt.zig @@ -724,25 +724,25 @@ comptime { @export(_aullrem, .{ .name = "\x01__aullrem", .linkage = strong_linkage }); } - mathExport("ceil", @import("./compiler_rt/ceil.zig"), false); - mathExport("cos", @import("./compiler_rt/cos.zig"), true); - mathExport("exp", @import("./compiler_rt/exp.zig"), true); - mathExport("exp2", @import("./compiler_rt/exp2.zig"), true); - mathExport("fabs", @import("./compiler_rt/fabs.zig"), true); - mathExport("floor", @import("./compiler_rt/floor.zig"), false); - mathExport("fma", @import("./compiler_rt/fma.zig"), true); - mathExport("fmax", @import("./compiler_rt/fmax.zig"), true); - mathExport("fmin", @import("./compiler_rt/fmin.zig"), true); - mathExport("fmod", @import("./compiler_rt/fmod.zig"), true); - mathExport("log", @import("./compiler_rt/log.zig"), true); - mathExport("log10", @import("./compiler_rt/log10.zig"), false); - mathExport("log2", @import("./compiler_rt/log2.zig"), true); - mathExport("round", @import("./compiler_rt/round.zig"), true); - mathExport("sin", @import("./compiler_rt/sin.zig"), true); - mathExport("sincos", @import("./compiler_rt/sincos.zig"), true); - mathExport("sqrt", @import("./compiler_rt/sqrt.zig"), true); - mathExport("tan", @import("./compiler_rt/tan.zig"), true); - mathExport("trunc", @import("./compiler_rt/trunc.zig"), true); + 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 @@ -825,7 +825,7 @@ comptime { } } -inline fn mathExport(double_name: []const u8, comptime import: type, win_libc_has_it: bool) void { +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"; @@ -853,9 +853,12 @@ inline fn mathExport(double_name: []const u8, comptime import: type, win_libc_ha .{ f128, quad_fn }, }; - // Weak aliases don't work on Windows, so we avoid exporting the `l` alias - // on this platform for functions we know will collide. - if (builtin.os.tag != .windows or !builtin.link_libc or !win_libc_has_it) { + 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]; diff --git a/lib/compiler_rt/ceil.zig b/lib/compiler_rt/ceil.zig index c7087a2c3a7e200f70ede4bcabfdd2e9853c2b85..06020ea8f8b3c2cffd817058b56b7fded2aad059 100644 --- a/lib/compiler_rt/ceil.zig +++ b/lib/compiler_rt/ceil.zig @@ -111,6 +111,17 @@ pub fn ceilq(x: f128) callconv(.C) f128 { } } +pub fn ceill(x: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __ceilh(x), + 32 => return ceilf(x), + 64 => return ceil(x), + 80 => return __ceilx(x), + 128 => return ceilq(x), + else => @compileError("unreachable"), + } +} + test "ceil32" { try expect(ceilf(1.3) == 2.0); try expect(ceilf(-1.3) == -1.0); diff --git a/lib/compiler_rt/cos.zig b/lib/compiler_rt/cos.zig index 957e5f9c91be8c4d670c5b6443092a9b8cdb4282..e01f458243b580ede5d0e8ff2dbed23c0515d6f2 100644 --- a/lib/compiler_rt/cos.zig +++ b/lib/compiler_rt/cos.zig @@ -107,6 +107,17 @@ pub fn cosq(a: f128) callconv(.C) f128 { return cos(@floatCast(f64, a)); } +pub fn cosl(x: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __cosh(x), + 32 => return cosf(x), + 64 => return cos(x), + 80 => return __cosx(x), + 128 => return cosq(x), + else => @compileError("unreachable"), + } +} + test "cos32" { const epsilon = 0.00001; diff --git a/lib/compiler_rt/exp.zig b/lib/compiler_rt/exp.zig index 0f129dfd4cf0cc88c5fc53bc10dacbfbab85675d..a2c5d0e5502fbb7eb9cba81a6f96136efc5bfc8b 100644 --- a/lib/compiler_rt/exp.zig +++ b/lib/compiler_rt/exp.zig @@ -182,6 +182,17 @@ pub fn expq(a: f128) callconv(.C) f128 { return exp(@floatCast(f64, a)); } +pub fn expl(x: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __exph(x), + 32 => return expf(x), + 64 => return exp(x), + 80 => return __expx(x), + 128 => return expq(x), + else => @compileError("unreachable"), + } +} + test "exp32" { const epsilon = 0.000001; diff --git a/lib/compiler_rt/exp2.zig b/lib/compiler_rt/exp2.zig index 53432a831d1326ae042082ce55acfb6d703c14c2..cbcb53c99f227fa80b4113cd27aa390ac6e4985d 100644 --- a/lib/compiler_rt/exp2.zig +++ b/lib/compiler_rt/exp2.zig @@ -149,6 +149,17 @@ pub fn exp2q(x: f128) callconv(.C) f128 { return exp2(@floatCast(f64, x)); } +pub fn exp2l(x: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __exp2h(x), + 32 => return exp2f(x), + 64 => return exp2(x), + 80 => return __exp2x(x), + 128 => return exp2q(x), + else => @compileError("unreachable"), + } +} + const exp2ft = [_]f64{ 0x1.6a09e667f3bcdp-1, 0x1.7a11473eb0187p-1, diff --git a/lib/compiler_rt/fabs.zig b/lib/compiler_rt/fabs.zig index fbef81fc9a4d18bf7b04bbdb8b30545930a7dcdd..396fdd46b7334f95ac9e6fe78b141bb29506a55d 100644 --- a/lib/compiler_rt/fabs.zig +++ b/lib/compiler_rt/fabs.zig @@ -20,6 +20,17 @@ pub fn fabsq(a: f128) callconv(.C) f128 { return generic_fabs(a); } +pub fn fabsl(x: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __fabsh(x), + 32 => return fabsf(x), + 64 => return fabs(x), + 80 => return __fabsx(x), + 128 => return fabsq(x), + else => @compileError("unreachable"), + } +} + inline fn generic_fabs(x: anytype) @TypeOf(x) { const T = @TypeOf(x); const TBits = std.meta.Int(.unsigned, @typeInfo(T).Float.bits); diff --git a/lib/compiler_rt/floor.zig b/lib/compiler_rt/floor.zig index f6df164b58cd8d1470cc830f934b864716ac5c10..783898fca7df7eec29c2af99d28a93ba0db8c8d6 100644 --- a/lib/compiler_rt/floor.zig +++ b/lib/compiler_rt/floor.zig @@ -141,6 +141,17 @@ pub fn floorq(x: f128) callconv(.C) f128 { } } +pub fn floorl(x: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __floorh(x), + 32 => return floorf(x), + 64 => return floor(x), + 80 => return __floorx(x), + 128 => return floorq(x), + else => @compileError("unreachable"), + } +} + test "floor16" { try expect(__floorh(1.3) == 1.0); try expect(__floorh(-1.3) == -2.0); diff --git a/lib/compiler_rt/fma.zig b/lib/compiler_rt/fma.zig index 4c603bf09570ce5c89406ccfbad6f3b261274c0d..7a39a4c9a00e28b59ecb9f8a50b8d713950f674c 100644 --- a/lib/compiler_rt/fma.zig +++ b/lib/compiler_rt/fma.zig @@ -135,6 +135,17 @@ pub fn fmaq(x: f128, y: f128, z: f128) callconv(.C) f128 { } } +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), + 32 => return fmaf(x, y, z), + 64 => return fma(x, y, z), + 80 => return __fmax(x, y, z), + 128 => return fmaq(x, y, z), + else => @compileError("unreachable"), + } +} + const dd = struct { hi: f64, lo: f64, diff --git a/lib/compiler_rt/fmax.zig b/lib/compiler_rt/fmax.zig index a5bd68cd7428cd175b747a21761e62fc8e69f60b..defc935afcfc2a39bf935ab8c86220f9e8b5984f 100644 --- a/lib/compiler_rt/fmax.zig +++ b/lib/compiler_rt/fmax.zig @@ -21,6 +21,17 @@ pub fn fmaxq(x: f128, y: f128) callconv(.C) f128 { return generic_fmax(f128, 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), + 32 => return fmaxf(x, y), + 64 => return fmax(x, y), + 80 => return __fmaxx(x, y), + 128 => return fmaxq(x, y), + else => @compileError("unreachable"), + } +} + inline fn generic_fmax(comptime T: type, x: T, y: T) T { if (math.isNan(x)) return y; diff --git a/lib/compiler_rt/fmin.zig b/lib/compiler_rt/fmin.zig index cc4dbf082bc7c17d100d4f7ee0d4830c3b8dce9d..e93300bd4b527d0c3437285276fa897c122d9d1d 100644 --- a/lib/compiler_rt/fmin.zig +++ b/lib/compiler_rt/fmin.zig @@ -21,6 +21,17 @@ pub fn fminq(x: f128, y: f128) callconv(.C) f128 { return generic_fmin(f128, 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), + 32 => return fminf(x, y), + 64 => return fmin(x, y), + 80 => return __fminx(x, y), + 128 => return fminq(x, y), + else => @compileError("unreachable"), + } +} + inline fn generic_fmin(comptime T: type, x: T, y: T) T { if (math.isNan(x)) return y; diff --git a/lib/compiler_rt/fmod.zig b/lib/compiler_rt/fmod.zig index 28e0df3d6b4301459226b8091e8180e17ed9b666..5d413ca37d8333844267b83bb9d73982d6212fc1 100644 --- a/lib/compiler_rt/fmod.zig +++ b/lib/compiler_rt/fmod.zig @@ -237,6 +237,17 @@ pub fn fmodq(a: f128, b: f128) callconv(.C) f128 { return amod; } +pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __fmodh(a, b), + 32 => return fmodf(a, b), + 64 => return fmod(a, b), + 80 => return __fmodx(a, b), + 128 => return fmodq(a, b), + else => @compileError("unreachable"), + } +} + inline fn generic_fmod(comptime T: type, x: T, y: T) T { @setRuntimeSafety(false); diff --git a/lib/compiler_rt/log.zig b/lib/compiler_rt/log.zig index 8b09baac2ef6a1ea39455ad5d1c98c9c1b310fe0..6e705dae609bec8d55cf9ea97ce1bcef7a2899d3 100644 --- a/lib/compiler_rt/log.zig +++ b/lib/compiler_rt/log.zig @@ -131,6 +131,17 @@ pub fn logq(a: f128) callconv(.C) f128 { return log(@floatCast(f64, a)); } +pub fn logl(x: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __logh(x), + 32 => return logf(x), + 64 => return log(x), + 80 => return __logx(x), + 128 => return logq(x), + else => @compileError("unreachable"), + } +} + test "ln32" { const epsilon = 0.000001; diff --git a/lib/compiler_rt/log10.zig b/lib/compiler_rt/log10.zig index ce06d8c6493bf19eaeb5eb8a9e2bef2f865884fe..47499d27398525295351ed9211be56acbe6610c7 100644 --- a/lib/compiler_rt/log10.zig +++ b/lib/compiler_rt/log10.zig @@ -159,6 +159,17 @@ pub fn log10q(a: f128) callconv(.C) f128 { return log10(@floatCast(f64, a)); } +pub fn log10l(x: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __log10h(x), + 32 => return log10f(x), + 64 => return log10(x), + 80 => return __log10x(x), + 128 => return log10q(x), + else => @compileError("unreachable"), + } +} + test "log10_32" { const epsilon = 0.000001; diff --git a/lib/compiler_rt/log2.zig b/lib/compiler_rt/log2.zig index 2c2d620c3dafce36bd03d7afc2b907f1b5d73b49..53f35c9a80c4e82aadf9f8232d3d00b384de73e1 100644 --- a/lib/compiler_rt/log2.zig +++ b/lib/compiler_rt/log2.zig @@ -150,6 +150,17 @@ pub fn log2q(a: f128) callconv(.C) f128 { return math.log2(a); } +pub fn log2l(x: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __log2h(x), + 32 => return log2f(x), + 64 => return log2(x), + 80 => return __log2x(x), + 128 => return log2q(x), + else => @compileError("unreachable"), + } +} + test "log2_32" { const epsilon = 0.000001; diff --git a/lib/compiler_rt/round.zig b/lib/compiler_rt/round.zig index 99201efcf89a9e6025130d75b0659917aea8d5ab..4f3266e00ca575d11646afc65f112baf251c3cff 100644 --- a/lib/compiler_rt/round.zig +++ b/lib/compiler_rt/round.zig @@ -123,6 +123,17 @@ pub fn roundq(x_: f128) callconv(.C) f128 { } } +pub fn roundl(x: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __roundh(x), + 32 => return roundf(x), + 64 => return round(x), + 80 => return __roundx(x), + 128 => return roundq(x), + else => @compileError("unreachable"), + } +} + test "round32" { try expect(roundf(1.3) == 1.0); try expect(roundf(-1.3) == -1.0); diff --git a/lib/compiler_rt/sin.zig b/lib/compiler_rt/sin.zig index 3d5572a59f82e76256b35312238c081414b73300..20259bc309023ef987e581fd443473c4739c206f 100644 --- a/lib/compiler_rt/sin.zig +++ b/lib/compiler_rt/sin.zig @@ -111,6 +111,17 @@ pub fn sinq(x: f128) callconv(.C) f128 { return sin(@floatCast(f64, x)); } +pub fn sinl(x: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __sinh(x), + 32 => return sinf(x), + 64 => return sin(x), + 80 => return __sinx(x), + 128 => return sinq(x), + else => @compileError("unreachable"), + } +} + test "sin32" { const epsilon = 0.00001; diff --git a/lib/compiler_rt/sincos.zig b/lib/compiler_rt/sincos.zig index 31ebd0d1d0a88b81d8759eddfaa67c68ff578557..8bc5b83ee5aa4a1f3cc960073c5051ca31673905 100644 --- a/lib/compiler_rt/sincos.zig +++ b/lib/compiler_rt/sincos.zig @@ -181,6 +181,17 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.C) void { r_cos.* = small_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), + 32 => return sincosf(x, r_sin, r_cos), + 64 => return sincos(x, r_sin, r_cos), + 80 => return __sincosx(x, r_sin, r_cos), + 128 => return sincosq(x, r_sin, r_cos), + else => @compileError("unreachable"), + } +} + const rem_pio2_generic = @compileError("TODO"); /// Ported from musl sincosl.c. Needs the following dependencies to be complete: diff --git a/lib/compiler_rt/sqrt.zig b/lib/compiler_rt/sqrt.zig index ba07beb86efaa008c7c695eafbaa077a7b8d6601..8d43949f9920e678389d5620fb95dcf11f504c83 100644 --- a/lib/compiler_rt/sqrt.zig +++ b/lib/compiler_rt/sqrt.zig @@ -225,6 +225,17 @@ pub fn sqrtq(x: f128) callconv(.C) f128 { return sqrt(@floatCast(f64, x)); } +pub fn sqrtl(x: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __sqrth(x), + 32 => return sqrtf(x), + 64 => return sqrt(x), + 80 => return __sqrtx(x), + 128 => return sqrtq(x), + else => @compileError("unreachable"), + } +} + test "sqrtf" { const V = [_]f32{ 0.0, diff --git a/lib/compiler_rt/tan.zig b/lib/compiler_rt/tan.zig index d99f00b99e87b9832f0bba4252e484d2cedac6d3..d37022d91804d26b0da12b5a079ecd6fd68e0897 100644 --- a/lib/compiler_rt/tan.zig +++ b/lib/compiler_rt/tan.zig @@ -96,6 +96,17 @@ pub fn tanq(x: f128) callconv(.C) f128 { return tan(@floatCast(f64, x)); } +pub fn tanl(x: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __tanh(x), + 32 => return tanf(x), + 64 => return tan(x), + 80 => return __tanx(x), + 128 => return tanq(x), + else => @compileError("unreachable"), + } +} + test "tan" { try expect(tan(@as(f32, 0.0)) == tanf(0.0)); try expect(tan(@as(f64, 0.0)) == tan(0.0)); diff --git a/lib/compiler_rt/trunc.zig b/lib/compiler_rt/trunc.zig index 5406f9a02d4dafee31eb224aa0bb070d5a9f45dd..d00df60d99d8c7f16a2d99604d80c1de39b0d7e8 100644 --- a/lib/compiler_rt/trunc.zig +++ b/lib/compiler_rt/trunc.zig @@ -81,6 +81,17 @@ pub fn truncq(x: f128) callconv(.C) f128 { } } +pub fn truncl(x: c_longdouble) callconv(.C) c_longdouble { + switch (@typeInfo(c_longdouble).Float.bits) { + 16 => return __trunch(x), + 32 => return truncf(x), + 64 => return trunc(x), + 80 => return __truncx(x), + 128 => return truncq(x), + else => @compileError("unreachable"), + } +} + test "trunc32" { try expect(truncf(1.3) == 1.0); try expect(truncf(-1.3) == -1.0);