From 9367253b4d13c76ddb13ccda73352f58c3fadca7 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Tue, 2 Mar 2021 13:57:23 -0800 Subject: [PATCH] Add more libm unit tests and fixes See #61 --- libc/tinymath/ceil.S | 45 +++++++++++++++++---------- libc/tinymath/ceilf.S | 49 ++++++++++++++++------------- libc/tinymath/ceill.S | 29 ++++++++++------- libc/tinymath/floor.S | 49 +++++++++++++++++------------ libc/tinymath/floorf.S | 47 ++++++++++++++++------------ libc/tinymath/floorl.S | 26 ++++++++++------ libc/tinymath/powl.S | 11 +++++-- libc/tinymath/trunc.S | 22 ++++++++----- libc/tinymath/truncf.S | 27 ++++++++++------ test/libc/tinymath/ceil_test.c | 55 +++++++++++++++++++++++++++++++++ test/libc/tinymath/exp2l_test.c | 28 +++++++++++++++++ test/libc/tinymath/floor_test.c | 55 +++++++++++++++++++++++++++++++++ test/libc/tinymath/powl_test.c | 14 +++++---- test/libc/tinymath/trunc_test.c | 55 +++++++++++++++++++++++++++++++++ tool/build/lib/fpu.c | 2 +- 15 files changed, 390 insertions(+), 124 deletions(-) create mode 100644 test/libc/tinymath/ceil_test.c create mode 100644 test/libc/tinymath/exp2l_test.c create mode 100644 test/libc/tinymath/floor_test.c create mode 100644 test/libc/tinymath/trunc_test.c diff --git a/libc/tinymath/ceil.S b/libc/tinymath/ceil.S index 750b99783..7f00dd1d6 100644 --- a/libc/tinymath/ceil.S +++ b/libc/tinymath/ceil.S @@ -17,28 +17,41 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ +// Returns smallest integral not less than 𝑥. +// +// @param 𝑥 is double scalar in low half of %xmm0 +// @return double scalar in low half of %xmm0 +// @see round(),rint(),nearbyint() +// @see vroundsd $_MM_FROUND_TO_POS_INF|_MM_FROUND_NO_EXC,%xmm0,%xmm0,%xmm0 ceil: .leafprologue .profilable - movsd nan(%rip),%xmm1 - movsd sig(%rip),%xmm2 - andpd %xmm0,%xmm1 - comisd %xmm1,%xmm2 + movsd 4f(%rip),%xmm3 + movsd 2f(%rip),%xmm4 + movapd %xmm0,%xmm2 + movapd %xmm0,%xmm1 + andpd %xmm3,%xmm2 + ucomisd %xmm2,%xmm4 jbe 1f cvttsd2siq %xmm0,%rax - pxor %xmm1,%xmm1 - movsd one(%rip),%xmm2 - cvtsi2sdq %rax,%xmm1 - cmpnlesd %xmm1,%xmm0 - andpd %xmm2,%xmm0 - addsd %xmm1,%xmm0 + pxor %xmm2,%xmm2 + movsd 3f(%rip),%xmm4 + andnpd %xmm1,%xmm3 + cvtsi2sdq %rax,%xmm2 + cmpnlesd %xmm2,%xmm0 + andpd %xmm4,%xmm0 + addsd %xmm2,%xmm0 + orpd %xmm3,%xmm0 1: .leafepilogue .endfn ceil,globl .rodata.cst8 -nan: .double nan -sig: .quad 0x0010000000000000 -one: .double 1 - -// vroundsd $_MM_FROUND_TO_POS_INF|_MM_FROUND_NO_EXC,%xmm0,%xmm0,%xmm0 +2: .long 0x00000000 + .long 0x43300000 +3: .long 0x00000000 + .long 0x3ff00000 + .rodata.cst16 +4: .long 0xffffffff + .long 0x7fffffff + .long 0x00000000 + .long 0x00000000 diff --git a/libc/tinymath/ceilf.S b/libc/tinymath/ceilf.S index bddf30464..79e7abd5c 100644 --- a/libc/tinymath/ceilf.S +++ b/libc/tinymath/ceilf.S @@ -17,34 +17,39 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ +// Returns smallest integral not less than 𝑥. +// +// @param 𝑥 is float scalar in low quarter of %xmm0 +// @return float scalar in low quarter of %xmm0 +// @see round(),rint(),nearbyint() +// @see vroundss $_MM_FROUND_TO_POS_INF|_MM_FROUND_NO_EXC,%xmm0,%xmm0,%xmm0 ceilf: .leafprologue .profilable - movss .L3(%rip),%xmm1 - andps %xmm0,%xmm1 - movss .L2(%rip),%xmm2 - comiss %xmm1,%xmm2 + movss 4f(%rip),%xmm3 + movss 2f(%rip),%xmm4 + movaps %xmm0,%xmm2 + movaps %xmm0,%xmm1 + andps %xmm3,%xmm2 + ucomiss %xmm2,%xmm4 jbe 1f - cvttss2si %xmm0,%eax - pxor %xmm1,%xmm1 - movss .L1(%rip),%xmm2 - cvtsi2ss %eax,%xmm1 - cmpnless %xmm1,%xmm0 - andps %xmm2,%xmm0 - addss %xmm1,%xmm0 + cvttss2sil %xmm0,%eax + pxor %xmm2,%xmm2 + movss 3f(%rip),%xmm4 + andnps %xmm1,%xmm3 + cvtsi2ssl %eax,%xmm2 + cmpnless %xmm2,%xmm0 + andps %xmm4,%xmm0 + addss %xmm2,%xmm0 + orps %xmm3,%xmm0 1: .leafepilogue .endfn ceilf,globl .rodata.cst4 -.L1: .float 1.0 -.L2: .long 1258291200 - +2: .long 0x4b000000 +3: .long 0x3f800000 .rodata.cst16 -.L3: .long 2147483647 - .long 0 - .long 0 - .long 0 - -// TODO(jart): -// vroundss $10,%xmm0,%xmm0,%xmm0 +4: .long 0x7fffffff + .long 0x00000000 + .long 0x00000000 + .long 0x00000000 diff --git a/libc/tinymath/ceill.S b/libc/tinymath/ceill.S index f1a12e89b..0f1212401 100644 --- a/libc/tinymath/ceill.S +++ b/libc/tinymath/ceill.S @@ -17,19 +17,24 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ -ceill: .profilable - sub $24,%rsp - fldt 32(%rsp) - fnstcw 14(%rsp) - movzwl 14(%rsp),%eax - andb $-13,%ah - orb $8,%ah - movw %ax,12(%rsp) - fldcw 12(%rsp) +// Returns smallest integral not less than 𝑥. +// +// @param 𝑥 is long double passed on stack +// @return long double in %st +ceill: pushq %rbp + mov %rsp,%rbp + .profilable + sub $16,%rsp + fnstcw -2(%rbp) + fldt 16(%rbp) + movzwl -2(%rbp),%eax + and $-13,%ah + or $8,%ah + mov %ax,-4(%rbp) + fldcw -4(%rbp) frndint - fldcw 14(%rsp) - add $24,%rsp + fldcw -2(%rbp) + leave ret .endfn ceill,globl diff --git a/libc/tinymath/floor.S b/libc/tinymath/floor.S index a117c553b..ccd4e6c7b 100644 --- a/libc/tinymath/floor.S +++ b/libc/tinymath/floor.S @@ -17,31 +17,42 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ - -// vroundsd $_MM_FROUND_TO_NEG_INF|_MM_FROUND_NO_EXC,%xmm0,%xmm0,%xmm0 +// Returns largest integral not greater than 𝑥. +// +// @param 𝑥 is double scalar in low half of %xmm0 +// @return double scalar in low half of %xmm0 floor: .leafprologue .profilable - movsd 4f(%rip),%xmm1 - movsd 3f(%rip),%xmm2 - andpd %xmm0,%xmm1 - comisd %xmm1,%xmm2 + movsd 4f(%rip),%xmm3 + movsd 2f(%rip),%xmm4 + movapd %xmm0,%xmm2 + movapd %xmm0,%xmm1 + andpd %xmm3,%xmm2 + ucomisd %xmm2,%xmm4 jbe 1f cvttsd2siq %xmm0,%rax - pxor %xmm1,%xmm1 - movsd 2f(%rip),%xmm2 - cvtsi2sdq %rax,%xmm1 - movapd %xmm1,%xmm3 - cmpnlesd %xmm0,%xmm3 - movapd %xmm3,%xmm0 - andpd %xmm2,%xmm0 - subsd %xmm0,%xmm1 - movapd %xmm1,%xmm0 + pxor %xmm2,%xmm2 + movsd 3f(%rip),%xmm4 + andnpd %xmm1,%xmm3 + cvtsi2sdq %rax,%xmm2 + movapd %xmm2,%xmm5 + cmpnlesd %xmm0,%xmm5 + movapd %xmm5,%xmm0 + andpd %xmm4,%xmm0 + subsd %xmm0,%xmm2 + movapd %xmm2,%xmm0 + orpd %xmm3,%xmm0 1: .leafepilogue .endfn floor,globl .rodata.cst8 -2: .double 1 -3: .quad 0x0010000000000000 -4: .double nan +2: .long 0x00000000 + .long 0x43300000 +3: .long 0x00000000 + .long 0x3ff00000 + .rodata.cst16 +4: .long 0xffffffff + .long 0x7fffffff + .long 0x00000000 + .long 0x00000000 diff --git a/libc/tinymath/floorf.S b/libc/tinymath/floorf.S index 4bf4ef56a..d9aa9c460 100644 --- a/libc/tinymath/floorf.S +++ b/libc/tinymath/floorf.S @@ -17,31 +17,40 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ +// Returns largest integral not greater than 𝑥. +// +// @param 𝑥 is float scalar in low quarter of %xmm0 +// @return float scalar in low quarter of %xmm0 floorf: .leafprologue .profilable - movss .LC8(%rip),%xmm1 - andps %xmm0,%xmm1 - movss .LC7(%rip),%xmm2 - comiss %xmm1,%xmm2 + movss 4f(%rip),%xmm3 + movss 2f(%rip),%xmm4 + movaps %xmm0,%xmm2 + movaps %xmm0,%xmm1 + andps %xmm3,%xmm2 + ucomiss %xmm2,%xmm4 jbe 1f - cvttss2si %xmm0,%eax - pxor %xmm1,%xmm1 - movss .LC3(%rip),%xmm2 - cvtsi2ss %eax,%xmm1 - movaps %xmm1,%xmm3 - cmpnless %xmm0,%xmm3 - movaps %xmm3,%xmm0 - andps %xmm2,%xmm0 - subss %xmm0,%xmm1 - movaps %xmm1,%xmm0 + cvttss2sil %xmm0,%eax + pxor %xmm2,%xmm2 + movss 3f(%rip),%xmm4 + andnps %xmm1,%xmm3 + cvtsi2ssl %eax,%xmm2 + movaps %xmm2,%xmm5 + cmpnless %xmm0,%xmm5 + movaps %xmm5,%xmm0 + andps %xmm4,%xmm0 + subss %xmm0,%xmm2 + movaps %xmm2,%xmm0 + orps %xmm3,%xmm0 1: .leafepilogue .endfn floorf,globl .rodata.cst4 -.LC3: .float 1.0 -.LC7: .long 0x4b000000 - +2: .long 0x4b000000 +3: .long 0x3f800000 .rodata.cst16 -.LC8: .long 2147483647,0,0,0 +4: .long 0x7fffffff + .long 0x00000000 + .long 0x00000000 + .long 0x00000000 diff --git a/libc/tinymath/floorl.S b/libc/tinymath/floorl.S index a6d0d0d71..f7eaee26f 100644 --- a/libc/tinymath/floorl.S +++ b/libc/tinymath/floorl.S @@ -17,17 +17,23 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ -floorl: .profilable - fldt 8(%rsp) - mov $7,%al - fstcw 8(%rsp) - mov 9(%rsp),%ah - mov %al,9(%rsp) - fldcw 8(%rsp) +// Returns largest integral not greater than 𝑥. +// +// @param 𝑥 is long double passed on stack +// @return float scalar in low quarter of %xmm0 +floorl: pushq %rbp + mov %rsp,%rbp + sub $16,%rsp + fnstcw -2(%rbp) + fldt 16(%rbp) + movzwl -2(%rbp),%eax + and $-13,%ah + or $4,%ah + mov %ax,-4(%rbp) + fldcw -4(%rbp) frndint - mov %ah,9(%rsp) - fldcw 8(%rsp) + fldcw -2(%rbp) + leave ret .endfn floorl,globl diff --git a/libc/tinymath/powl.S b/libc/tinymath/powl.S index c6246b07e..f9865d647 100644 --- a/libc/tinymath/powl.S +++ b/libc/tinymath/powl.S @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/pc.internal.h" #include "libc/macros.internal.h" // Returns 𝑥^𝑦. @@ -24,12 +25,15 @@ // @param 𝑦 is the power, also pushed on stack, in reverse order // @return result of exponentiation on FPU stack in %st // @note Sun's fdlibm needs 2kLOC to do this for RISC lool -// @define exp2l(fmodl(y*log2l(x),1))*exp2l(y) +// @define z=y*log2(fabs(x)),copysign(trunc(exp2(fmod(z,1)))*exp2(z),x) powl: push %rbp mov %rsp,%rbp .profilable fldt 32(%rbp) fldt 16(%rbp) + fxam + fstsw + fabs fyl2x fld1 fld %st(1) @@ -39,7 +43,10 @@ powl: push %rbp fscale fxch fstp %st - pop %rbp + test $FPU_C1>>8,%ah + jz 1f + fchs +1: pop %rbp ret .endfn powl,globl .alias powl,__powl_finite diff --git a/libc/tinymath/trunc.S b/libc/tinymath/trunc.S index 4cee5bb58..6c581f29f 100644 --- a/libc/tinymath/trunc.S +++ b/libc/tinymath/trunc.S @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ // Rounds to integer, toward zero. // @@ -28,17 +27,26 @@ // @see roundsd $_MM_FROUND_TO_ZERO|_MM_FROUND_NO_EXC,%xmm0,%xmm0 trunc: .leafprologue .profilable - movsd 3f(%rip),%xmm1 - movsd 2f(%rip),%xmm2 - andpd %xmm0,%xmm1 - comisd %xmm1,%xmm2 + movsd 3f(%rip),%xmm2 + movsd 2f(%rip),%xmm4 + movapd %xmm0,%xmm3 + movapd %xmm0,%xmm1 + andpd %xmm2,%xmm3 + ucomisd %xmm3,%xmm4 jbe 1f cvttsd2siq %xmm0,%rax pxor %xmm0,%xmm0 + andnpd %xmm1,%xmm2 cvtsi2sdq %rax,%xmm0 + orpd %xmm2,%xmm0 1: .leafepilogue .endfn trunc,globl .rodata.cst8 -2: .quad 0x0010000000000000 -3: .double nan +2: .long 0x00000000 + .long 0x43300000 + .rodata.cst16 +3: .long 0xffffffff + .long 0x7fffffff + .long 0x00000000 + .long 0x00000000 diff --git a/libc/tinymath/truncf.S b/libc/tinymath/truncf.S index 7cc1510ad..eac2deac9 100644 --- a/libc/tinymath/truncf.S +++ b/libc/tinymath/truncf.S @@ -17,18 +17,28 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -.source __FILE__ +// Rounds to integer, toward zero. +// +// @param 𝑥 is float scalar in low quarter of %xmm0 +// @return float scalar in low quarter of %xmm0 +// @define trunc(𝑥+copysign(.5,𝑥)) +// @see round(),rint(),nearbyint() +// @see roundss $_MM_FROUND_TO_ZERO|_MM_FROUND_NO_EXC,%xmm0,%xmm0 truncf: .leafprologue .profilable - movss 3f(%rip),%xmm1 - andps %xmm0,%xmm1 - movss 2f(%rip),%xmm2 - comiss %xmm1,%xmm2 + movss 3f(%rip),%xmm2 + movss 2f(%rip),%xmm4 + movaps %xmm0,%xmm3 + movaps %xmm0,%xmm1 + andps %xmm2,%xmm3 + ucomiss %xmm3,%xmm4 jbe 1f - cvttss2si %xmm0,%eax + cvttss2sil %xmm0,%eax pxor %xmm0,%xmm0 - cvtsi2ss %eax,%xmm0 + andnps %xmm1,%xmm2 + cvtsi2ssl %eax,%xmm0 + orps %xmm2,%xmm0 1: .leafepilogue .endfn truncf,globl @@ -36,6 +46,3 @@ truncf: .leafprologue 2: .long 0x4b000000 .rodata.cst16 3: .long 0x7fffffff,0,0,0 - -// TODO(jart) -// roundss $_MM_FROUND_TO_ZERO|_MM_FROUND_NO_EXC,%xmm0,%xmm0 diff --git a/test/libc/tinymath/ceil_test.c b/test/libc/tinymath/ceil_test.c new file mode 100644 index 000000000..893fd8f9b --- /dev/null +++ b/test/libc/tinymath/ceil_test.c @@ -0,0 +1,55 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2021 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/runtime/gc.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +TEST(ceil, test) { + EXPECT_STREQ("3", gc(xdtoa(ceil(3)))); + EXPECT_STREQ("4", gc(xdtoa(ceil(3.14)))); + EXPECT_STREQ("-3", gc(xdtoa(ceil(-3.14)))); + EXPECT_STREQ("-0", gc(xdtoa(ceil(-0.)))); + EXPECT_STREQ("NAN", gc(xdtoa(ceil(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoa(ceil(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoa(ceil(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoa(ceil(-INFINITY)))); +} + +TEST(ceilf, test) { + EXPECT_STREQ("3", gc(xdtoaf(ceilf(3)))); + EXPECT_STREQ("4", gc(xdtoaf(ceilf(3.14)))); + EXPECT_STREQ("-3", gc(xdtoaf(ceilf(-3.14)))); + EXPECT_STREQ("-0", gc(xdtoaf(ceilf(-0.)))); + EXPECT_STREQ("NAN", gc(xdtoaf(ceilf(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoaf(ceilf(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoaf(ceilf(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoaf(ceilf(-INFINITY)))); +} + +TEST(ceill, test) { + EXPECT_STREQ("3", gc(xdtoal(ceill(3)))); + EXPECT_STREQ("4", gc(xdtoal(ceill(3.14)))); + EXPECT_STREQ("-3", gc(xdtoal(ceill(-3.14)))); + EXPECT_STREQ("-0", gc(xdtoal(ceill(-0.)))); + EXPECT_STREQ("NAN", gc(xdtoal(ceill(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoal(ceill(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoal(ceill(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoal(ceill(-INFINITY)))); +} diff --git a/test/libc/tinymath/exp2l_test.c b/test/libc/tinymath/exp2l_test.c new file mode 100644 index 000000000..ff0d6453a --- /dev/null +++ b/test/libc/tinymath/exp2l_test.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2021 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/runtime/gc.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +TEST(exp2l, test) { + EXPECT_STREQ("16", gc(xdtoal(exp2l(4)))); + EXPECT_STREQ("16", gc(xdtoa(exp2(4)))); + EXPECT_STREQ("16", gc(xdtoaf(exp2f(4)))); +} diff --git a/test/libc/tinymath/floor_test.c b/test/libc/tinymath/floor_test.c new file mode 100644 index 000000000..9c5a757d9 --- /dev/null +++ b/test/libc/tinymath/floor_test.c @@ -0,0 +1,55 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2021 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/runtime/gc.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +TEST(floor, test) { + EXPECT_STREQ("3", gc(xdtoa(floor(3)))); + EXPECT_STREQ("3", gc(xdtoa(floor(3.14)))); + EXPECT_STREQ("-4", gc(xdtoa(floor(-3.14)))); + EXPECT_STREQ("-0", gc(xdtoa(floor(-0.)))); + EXPECT_STREQ("NAN", gc(xdtoa(floor(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoa(floor(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoa(floor(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoa(floor(-INFINITY)))); +} + +TEST(floorf, test) { + EXPECT_STREQ("3", gc(xdtoaf(floorf(3)))); + EXPECT_STREQ("3", gc(xdtoaf(floorf(3.14)))); + EXPECT_STREQ("-4", gc(xdtoaf(floorf(-3.14)))); + EXPECT_STREQ("-0", gc(xdtoaf(floorf(-0.)))); + EXPECT_STREQ("NAN", gc(xdtoaf(floorf(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoaf(floorf(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoaf(floorf(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoaf(floorf(-INFINITY)))); +} + +TEST(floorl, test) { + EXPECT_STREQ("3", gc(xdtoal(floorl(3)))); + EXPECT_STREQ("3", gc(xdtoal(floorl(3.14)))); + EXPECT_STREQ("-4", gc(xdtoal(floorl(-3.14)))); + EXPECT_STREQ("-0", gc(xdtoal(floorl(-0.)))); + EXPECT_STREQ("NAN", gc(xdtoal(floorl(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoal(floorl(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoal(floorl(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoal(floorl(-INFINITY)))); +} diff --git a/test/libc/tinymath/powl_test.c b/test/libc/tinymath/powl_test.c index 2011db3e9..b68bbcc8a 100644 --- a/test/libc/tinymath/powl_test.c +++ b/test/libc/tinymath/powl_test.c @@ -22,33 +22,35 @@ #include "libc/math.h" #include "libc/runtime/gc.h" #include "libc/runtime/pc.internal.h" +#include "libc/stdio/stdio.h" #include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/sig.h" #include "libc/testlib/ezbench.h" #include "libc/testlib/testlib.h" #include "libc/x/x.h" -double powa(double x, double y) { - return exp2(fmod(y * log2(x), 1)) * exp2(y); -} - TEST(powl, testLongDouble) { - EXPECT_TRUE(isnan(powl(-1, 1.1))); + EXPECT_STREQ("27", gc(xdtoal(powl(3, 3)))); + EXPECT_STREQ("-27", gc(xdtoal(powl(-3, 3)))); + EXPECT_STREQ("-1", gc(xdtoal(powl(-1, 1.1)))); EXPECT_STREQ("1e+4932", gc(xdtoal(powl(10, 4932)))); EXPECT_STREQ("INFINITY", gc(xdtoal(powl(10, 4933)))); EXPECT_STREQ("0", gc(xdtoal(powl(10, -5000)))); EXPECT_STREQ("1.063382396627933e+37", gc(xdtoal(powl(2, 123)))); - /* .4248496805467504836322459796959084815827285786480897 */ EXPECT_STARTSWITH(".4248496805467504", gc(xdtoal(powl(0.7, 2.4)))); } TEST(powl, testDouble) { + EXPECT_STREQ("27", gc(xdtoa(pow(3, 3)))); + EXPECT_STREQ("-27", gc(xdtoa(pow(-3, 3)))); EXPECT_STREQ("1e+308", gc(xdtoa(pow(10, 308)))); EXPECT_STREQ("INFINITY", gc(xdtoa(pow(10, 309)))); EXPECT_STARTSWITH(".42484968054675", gc(xdtoa(pow(0.7, 2.4)))); } TEST(powl, testFloat) { + EXPECT_STREQ("27", gc(xdtoaf(powf(3, 3)))); + EXPECT_STREQ("-27", gc(xdtoaf(powf(-3, 3)))); EXPECT_STARTSWITH(".4248496", gc(xdtoa(powf(0.7f, 2.4f)))); } diff --git a/test/libc/tinymath/trunc_test.c b/test/libc/tinymath/trunc_test.c new file mode 100644 index 000000000..bda338143 --- /dev/null +++ b/test/libc/tinymath/trunc_test.c @@ -0,0 +1,55 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2021 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/runtime/gc.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +TEST(trunc, test) { + EXPECT_STREQ("3", gc(xdtoa(trunc(3)))); + EXPECT_STREQ("3", gc(xdtoa(trunc(3.14)))); + EXPECT_STREQ("-3", gc(xdtoa(trunc(-3.14)))); + EXPECT_STREQ("-0", gc(xdtoa(trunc(-0.)))); + EXPECT_STREQ("NAN", gc(xdtoa(trunc(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoa(trunc(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoa(trunc(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoa(trunc(-INFINITY)))); +} + +TEST(truncf, test) { + EXPECT_STREQ("3", gc(xdtoaf(truncf(3)))); + EXPECT_STREQ("3", gc(xdtoaf(truncf(3.14)))); + EXPECT_STREQ("-3", gc(xdtoaf(truncf(-3.14)))); + EXPECT_STREQ("-0", gc(xdtoaf(truncf(-0.)))); + EXPECT_STREQ("NAN", gc(xdtoaf(truncf(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoaf(truncf(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoaf(truncf(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoaf(truncf(-INFINITY)))); +} + +TEST(truncl, test) { + EXPECT_STREQ("3", gc(xdtoal(truncl(3)))); + EXPECT_STREQ("3", gc(xdtoal(truncl(3.14)))); + EXPECT_STREQ("-3", gc(xdtoal(truncl(-3.14)))); + EXPECT_STREQ("-0", gc(xdtoal(truncl(-0.)))); + EXPECT_STREQ("NAN", gc(xdtoal(truncl(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoal(truncl(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoal(truncl(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoal(truncl(-INFINITY)))); +} diff --git a/tool/build/lib/fpu.c b/tool/build/lib/fpu.c index 75178447a..3ed71fb2a 100644 --- a/tool/build/lib/fpu.c +++ b/tool/build/lib/fpu.c @@ -171,7 +171,7 @@ static long double fyl2xp1(long double x, long double y) { } static long double fscale(long double significand, long double exponent) { - return scalbl(significand, exponent); + return scalbl(trunc(significand), exponent); } static long double x87remainder(long double x, long double y, uint32_t *sw,