| author | |
| committer | |
| log | db1e649575a741527ca0fd7815515c2f97924410 |
| tree | c72f39e4b7cb178fc80bf1b67d6eb7f4f4c90787 |
| parent | 521a093334eb92b4fd2430b9018ed94b912857a8 |
| signature |
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=<LIBC-TEST-PATH> -Dtest-filter=frexpl -fqemu -fwasmtime --summary line
Build Summary: 369/369 steps succeeded
```6 files changed, 5 insertions(+), 103 deletions(-)
lib/c/math.zig+5| ... | ... | @@ -37,6 +37,7 @@ comptime { |
| 37 | 37 | if (builtin.target.isMinGW() or builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) { |
| 38 | 38 | symbol(&coshf, "coshf"); |
| 39 | 39 | symbol(&frexpf, "frexpf"); |
| 40 | symbol(&frexpl, "frexpl"); | |
| 40 | 41 | symbol(&hypotf, "hypotf"); |
| 41 | 42 | symbol(&hypotl, "hypotl"); |
| 42 | 43 | symbol(&modff, "modff"); |
| ... | ... | @@ -190,6 +191,10 @@ fn frexpf(x: f32, e: *c_int) callconv(.c) f32 { |
| 190 | 191 | return frexpGeneric(f32, x, e); |
| 191 | 192 | } |
| 192 | 193 | |
| 194 | fn frexpl(x: c_longdouble, e: *c_int) callconv(.c) c_longdouble { | |
| 195 | return frexpGeneric(c_longdouble, x, e); | |
| 196 | } | |
| 197 | ||
| 193 | 198 | fn hypot(x: f64, y: f64) callconv(.c) f64 { |
| 194 | 199 | return math.hypot(x, y); |
| 195 | 200 | } |
lib/libc/mingw/math/frexpl.c deleted-71| ... | ... | @@ -1,71 +0,0 @@ |
| 1 | /** | |
| 2 | * This file has no copyright assigned and is placed in the Public Domain. | |
| 3 | * This file is part of the mingw-w64 runtime package. | |
| 4 | * No warranty is given; refer to the file DISCLAIMER.PD within this package. | |
| 5 | */ | |
| 6 | long double frexpl(long double value, int* exp); | |
| 7 | ||
| 8 | #if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ | |
| 9 | ||
| 10 | double frexp(double value, int* exp); | |
| 11 | ||
| 12 | /* On ARM `long double` is 64 bits. */ | |
| 13 | long double frexpl(long double value, int* exp) | |
| 14 | { | |
| 15 | return frexp(value, exp); | |
| 16 | } | |
| 17 | ||
| 18 | #elif defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(__i386__) | |
| 19 | ||
| 20 | #include <stdint.h> | |
| 21 | ||
| 22 | /* https://en.wikipedia.org/wiki/Extended_precision#x86_extended_precision_format */ | |
| 23 | typedef union x87reg_ { | |
| 24 | struct __attribute__((__packed__)) { | |
| 25 | uint64_t f64; | |
| 26 | uint16_t exp : 15; | |
| 27 | uint16_t sgn : 1; | |
| 28 | }; | |
| 29 | long double f; | |
| 30 | } x87reg; | |
| 31 | ||
| 32 | long double frexpl(long double value, int* exp) | |
| 33 | { | |
| 34 | int n; | |
| 35 | x87reg reg; | |
| 36 | reg.f = value; | |
| 37 | if(reg.exp == 0x7FFF) { | |
| 38 | /* The value is an infinity or NaN. | |
| 39 | * Store zero in `*exp`. Return the value as is. */ | |
| 40 | *exp = 0; | |
| 41 | return reg.f; | |
| 42 | } | |
| 43 | if(reg.exp != 0) { | |
| 44 | /* The value is normalized. | |
| 45 | * Extract and zero out the exponent. */ | |
| 46 | *exp = reg.exp - 0x3FFE; | |
| 47 | reg.exp = 0x3FFE; | |
| 48 | return reg.f; | |
| 49 | } | |
| 50 | if(reg.f64 == 0) { | |
| 51 | /* The value is zero. | |
| 52 | * Store zero in `*exp`. Return the value as is. | |
| 53 | * Note the signness. */ | |
| 54 | *exp = 0; | |
| 55 | return reg.f; | |
| 56 | } | |
| 57 | /* The value is denormalized. | |
| 58 | * Extract the exponent, normalize the value, then zero out | |
| 59 | * the exponent. Note that x87 uses an explicit leading bit. */ | |
| 60 | n = __builtin_clzll(reg.f64); | |
| 61 | reg.f64 <<= n; | |
| 62 | *exp = 1 - 0x3FFE - n; | |
| 63 | reg.exp = 0x3FFE; | |
| 64 | return reg.f; | |
| 65 | } | |
| 66 | ||
| 67 | #else | |
| 68 | ||
| 69 | #error Please add `frexpl()` implementation for this platform. | |
| 70 | ||
| 71 | #endif |
lib/libc/musl/src/math/frexpl.c deleted-29| ... | ... | @@ -1,29 +0,0 @@ |
| 1 | #include "libm.h" | |
| 2 | ||
| 3 | #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 | |
| 4 | long double frexpl(long double x, int *e) | |
| 5 | { | |
| 6 | 	return frexp(x, e); | |
| 7 | } | |
| 8 | #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 | |
| 9 | long double frexpl(long double x, int *e) | |
| 10 | { | |
| 11 | 	union ldshape u = {x}; | |
| 12 | 	int ee = u.i.se & 0x7fff; | |
| 13 | ||
| 14 | 	if (!ee) { | |
| 15 | 		if (x) { | |
| 16 | 			x = frexpl(x*0x1p120, e); | |
| 17 | 			*e -= 120; | |
| 18 | 		} else *e = 0; | |
| 19 | 		return x; | |
| 20 | 	} else if (ee == 0x7fff) { | |
| 21 | 		return x; | |
| 22 | 	} | |
| 23 | ||
| 24 | 	*e = ee - 0x3ffe; | |
| 25 | 	u.i.se &= 0x8000; | |
| 26 | 	u.i.se |= 0x3ffe; | |
| 27 | 	return u.f; | |
| 28 | } | |
| 29 | #endif |
src/libs/mingw.zig-1| ... | ... | @@ -613,7 +613,6 @@ const mingw32_generic_src = [_][]const u8{ |
| 613 | 613 | "math" ++ path.sep_str ++ "fpclassify.c", |
| 614 | 614 | "math" ++ path.sep_str ++ "fpclassifyf.c", |
| 615 | 615 | "math" ++ path.sep_str ++ "fpclassifyl.c", |
| 616 | "math" ++ path.sep_str ++ "frexpl.c", | |
| 617 | 616 | "math" ++ path.sep_str ++ "ldexpf.c", |
| 618 | 617 | "math" ++ path.sep_str ++ "lgamma.c", |
| 619 | 618 | "math" ++ path.sep_str ++ "lgammaf.c", |
src/libs/musl.zig-1| ... | ... | @@ -839,7 +839,6 @@ const src_files = [_][]const u8{ |
| 839 | 839 | "musl/src/math/__fpclassify.c", |
| 840 | 840 | "musl/src/math/__fpclassifyf.c", |
| 841 | 841 | "musl/src/math/__fpclassifyl.c", |
| 842 | "musl/src/math/frexpl.c", | |
| 843 | 842 | "musl/src/math/i386/acosl.s", |
| 844 | 843 | "musl/src/math/i386/asinf.s", |
| 845 | 844 | "musl/src/math/i386/asinl.s", |
src/libs/wasi_libc.zig-1| ... | ... | @@ -701,7 +701,6 @@ const libc_top_half_src_files = [_][]const u8{ |
| 701 | 701 | "musl/src/math/finitef.c", |
| 702 | 702 | "musl/src/math/fma.c", |
| 703 | 703 | "musl/src/math/fmaf.c", |
| 704 | "musl/src/math/frexpl.c", | |
| 705 | 704 | "musl/src/math/ilogb.c", |
| 706 | 705 | "musl/src/math/ilogbf.c", |
| 707 | 706 | "musl/src/math/ilogbl.c", |