From 1f92162875a3f05942dad6696b206cb9a1394f80 Mon Sep 17 00:00:00 2001 From: mihael Date: Mon, 9 Mar 2026 23:17:46 +0100 Subject: [PATCH 1/3] Reimplement `cosh` in `libzigc` The function basically calls the Zig std's implementation. The changes were tested by running: ``` $ ./build/stage3/bin/zig build -p stage4 -Denable-llvm -Dno-lib $ stage4/bin/zig build test-libc -Dlibc-test-path= -Dtest-filter=cosh -fqemu -fwasmtime --summary line Build Summary: 921/921 steps succeeded ``` --- lib/c/math.zig | 5 +++ lib/libc/musl/src/math/cosh.c | 40 ----------------- .../wasi/libc-top-half/musl/src/math/cosh.c | 44 ------------------- src/libs/musl.zig | 1 - src/libs/wasi_libc.zig | 1 - 5 files changed, 5 insertions(+), 86 deletions(-) delete mode 100644 lib/libc/musl/src/math/cosh.c delete mode 100644 lib/libc/wasi/libc-top-half/musl/src/math/cosh.c diff --git a/lib/c/math.zig b/lib/c/math.zig index cce37f9000858b41b08d14a9012f5e607a2b2367..ae3491e430c4cb433ab01430b93193ed732ed14b 100644 --- a/lib/c/math.zig +++ b/lib/c/math.zig @@ -45,6 +45,7 @@ comptime { symbol(&atanl, "atanl"); symbol(&cbrt, "cbrt"); symbol(&cbrtf, "cbrtf"); + symbol(&cosh, "cosh"); symbol(&exp10, "exp10"); symbol(&exp10f, "exp10f"); symbol(&hypot, "hypot"); @@ -125,6 +126,10 @@ fn copysignl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { return math.copysign(x, y); } +fn cosh(x: f64) callconv(.c) f64 { + return math.cosh(x); +} + fn cbrt(x: f64) callconv(.c) f64 { return math.cbrt(x); } diff --git a/lib/libc/musl/src/math/cosh.c b/lib/libc/musl/src/math/cosh.c deleted file mode 100644 index 490c15fb166752d18fa4015401f5a27fd34337b6..0000000000000000000000000000000000000000 --- a/lib/libc/musl/src/math/cosh.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "libm.h" - -/* cosh(x) = (exp(x) + 1/exp(x))/2 - * = 1 + 0.5*(exp(x)-1)*(exp(x)-1)/exp(x) - * = 1 + x*x/2 + o(x^4) - */ -double cosh(double x) -{ - union {double f; uint64_t i;} u = {.f = x}; - uint32_t w; - double t; - - /* |x| */ - u.i &= (uint64_t)-1/2; - x = u.f; - w = u.i >> 32; - - /* |x| < log(2) */ - if (w < 0x3fe62e42) { - if (w < 0x3ff00000 - (26<<20)) { - /* raise inexact if x!=0 */ - FORCE_EVAL(x + 0x1p120f); - return 1; - } - t = expm1(x); - return 1 + t*t/(2*(1+t)); - } - - /* |x| < log(DBL_MAX) */ - if (w < 0x40862e42) { - t = exp(x); - /* note: if x>log(0x1p26) then the 1/t is not needed */ - return 0.5*(t + 1/t); - } - - /* |x| > log(DBL_MAX) or nan */ - /* note: the result is stored to handle overflow */ - t = __expo2(x, 1.0); - return t; -} diff --git a/lib/libc/wasi/libc-top-half/musl/src/math/cosh.c b/lib/libc/wasi/libc-top-half/musl/src/math/cosh.c deleted file mode 100644 index 2cdf0023f8b3725d12c8ec96ba0e6ed30f1d5aae..0000000000000000000000000000000000000000 --- a/lib/libc/wasi/libc-top-half/musl/src/math/cosh.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "libm.h" - -/* cosh(x) = (exp(x) + 1/exp(x))/2 - * = 1 + 0.5*(exp(x)-1)*(exp(x)-1)/exp(x) - * = 1 + x*x/2 + o(x^4) - */ -double cosh(double x) -{ - union {double f; uint64_t i;} u = {.f = x}; - uint32_t w; - double t; - - /* |x| */ - u.i &= (uint64_t)-1/2; - x = u.f; - w = u.i >> 32; - - /* |x| < log(2) */ - if (w < 0x3fe62e42) { - if (w < 0x3ff00000 - (26<<20)) { - /* raise inexact if x!=0 */ - FORCE_EVAL(x + 0x1p120f); - return 1; - } - t = expm1(x); - return 1 + t*t/(2*(1+t)); - } - - /* |x| < log(DBL_MAX) */ - if (w < 0x40862e42) { - t = exp(x); - /* note: if x>log(0x1p26) then the 1/t is not needed */ - return 0.5*(t + 1/t); - } - - /* |x| > log(DBL_MAX) or nan */ - /* note: the result is stored to handle overflow */ -#ifdef __wasilibc_unmodified_upstream // Wasm doesn't have alternate rounding modes - t = __expo2(x, 1.0); -#else - t = __expo2(x); -#endif - return t; -} diff --git a/src/libs/musl.zig b/src/libs/musl.zig index d8f5fe28121d5b1e93507bae4edee26c2456ea57..eb49d4c4f136f9b166f4dc81593d7d2ecc9b8daf 100644 --- a/src/libs/musl.zig +++ b/src/libs/musl.zig @@ -819,7 +819,6 @@ const src_files = [_][]const u8{ "musl/src/math/cbrtl.c", "musl/src/math/__cos.c", "musl/src/math/__cosdf.c", - "musl/src/math/cosh.c", "musl/src/math/coshf.c", "musl/src/math/coshl.c", "musl/src/math/__cosl.c", diff --git a/src/libs/wasi_libc.zig b/src/libs/wasi_libc.zig index 0bdcb724c50c1db7a6253f042d20e0fb4c2e09c9..72b19fe2e6e88e9cb8ead76bd4178248ef1c633c 100644 --- a/src/libs/wasi_libc.zig +++ b/src/libs/wasi_libc.zig @@ -1003,7 +1003,6 @@ const libc_top_half_src_files = [_][]const u8{ "wasi/libc-top-half/musl/src/locale/locale_map.c", "wasi/libc-top-half/musl/src/locale/newlocale.c", "wasi/libc-top-half/musl/src/locale/uselocale.c", - "wasi/libc-top-half/musl/src/math/cosh.c", "wasi/libc-top-half/musl/src/math/coshf.c", "wasi/libc-top-half/musl/src/math/__expo2.c", "wasi/libc-top-half/musl/src/math/__expo2f.c", -- 2.54.0 From 159568a05a222681f54a27310ac15c3043563f95 Mon Sep 17 00:00:00 2001 From: mihael Date: Tue, 10 Mar 2026 00:09:00 +0100 Subject: [PATCH 2/3] Reimplement `coshf` in `libzigc` The function basically calls the Zig std's implementation. The changes were tested by running: ``` $ ./build/stage3/bin/zig build -p stage4 -Denable-llvm -Dno-lib $ stage4/bin/zig build test-libc -Dlibc-test-path= -Dtest-filter=coshf -fqemu -fwasmtime --summary line Build Summary: 553/553 steps succeeded ``` --- lib/c/math.zig | 5 +++ lib/libc/mingw/math/coshf.c | 10 ----- lib/libc/musl/src/math/coshf.c | 33 ----------------- .../wasi/libc-top-half/musl/src/math/coshf.c | 37 ------------------- src/libs/mingw.zig | 1 - src/libs/musl.zig | 1 - src/libs/wasi_libc.zig | 1 - 7 files changed, 5 insertions(+), 83 deletions(-) delete mode 100644 lib/libc/mingw/math/coshf.c delete mode 100644 lib/libc/musl/src/math/coshf.c delete mode 100644 lib/libc/wasi/libc-top-half/musl/src/math/coshf.c diff --git a/lib/c/math.zig b/lib/c/math.zig index ae3491e430c4cb433ab01430b93193ed732ed14b..281b898ac2061cdad1c41a9fe56361ae9724a3f7 100644 --- a/lib/c/math.zig +++ b/lib/c/math.zig @@ -31,6 +31,7 @@ comptime { } if (builtin.target.isMinGW() or builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) { + symbol(&coshf, "coshf"); symbol(&hypotf, "hypotf"); symbol(&hypotl, "hypotl"); symbol(&nan, "nan"); @@ -130,6 +131,10 @@ fn cosh(x: f64) callconv(.c) f64 { return math.cosh(x); } +fn coshf(x: f32) callconv(.c) f32 { + return math.cosh(x); +} + fn cbrt(x: f64) callconv(.c) f64 { return math.cbrt(x); } diff --git a/lib/libc/mingw/math/coshf.c b/lib/libc/mingw/math/coshf.c deleted file mode 100644 index 72147f5bfbcb77fdb2754e876472f33583ae2756..0000000000000000000000000000000000000000 --- a/lib/libc/mingw/math/coshf.c +++ /dev/null @@ -1,10 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -#include -float coshf (float x) -{ - return (float) cosh (x); -} diff --git a/lib/libc/musl/src/math/coshf.c b/lib/libc/musl/src/math/coshf.c deleted file mode 100644 index e739cff93b1325f931198d8d75b3313359803752..0000000000000000000000000000000000000000 --- a/lib/libc/musl/src/math/coshf.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "libm.h" - -float coshf(float x) -{ - union {float f; uint32_t i;} u = {.f = x}; - uint32_t w; - float t; - - /* |x| */ - u.i &= 0x7fffffff; - x = u.f; - w = u.i; - - /* |x| < log(2) */ - if (w < 0x3f317217) { - if (w < 0x3f800000 - (12<<23)) { - FORCE_EVAL(x + 0x1p120f); - return 1; - } - t = expm1f(x); - return 1 + t*t/(2*(1+t)); - } - - /* |x| < log(FLT_MAX) */ - if (w < 0x42b17217) { - t = expf(x); - return 0.5f*(t + 1/t); - } - - /* |x| > log(FLT_MAX) or nan */ - t = __expo2f(x, 1.0f); - return t; -} diff --git a/lib/libc/wasi/libc-top-half/musl/src/math/coshf.c b/lib/libc/wasi/libc-top-half/musl/src/math/coshf.c deleted file mode 100644 index b946c0b068e6292ac99a53d855fb8b3a6f91bef3..0000000000000000000000000000000000000000 --- a/lib/libc/wasi/libc-top-half/musl/src/math/coshf.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "libm.h" - -float coshf(float x) -{ - union {float f; uint32_t i;} u = {.f = x}; - uint32_t w; - float t; - - /* |x| */ - u.i &= 0x7fffffff; - x = u.f; - w = u.i; - - /* |x| < log(2) */ - if (w < 0x3f317217) { - if (w < 0x3f800000 - (12<<23)) { - FORCE_EVAL(x + 0x1p120f); - return 1; - } - t = expm1f(x); - return 1 + t*t/(2*(1+t)); - } - - /* |x| < log(FLT_MAX) */ - if (w < 0x42b17217) { - t = expf(x); - return 0.5f*(t + 1/t); - } - - /* |x| > log(FLT_MAX) or nan */ -#ifdef __wasilibc_unmodified_upstream // Wasm doesn't have alternate rounding modes - t = __expo2f(x, 1.0f); -#else - t = __expo2f(x); -#endif - return t; -} diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index 0be2b7c0a8c4a13faaac25ad2b3d654d8bd23d1e..70e0d6e8c019e760144004437e10f2e42c0123f5 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -977,7 +977,6 @@ const mingw32_x86_src = [_][]const u8{ const mingw32_x86_32_src = [_][]const u8{ // ucrtbase - "math" ++ path.sep_str ++ "coshf.c", "math" ++ path.sep_str ++ "modff.c", "math" ++ path.sep_str ++ "powf.c", "math" ++ path.sep_str ++ "sinhf.c", diff --git a/src/libs/musl.zig b/src/libs/musl.zig index eb49d4c4f136f9b166f4dc81593d7d2ecc9b8daf..482c1a1b29190bac0e48368ab61d77ec196ce157 100644 --- a/src/libs/musl.zig +++ b/src/libs/musl.zig @@ -819,7 +819,6 @@ const src_files = [_][]const u8{ "musl/src/math/cbrtl.c", "musl/src/math/__cos.c", "musl/src/math/__cosdf.c", - "musl/src/math/coshf.c", "musl/src/math/coshl.c", "musl/src/math/__cosl.c", "musl/src/math/cosl.c", diff --git a/src/libs/wasi_libc.zig b/src/libs/wasi_libc.zig index 72b19fe2e6e88e9cb8ead76bd4178248ef1c633c..67c1b0e74c2a54bea0e7948fff34205201f3ce7d 100644 --- a/src/libs/wasi_libc.zig +++ b/src/libs/wasi_libc.zig @@ -1003,7 +1003,6 @@ const libc_top_half_src_files = [_][]const u8{ "wasi/libc-top-half/musl/src/locale/locale_map.c", "wasi/libc-top-half/musl/src/locale/newlocale.c", "wasi/libc-top-half/musl/src/locale/uselocale.c", - "wasi/libc-top-half/musl/src/math/coshf.c", "wasi/libc-top-half/musl/src/math/__expo2.c", "wasi/libc-top-half/musl/src/math/__expo2f.c", "wasi/libc-top-half/musl/src/math/fmal.c", -- 2.54.0 From 4a0be5613b865c345e2b9daade65ee6fbb139e39 Mon Sep 17 00:00:00 2001 From: mihael Date: Tue, 10 Mar 2026 00:40:23 +0100 Subject: [PATCH 3/3] Alphabetically sort functions in `libzigc/math` The functions were sorted alphabetically for easier navigation, and less confusion where to add a new one. The sorting of comptime exports was done within the visual "blocks". --- lib/c/math.zig | 95 +++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/lib/c/math.zig b/lib/c/math.zig index 281b898ac2061cdad1c41a9fe56361ae9724a3f7..501df810d693e43c2330238dca53e50044c4da0f 100644 --- a/lib/c/math.zig +++ b/lib/c/math.zig @@ -14,20 +14,20 @@ comptime { symbol(&isnanl, "isnanl"); symbol(&isnanl, "__isnanl"); + symbol(&math.floatTrueMin(f64), "__DENORM"); + symbol(&math.inf(f64), "__INF"); symbol(&math.nan(f64), "__QNAN"); symbol(&math.snan(f64), "__SNAN"); - symbol(&math.inf(f64), "__INF"); - symbol(&math.floatTrueMin(f64), "__DENORM"); + symbol(&math.floatTrueMin(f32), "__DENORMF"); + symbol(&math.inf(f32), "__INFF"); symbol(&math.nan(f32), "__QNANF"); symbol(&math.snan(f32), "__SNANF"); - symbol(&math.inf(f32), "__INFF"); - symbol(&math.floatTrueMin(f32), "__DENORMF"); + symbol(&math.floatTrueMin(c_longdouble), "__DENORML"); + symbol(&math.inf(c_longdouble), "__INFL"); symbol(&math.nan(c_longdouble), "__QNANL"); symbol(&math.snan(c_longdouble), "__SNANL"); - symbol(&math.inf(c_longdouble), "__INFL"); - symbol(&math.floatTrueMin(c_longdouble), "__DENORML"); } if (builtin.target.isMinGW() or builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) { @@ -41,8 +41,9 @@ comptime { if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) { symbol(&acos, "acos"); - symbol(&atanf, "atanf"); + symbol(&acosf, "acosf"); symbol(&atan, "atan"); + symbol(&atanf, "atanf"); symbol(&atanl, "atanl"); symbol(&cbrt, "cbrt"); symbol(&cbrtf, "cbrtf"); @@ -53,14 +54,14 @@ comptime { symbol(&pow, "pow"); symbol(&pow10, "pow10"); symbol(&pow10f, "pow10f"); - symbol(&acosf, "acosf"); } if (builtin.target.isMuslLibC()) { - symbol(©signf, "copysignf"); symbol(©sign, "copysign"); + symbol(©signf, "copysignf"); symbol(&rint, "rint"); } + symbol(©signl, "copysignl"); } @@ -68,14 +69,18 @@ fn acos(x: f64) callconv(.c) f64 { return math.acos(x); } -fn atanf(x: f32) callconv(.c) f32 { - return math.atan(x); +fn acosf(x: f32) callconv(.c) f32 { + return std.math.acos(x); } fn atan(x: f64) callconv(.c) f64 { return math.atan(x); } +fn atanf(x: f32) callconv(.c) f32 { + return math.atan(x); +} + fn atanl(x: c_longdouble) callconv(.c) c_longdouble { return switch (@typeInfo(@TypeOf(x)).float.bits) { 16 => math.atan(@as(f16, @floatCast(x))), @@ -87,42 +92,22 @@ fn atanl(x: c_longdouble) callconv(.c) c_longdouble { }; } -fn acosf(x: f32) callconv(.c) f32 { - return std.math.acos(x); +fn cbrt(x: f64) callconv(.c) f64 { + return math.cbrt(x); } -fn isnan(x: f64) callconv(.c) c_int { - return if (math.isNan(x)) 1 else 0; -} - -fn isnanf(x: f32) callconv(.c) c_int { - return if (math.isNan(x)) 1 else 0; -} - -fn isnanl(x: c_longdouble) callconv(.c) c_int { - return if (math.isNan(x)) 1 else 0; -} - -fn nan(_: [*:0]const c_char) callconv(.c) f64 { - return math.nan(f64); -} - -fn nanf(_: [*:0]const c_char) callconv(.c) f32 { - return math.nan(f32); -} - -fn nanl(_: [*:0]const c_char) callconv(.c) c_longdouble { - return math.nan(c_longdouble); -} - -fn copysignf(x: f32, y: f32) callconv(.c) f32 { - return math.copysign(x, y); +fn cbrtf(x: f32) callconv(.c) f32 { + return math.cbrt(x); } fn copysign(x: f64, y: f64) callconv(.c) f64 { return math.copysign(x, y); } +fn copysignf(x: f32, y: f32) callconv(.c) f32 { + return math.copysign(x, y); +} + fn copysignl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { return math.copysign(x, y); } @@ -135,14 +120,6 @@ fn coshf(x: f32) callconv(.c) f32 { return math.cosh(x); } -fn cbrt(x: f64) callconv(.c) f64 { - return math.cbrt(x); -} - -fn cbrtf(x: f32) callconv(.c) f32 { - return math.cbrt(x); -} - fn exp10(x: f64) callconv(.c) f64 { return math.pow(f64, 10.0, x); } @@ -163,6 +140,30 @@ fn hypotl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { return math.hypot(x, y); } +fn isnan(x: f64) callconv(.c) c_int { + return if (math.isNan(x)) 1 else 0; +} + +fn isnanf(x: f32) callconv(.c) c_int { + return if (math.isNan(x)) 1 else 0; +} + +fn isnanl(x: c_longdouble) callconv(.c) c_int { + return if (math.isNan(x)) 1 else 0; +} + +fn nan(_: [*:0]const c_char) callconv(.c) f64 { + return math.nan(f64); +} + +fn nanf(_: [*:0]const c_char) callconv(.c) f32 { + return math.nan(f32); +} + +fn nanl(_: [*:0]const c_char) callconv(.c) c_longdouble { + return math.nan(c_longdouble); +} + fn pow(x: f64, y: f64) callconv(.c) f64 { return math.pow(f64, x, y); } -- 2.54.0