mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-27 19:09:47 +03:00
libzigc/math: Implement lrint
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=lrint -fqemu -fwasmtime --summary line Build Summary: 737/737 steps succeeded ```
This commit is contained in:
@@ -66,6 +66,7 @@ comptime {
|
||||
symbol(&finitef, "finitef");
|
||||
symbol(&frexp, "frexp");
|
||||
symbol(&hypot, "hypot");
|
||||
symbol(&lrint, "lrint");
|
||||
symbol(&modf, "modf");
|
||||
symbol(&pow, "pow");
|
||||
symbol(&pow10, "pow10");
|
||||
@@ -229,6 +230,10 @@ fn isnanl(x: c_longdouble) callconv(.c) c_int {
|
||||
return if (math.isNan(x)) 1 else 0;
|
||||
}
|
||||
|
||||
fn lrint(x: f64) callconv(.c) c_long {
|
||||
return @intFromFloat(rint(x));
|
||||
}
|
||||
|
||||
fn modfGeneric(comptime T: type, x: T, iptr: *T) T {
|
||||
if (math.isNegativeInf(x)) {
|
||||
iptr.* = -math.inf(T);
|
||||
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
#include <math.h>
|
||||
|
||||
long lrint(double x)
|
||||
{
|
||||
long n;
|
||||
__asm__ (
|
||||
"frintx %d1, %d1\n"
|
||||
"fcvtzs %x0, %d1\n" : "=r"(n), "+w"(x));
|
||||
return n;
|
||||
}
|
||||
Vendored
-8
@@ -1,8 +0,0 @@
|
||||
#include <math.h>
|
||||
|
||||
long lrint(double x)
|
||||
{
|
||||
long r;
|
||||
__asm__ ("fistpl %0" : "=m"(r) : "t"(x) : "st");
|
||||
return r;
|
||||
}
|
||||
Vendored
-72
@@ -1,72 +0,0 @@
|
||||
#include <limits.h>
|
||||
#include <fenv.h>
|
||||
#include <math.h>
|
||||
#include "libm.h"
|
||||
|
||||
/*
|
||||
If the result cannot be represented (overflow, nan), then
|
||||
lrint raises the invalid exception.
|
||||
|
||||
Otherwise if the input was not an integer then the inexact
|
||||
exception is raised.
|
||||
|
||||
C99 is a bit vague about whether inexact exception is
|
||||
allowed to be raised when invalid is raised.
|
||||
(F.9 explicitly allows spurious inexact exceptions, F.9.6.5
|
||||
does not make it clear if that rule applies to lrint, but
|
||||
IEEE 754r 7.8 seems to forbid spurious inexact exception in
|
||||
the ineger conversion functions)
|
||||
|
||||
So we try to make sure that no spurious inexact exception is
|
||||
raised in case of an overflow.
|
||||
|
||||
If the bit size of long > precision of double, then there
|
||||
cannot be inexact rounding in case the result overflows,
|
||||
otherwise LONG_MAX and LONG_MIN can be represented exactly
|
||||
as a double.
|
||||
*/
|
||||
|
||||
#if LONG_MAX < 1U<<53 && defined(FE_INEXACT)
|
||||
#include <float.h>
|
||||
#include <stdint.h>
|
||||
#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
|
||||
#define EPS DBL_EPSILON
|
||||
#elif FLT_EVAL_METHOD==2
|
||||
#define EPS LDBL_EPSILON
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
/* avoid stack frame in lrint */
|
||||
__attribute__((noinline))
|
||||
#endif
|
||||
static long lrint_slow(double x)
|
||||
{
|
||||
#pragma STDC FENV_ACCESS ON
|
||||
int e;
|
||||
|
||||
e = fetestexcept(FE_INEXACT);
|
||||
x = rint(x);
|
||||
if (!e && (x > LONG_MAX || x < LONG_MIN))
|
||||
feclearexcept(FE_INEXACT);
|
||||
/* conversion */
|
||||
return x;
|
||||
}
|
||||
|
||||
long lrint(double x)
|
||||
{
|
||||
uint32_t abstop = asuint64(x)>>32 & 0x7fffffff;
|
||||
uint64_t sign = asuint64(x) & (1ULL << 63);
|
||||
|
||||
if (abstop < 0x41dfffff) {
|
||||
/* |x| < 0x7ffffc00, no overflow */
|
||||
double_t toint = asdouble(asuint64(1/EPS) | sign);
|
||||
double_t y = x + toint - toint;
|
||||
return (long)y;
|
||||
}
|
||||
return lrint_slow(x);
|
||||
}
|
||||
#else
|
||||
long lrint(double x)
|
||||
{
|
||||
return rint(x);
|
||||
}
|
||||
#endif
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
#include <math.h>
|
||||
|
||||
#ifdef _ARCH_PWR5X
|
||||
|
||||
long lrint(double x)
|
||||
{
|
||||
long n;
|
||||
__asm__ ("fctid %0, %1" : "=d"(n) : "d"(x));
|
||||
return n;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "../lrint.c"
|
||||
|
||||
#endif
|
||||
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
.global lrint
|
||||
.type lrint,@function
|
||||
lrint:
|
||||
cvtsd2si %xmm0,%rax
|
||||
ret
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
#include <math.h>
|
||||
|
||||
long lrint(double x)
|
||||
{
|
||||
long r;
|
||||
__asm__ ("cvtsd2si %1, %0" : "=r"(r) : "x"(x));
|
||||
return r;
|
||||
}
|
||||
@@ -787,7 +787,6 @@ const src_files = [_][]const u8{
|
||||
"musl/src/math/aarch64/llrintf.c",
|
||||
"musl/src/math/aarch64/llround.c",
|
||||
"musl/src/math/aarch64/llroundf.c",
|
||||
"musl/src/math/aarch64/lrint.c",
|
||||
"musl/src/math/aarch64/lrintf.c",
|
||||
"musl/src/math/aarch64/lround.c",
|
||||
"musl/src/math/aarch64/lroundf.c",
|
||||
@@ -860,7 +859,6 @@ const src_files = [_][]const u8{
|
||||
"musl/src/math/i386/log1p.s",
|
||||
"musl/src/math/i386/log2l.s",
|
||||
"musl/src/math/i386/logl.s",
|
||||
"musl/src/math/i386/lrint.c",
|
||||
"musl/src/math/i386/lrintf.c",
|
||||
"musl/src/math/i386/lrintl.c",
|
||||
"musl/src/math/i386/remainder.c",
|
||||
@@ -910,7 +908,6 @@ const src_files = [_][]const u8{
|
||||
"musl/src/math/logbf.c",
|
||||
"musl/src/math/logbl.c",
|
||||
"musl/src/math/logl.c",
|
||||
"musl/src/math/lrint.c",
|
||||
"musl/src/math/lrintf.c",
|
||||
"musl/src/math/lrintl.c",
|
||||
"musl/src/math/lround.c",
|
||||
@@ -940,7 +937,6 @@ const src_files = [_][]const u8{
|
||||
"musl/src/math/pow_data.c",
|
||||
"musl/src/math/powerpc64/fma.c",
|
||||
"musl/src/math/powerpc64/fmaf.c",
|
||||
"musl/src/math/powerpc64/lrint.c",
|
||||
"musl/src/math/powerpc64/lrintf.c",
|
||||
"musl/src/math/powerpc64/lround.c",
|
||||
"musl/src/math/powerpc64/lroundf.c",
|
||||
@@ -1017,7 +1013,6 @@ const src_files = [_][]const u8{
|
||||
"musl/src/math/x32/logl.s",
|
||||
"musl/src/math/x32/lrintf.s",
|
||||
"musl/src/math/x32/lrintl.s",
|
||||
"musl/src/math/x32/lrint.s",
|
||||
"musl/src/math/x32/remainderl.s",
|
||||
"musl/src/math/x32/rintl.s",
|
||||
"musl/src/math/x86_64/acosl.s",
|
||||
@@ -1036,7 +1031,6 @@ const src_files = [_][]const u8{
|
||||
"musl/src/math/x86_64/log1pl.s",
|
||||
"musl/src/math/x86_64/log2l.s",
|
||||
"musl/src/math/x86_64/logl.s",
|
||||
"musl/src/math/x86_64/lrint.c",
|
||||
"musl/src/math/x86_64/lrintf.c",
|
||||
"musl/src/math/x86_64/lrintl.c",
|
||||
"musl/src/math/x86_64/remainderl.c",
|
||||
|
||||
@@ -732,7 +732,6 @@ const libc_top_half_src_files = [_][]const u8{
|
||||
"musl/src/math/logbf.c",
|
||||
"musl/src/math/logbl.c",
|
||||
"musl/src/math/logl.c",
|
||||
"musl/src/math/lrint.c",
|
||||
"musl/src/math/lrintf.c",
|
||||
"musl/src/math/lrintl.c",
|
||||
"musl/src/math/lround.c",
|
||||
|
||||
Reference in New Issue
Block a user