commit f1b255402377b41e47cec65b4dbc2633e1dd7b83 (tree)
parent fb18f2096aaff3a26c309da635472a2fb8b303cd
Author: Pivok <pivoc@protonmail.com>
Date: Mon, 9 Feb 2026 07:59:40 +0100
libzigc: hypotf, hypotl (#31150)
Implements hypotf and hypotl for libzigc #30978.
Continuation of #31104
Commands i run:
```
$ stage3/bin/zig build -p stage4 -Denable-llvm -Dno-lib
$ stage4/bin/zig build test-libc -Dlibc-test-path=../../libc-test -Dtest-filter=hypotf -fqemu -fwasmtime --summary line
Build Summary: 365/369 steps succeeded (4 skipped)
$ stage4/bin/zig build test-modules -Dtest-target-filter=windows -Dtest-filter=hypotf --summary line
Build Summary: 53/101 steps succeeded (48 skipped)
```
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31150
Reviewed-by: Andrew Kelley <andrew@ziglang.org>
Co-authored-by: Pivok <pivoc@protonmail.com>
Co-committed-by: Pivok <pivoc@protonmail.com>
Diffstat:
9 files changed, 10 insertions(+), 255 deletions(-)
diff --git a/lib/c/math.zig b/lib/c/math.zig
@@ -29,6 +29,8 @@ comptime {
}
if (builtin.target.isMinGW() or builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
+ @export(&hypotf, .{ .name = "hypotf", .linkage = common.linkage, .visibility = common.visibility });
+ @export(&hypotl, .{ .name = "hypotl", .linkage = common.linkage, .visibility = common.visibility });
@export(&nan, .{ .name = "nan", .linkage = common.linkage, .visibility = common.visibility });
@export(&nanf, .{ .name = "nanf", .linkage = common.linkage, .visibility = common.visibility });
@export(&nanl, .{ .name = "nanl", .linkage = common.linkage, .visibility = common.visibility });
@@ -123,6 +125,14 @@ fn hypot(x: f64, y: f64) callconv(.c) f64 {
return math.hypot(x, y);
}
+fn hypotf(x: f32, y: f32) callconv(.c) f32 {
+ return math.hypot(x, y);
+}
+
+fn hypotl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble {
+ return math.hypot(x, y);
+}
+
fn pow(x: f64, y: f64) callconv(.c) f64 {
return math.pow(f64, x, y);
}
diff --git a/lib/libc/mingw/math/hypotf.c b/lib/libc/mingw/math/hypotf.c
@@ -1,23 +0,0 @@
-/**
- * This file is part of the mingw-w64 runtime package.
- * No warranty is given; refer to the file DISCLAIMER within this package.
- */
-#define _NEW_COMPLEX_FLOAT 1
-
-#include "../complex/complex_internal.h"
-#include <errno.h>
-#include <math.h>
-
-float hypotf (float x, float y)
-{
- int x_class = fpclassify (x);
- int y_class = fpclassify (y);
-
- if (x_class == FP_INFINITE || y_class == FP_INFINITE)
- return __FLT_HUGE_VAL;
- else if (x_class == FP_NAN || y_class == FP_NAN)
- return __FLT_NAN;
-
- return (float) _hypot (x, y);
-}
-
diff --git a/lib/libc/mingw/math/hypotl.c b/lib/libc/mingw/math/hypotl.c
@@ -1,82 +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 <math.h>
-#include <float.h>
-#include <errno.h>
-
-/*
-This implementation is based largely on Cephes library
-function cabsl (cmplxl.c), which bears the following notice:
-
-Cephes Math Library Release 2.1: January, 1989
-Copyright 1984, 1987, 1989 by Stephen L. Moshier
-Direct inquiries to 30 Frost Street, Cambridge, MA 02140
-*/
-
-/*
- Modified for use in libmingwex.a
- 02 Sept 2002 Danny Smith <dannysmith@users.sourceforege.net>
- Calls to ldexpl replaced by logbl and calls to frexpl replaced
- by scalbnl to avoid duplicated range checks.
-*/
-
-#define PRECL 32
-
-long double
-hypotl (long double x, long double y)
-{
- int exx;
- int eyy;
- int scale;
- long double xx =fabsl(x);
- long double yy =fabsl(y);
- if (!isfinite(xx) || !isfinite(yy))
- {
- /* Annex F.9.4.3, hypot returns +infinity if
- either component is an infinity, even when the
- other component is NaN. */
- return (isinf(xx) || isinf(yy)) ? INFINITY : NAN;
- }
-
- if (xx == 0.0L)
- return yy;
- if (yy == 0.0L)
- return xx;
-
- /* Get exponents */
- exx = logbl (xx);
- eyy = logbl (yy);
-
- /* Check if large differences in scale */
- scale = exx - eyy;
- if ( scale > PRECL)
- return xx;
- if ( scale < -PRECL)
- return yy;
-
- /* Exponent of approximate geometric mean (x 2) */
- scale = (exx + eyy) >> 1;
-
- /* Rescale: Geometric mean is now about 2 */
- x = scalbnl(xx, -scale);
- y = scalbnl(yy, -scale);
-
- xx = sqrtl(x * x + y * y);
-
- /* Check for overflow and underflow */
- exx = logbl(xx);
- exx += scale;
- if (exx > LDBL_MAX_EXP)
- {
- errno = ERANGE;
- return INFINITY;
- }
- if (exx < LDBL_MIN_EXP)
- return 0.0L;
-
- /* Undo scaling */
- return (scalbnl (xx, scale));
-}
diff --git a/lib/libc/musl/src/math/hypotf.c b/lib/libc/musl/src/math/hypotf.c
@@ -1,35 +0,0 @@
-#include <math.h>
-#include <stdint.h>
-
-float hypotf(float x, float y)
-{
- union {float f; uint32_t i;} ux = {x}, uy = {y}, ut;
- float_t z;
-
- ux.i &= -1U>>1;
- uy.i &= -1U>>1;
- if (ux.i < uy.i) {
- ut = ux;
- ux = uy;
- uy = ut;
- }
-
- x = ux.f;
- y = uy.f;
- if (uy.i == 0xff<<23)
- return y;
- if (ux.i >= 0xff<<23 || uy.i == 0 || ux.i - uy.i >= 25<<23)
- return x + y;
-
- z = 1;
- if (ux.i >= (0x7f+60)<<23) {
- z = 0x1p90f;
- x *= 0x1p-90f;
- y *= 0x1p-90f;
- } else if (uy.i < (0x7f-60)<<23) {
- z = 0x1p-90f;
- x *= 0x1p90f;
- y *= 0x1p90f;
- }
- return z*sqrtf((double)x*x + (double)y*y);
-}
diff --git a/lib/libc/musl/src/math/hypotl.c b/lib/libc/musl/src/math/hypotl.c
@@ -1,66 +0,0 @@
-#include "libm.h"
-
-#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
-long double hypotl(long double x, long double y)
-{
- return hypot(x, y);
-}
-#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
-#if LDBL_MANT_DIG == 64
-#define SPLIT (0x1p32L+1)
-#elif LDBL_MANT_DIG == 113
-#define SPLIT (0x1p57L+1)
-#endif
-
-static void sq(long double *hi, long double *lo, long double x)
-{
- long double xh, xl, xc;
- xc = x*SPLIT;
- xh = x - xc + xc;
- xl = x - xh;
- *hi = x*x;
- *lo = xh*xh - *hi + 2*xh*xl + xl*xl;
-}
-
-long double hypotl(long double x, long double y)
-{
- union ldshape ux = {x}, uy = {y};
- int ex, ey;
- long double hx, lx, hy, ly, z;
-
- ux.i.se &= 0x7fff;
- uy.i.se &= 0x7fff;
- if (ux.i.se < uy.i.se) {
- ex = uy.i.se;
- ey = ux.i.se;
- x = uy.f;
- y = ux.f;
- } else {
- ex = ux.i.se;
- ey = uy.i.se;
- x = ux.f;
- y = uy.f;
- }
-
- if (ex == 0x7fff && isinf(y))
- return y;
- if (ex == 0x7fff || y == 0)
- return x;
- if (ex - ey > LDBL_MANT_DIG)
- return x + y;
-
- z = 1;
- if (ex > 0x3fff+8000) {
- z = 0x1p10000L;
- x *= 0x1p-10000L;
- y *= 0x1p-10000L;
- } else if (ey < 0x3fff-8000) {
- z = 0x1p-10000L;
- x *= 0x1p10000L;
- y *= 0x1p10000L;
- }
- sq(&hx, &lx, x);
- sq(&hy, &ly, y);
- return z*sqrtl(ly+lx+hy+hx);
-}
-#endif
diff --git a/lib/libc/musl/src/math/i386/hypotf.s b/lib/libc/musl/src/math/i386/hypotf.s
@@ -1,42 +0,0 @@
-.global hypotf
-.type hypotf,@function
-hypotf:
- mov 4(%esp),%eax
- mov 8(%esp),%ecx
- add %eax,%eax
- add %ecx,%ecx
- and %eax,%ecx
- cmp $0xff000000,%ecx
- jae 2f
- test %eax,%eax
- jnz 1f
- flds 8(%esp)
- fabs
- ret
-1: mov 8(%esp),%eax
- add %eax,%eax
- jnz 1f
- flds 4(%esp)
- fabs
- ret
-1: flds 4(%esp)
- fld %st(0)
- fmulp
- flds 8(%esp)
- fld %st(0)
- fmulp
- faddp
- fsqrt
- ret
-2: cmp $0xff000000,%eax
- jnz 1f
- flds 4(%esp)
- fabs
- ret
-1: mov 8(%esp),%eax
- add %eax,%eax
- cmp $0xff000000,%eax
- flds 8(%esp)
- jnz 1f
- fabs
-1: ret
diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig
@@ -615,8 +615,6 @@ const mingw32_generic_src = [_][]const u8{
"math" ++ path.sep_str ++ "fpclassifyl.c",
"math" ++ path.sep_str ++ "frexpf.c",
"math" ++ path.sep_str ++ "frexpl.c",
- "math" ++ path.sep_str ++ "hypotf.c",
- "math" ++ path.sep_str ++ "hypotl.c",
"math" ++ path.sep_str ++ "ldexpf.c",
"math" ++ path.sep_str ++ "lgamma.c",
"math" ++ path.sep_str ++ "lgammaf.c",
diff --git a/src/libs/musl.zig b/src/libs/musl.zig
@@ -874,8 +874,6 @@ const src_files = [_][]const u8{
"musl/src/math/frexp.c",
"musl/src/math/frexpf.c",
"musl/src/math/frexpl.c",
- "musl/src/math/hypotf.c",
- "musl/src/math/hypotl.c",
"musl/src/math/i386/acosf.s",
"musl/src/math/i386/acosl.s",
"musl/src/math/i386/asinf.s",
@@ -888,7 +886,6 @@ const src_files = [_][]const u8{
"musl/src/math/i386/exp_ld.s",
"musl/src/math/i386/expl.s",
"musl/src/math/i386/expm1l.s",
- "musl/src/math/i386/hypotf.s",
"musl/src/math/i386/__invtrigl.s",
"musl/src/math/i386/ldexpf.s",
"musl/src/math/i386/ldexpl.s",
diff --git a/src/libs/wasi_libc.zig b/src/libs/wasi_libc.zig
@@ -730,8 +730,6 @@ const libc_top_half_src_files = [_][]const u8{
"musl/src/math/frexp.c",
"musl/src/math/frexpf.c",
"musl/src/math/frexpl.c",
- "musl/src/math/hypotf.c",
- "musl/src/math/hypotl.c",
"musl/src/math/ilogb.c",
"musl/src/math/ilogbf.c",
"musl/src/math/ilogbl.c",