authorgravatar for rpkak@noreply.codeberg.orgrpkak <rpkak@noreply.codeberg.org> 2026-04-07 12:10:27+02:00
committergravatar for rpkak@noreply.codeberg.orgrpkak <rpkak@noreply.codeberg.org> 2026-04-16 07:05:30+02:00
loge74b98227eee5eef1c3a7cded0f8fff147178864
treedc34e32102a9baccebb75139d8195f768d134e06
parent0dd99c37cca1894ad7219e5944e7eef25902e44e
signaturebadge-check Signed by SSH key SHA256:A2g6ATENrgLKQcUdthsn72P0njmQxnHSimzwnyJsZzo

zigc: long double: call double function if long double and double are equivalent

For some of these functions and most targets this changes nothing, either because long double and double are not equivalent or because llvm did function deduplication. But e.g. on aarch64-windows-gnu, ucrt provides hypot, but not hypotl. Now hypotl calls hypot from ucrt instead of including the std.math.hypot implementation in zigc. Very trivial functions (like nanl) are not changed, because a function call would probably make this function more complex.

2 files changed, 36 insertions(+), 17 deletions(-)

lib/c/math.zig+28-17
......@@ -116,13 +116,9 @@ fn atanf(x: f32) callconv(.c) f32 {
116116}
117117
118118fn atanl(x: c_longdouble) callconv(.c) c_longdouble {
119 return switch (@typeInfo(@TypeOf(x)).float.bits) {
120 16 => math.atan(@as(f16, @floatCast(x))),
121 32 => math.atan(@as(f32, @floatCast(x))),
122 64 => math.atan(@as(f64, @floatCast(x))),
123 80 => math.atan(@as(f80, @floatCast(x))),
124 128 => math.atan(@as(f128, @floatCast(x))),
125 else => unreachable,
119 return switch (@typeInfo(c_longdouble).float.bits) {
120 64 => std.c.atan(x),
121 else => math.atan(x),
126122 };
127123}
128124
......@@ -143,7 +139,10 @@ fn copysignf(x: f32, y: f32) callconv(.c) f32 {
143139}
144140
145141fn copysignl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble {
146 return math.copysign(x, y);
142 return switch (@typeInfo(c_longdouble).float.bits) {
143 64 => std.c.copysign(x, y),
144 else => math.copysign(x, y),
145 };
147146}
148147
149148fn cosh(x: f64) callconv(.c) f64 {
......@@ -183,15 +182,18 @@ fn fdimf(x: f32, y: f32) callconv(.c) f32 {
183182}
184183
185184fn fdiml(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble {
186 return fdimGeneric(c_longdouble, x, y);
185 return switch (@typeInfo(c_longdouble).float.bits) {
186 64 => std.c.fdim(x, y),
187 else => fdimGeneric(c_longdouble, x, y),
188 };
187189}
188190
189191fn finite(x: f64) callconv(.c) c_int {
190 return if (math.isFinite(x)) 1 else 0;
192 return @intFromBool(math.isFinite(x));
191193}
192194
193195fn finitef(x: f32) callconv(.c) c_int {
194 return if (math.isFinite(x)) 1 else 0;
196 return @intFromBool(math.isFinite(x));
195197}
196198
197199fn frexpGeneric(comptime T: type, x: T, e: *c_int) T {
......@@ -222,7 +224,10 @@ fn frexpf(x: f32, e: *c_int) callconv(.c) f32 {
222224}
223225
224226fn frexpl(x: c_longdouble, e: *c_int) callconv(.c) c_longdouble {
225 return frexpGeneric(c_longdouble, x, e);
227 return switch (@typeInfo(c_longdouble).float.bits) {
228 64 => std.c.frexp(x, e),
229 else => frexpGeneric(c_longdouble, x, e),
230 };
226231}
227232
228233fn hypot(x: f64, y: f64) callconv(.c) f64 {
......@@ -234,19 +239,22 @@ fn hypotf(x: f32, y: f32) callconv(.c) f32 {
234239}
235240
236241fn hypotl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble {
237 return math.hypot(x, y);
242 return switch (@typeInfo(c_longdouble).float.bits) {
243 64 => std.c.hypot(x, y),
244 else => math.hypot(x, y),
245 };
238246}
239247
240248fn isnan(x: f64) callconv(.c) c_int {
241 return if (math.isNan(x)) 1 else 0;
249 return @intFromBool(math.isNan(x));
242250}
243251
244252fn isnanf(x: f32) callconv(.c) c_int {
245 return if (math.isNan(x)) 1 else 0;
253 return @intFromBool(math.isNan(x));
246254}
247255
248256fn isnanl(x: c_longdouble) callconv(.c) c_int {
249 return if (math.isNan(x)) 1 else 0;
257 return @intFromBool(math.isNan(x));
250258}
251259
252260fn lrint(x: f64) callconv(.c) c_long {
......@@ -290,7 +298,10 @@ fn modff(x: f32, iptr: *f32) callconv(.c) f32 {
290298}
291299
292300fn modfl(x: c_longdouble, iptr: *c_longdouble) callconv(.c) c_longdouble {
293 return modfGeneric(c_longdouble, x, iptr);
301 return switch (@typeInfo(c_longdouble).float.bits) {
302 64 => std.c.modf(x, iptr),
303 else => modfGeneric(c_longdouble, x, iptr),
304 };
294305}
295306
296307fn testModf(comptime T: type) !void {
lib/std/c.zig+8
......@@ -11102,6 +11102,14 @@ pub const ioctl = switch (native_os) {
1110211102 else => private.ioctl,
1110311103};
1110411104
11105// Math
11106pub extern "c" fn atan(x: f64) callconv(.c) f64;
11107pub extern "c" fn copysign(x: f64, y: f64) callconv(.c) f64;
11108pub extern "c" fn fdim(x: f64, y: f64) callconv(.c) f64;
11109pub extern "c" fn frexp(x: f64, e: *c_int) callconv(.c) f64;
11110pub extern "c" fn hypot(x: f64, y: f64) callconv(.c) f64;
11111pub extern "c" fn modf(x: f64, iptr: *f64) callconv(.c) f64;
11112
1110511113// OS-specific bits. These are protected from being used on the wrong OS by
1110611114// comptime assertions inside each OS-specific file.
1110711115