libc
/* $Id$ */
							/* Copyright (c) 2008-2020 Pierre Pronchery <khorben@defora.org> */
							/* This file is part of DeforaOS System libc */
							/* All rights reserved.
							 *
							 * Redistribution and use in source and binary forms, with or without
							 * modification, are permitted provided that the following conditions are
							 * met:
							 *
							 * 1. Redistributions of source code must retain the above copyright
							 *    notice, this list of conditions and the following disclaimer.
							 *
							 * 2. Redistributions in binary form must reproduce the above copyright
							 *    notice, this list of conditions and the following disclaimer in the
							 *    documentation and/or other materials provided with the distribution.
							 *
							 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
							 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
							 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
							 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
							 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
							 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
							 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
							 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
							 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
							 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
							 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
							/* functions */
							/* XXX math functions from dietlibc */
							/* _flcetr */
							.Lflcetr:
								xor	%ecx, %ecx
								mov	%ah, %ch
								push	%eax
								fstcw	(%esp)
								mov	(%esp), %ax
								and	$0x3, %ah
								or	%ecx, %eax
								mov	%ax, 0x2(%esp)
								fldcw	0x2(%esp)
								frndint
								fldcw	(%esp)
								pop	%eax
								ret
							/* atan */
							.global atan
							.type atan,@function
							atan:
								fldl	0x4(%esp)
								fld1
								fpatan
								ret
							/* atan2 */
							.global atan2
							.type atan2,@function
							atan2:
								fldl	0x8(%esp)
								fldl	0x4(%esp)
								fpatan
								ret
							/* atan2f */
							.global atan2f
							.type atan2f,@function
							atan2f:
								flds	0x8(%esp)
								flds	0x4(%esp)
								fpatan
								ret
							/* atan2l */
							.global atan2l
							.type atan2l,@function
							atan2l:
								fldt	0x8(%esp)
								fldt	0x4(%esp)
								fpatan
								ret
							/* atanf */
							.global atanf
							.type atanf,@function
							atanf:
								flds	0x4(%esp)
								fld1
								fpatan
								ret
							/* atanl */
							.global atanl
							.type atanl,@function
							atanl:
								fldt	0x4(%esp)
								fld1
								fpatan
								ret
							/* ceil */
							.global ceil
							.type ceil,@function
							ceil:
								fldl	0x4(%esp)
								mov	$0x8, %ah
								jmp	.Lflcetr
							/* ceilf */
							.global ceilf
							.type ceilf,@function
							ceilf:
								flds	0x4(%esp)
								mov	$0x8, %ah
								jmp	.Lflcetr
							/* ceill */
							.global ceill
							.type ceill,@function
							ceill:
								fldt	0x4(%esp)
								mov	$0x8, %ah
								jmp	.Lflcetr
							/* cosf */
							.global cosf
							.type cosf,@function
							cosf:
								flds	0x4(%esp)
							1:	fcos
								fnstsw	%ax
								test	$0x4, %ah
								je	3f
								fldpi
								fadd	%st
								fxch	%st(1)
							2:	fprem1
								fnstsw	%ax
								test	$0x4, %ah
								jne	2b
								fstp	%st(1)
								fcos
							3:	ret
							/* cos */
							.global cos
							.type cos,@function
							cos:
								fldl	0x4(%esp)
							1:	fcos
								fnstsw	%ax
								test	$0x4, %ah
								je	3f
								fldpi
								fadd	%st
								fxch	%st(1)
							2:	fprem1
								fnstsw	%ax
								test	$0x4, %ah
								jne	2b
								fstp	%st(1)
								fcos
							3:	ret
							/* cosl */
							.global cosl
							.type cosl,@function
							cosl:
								fldt	0x4(%esp)
							1:	fcos
								fnstsw	%ax
								test	$0x4, %ah
								je	3f
								fldpi
								fadd	%st
								fxch	%st(1)
							2:	fprem1
								fnstsw	%ax
								test	$0x4, %ah
								jne	2b
								fstp	%st(1)
								fcos
							3:	ret
							/* exp */
							.global exp
							.type exp,@function
							exp:
								fldl2e
								fmull	0x4(%esp)
							__finexp:
								fst	%st(1)
								frndint
								fst	%st(2)
								fsubrp
								f2xm1
								fld1
								faddp
								fscale
								ret
							/* fabs */
							.global fabs
							.type fabs,@function
							fabs:
								fldl	0x4(%esp)
								fabs
								ret
							/* fabsf */
							.global fabsf
							.type fabsf,@function
							fabsf:
								flds	0x4(%esp)
								fabs
								ret
							/* fabsl */
							.global fabsl
							.type fabsl,@function
							fabsl:
								fldt	0x4(%esp)
								fabs
								ret
							/* floor */
							.global floor
							.type floor,@function
							floor:
								fldl	0x4(%esp)
								mov	$0x4, %ah
								jmp	.Lflcetr
							/* floorf */
							.global floorf
							.type floorf,@function
							floorf:
								flds	0x4(%esp)
								mov	$0x4, %ah
								jmp	.Lflcetr
							/* floorl */
							.global floorl
							.type floorl,@function
							floorl:
								fldt	0x4(%esp)
								mov	$0x4, %ah
								jmp	.Lflcetr
							/* fmod */
							.global fmod
							.type fmod,@function
							fmod:
								fldl	0xc(%esp)
								fldl	0x4(%esp)
							.Lfmod:
								fprem
								fstsw	%ax
								sahf
								jp	.Lfmod
								fstp	%st(1)
								ret
							/* fmodf */
							.global fmodf
							.type fmodf,@function
							fmodf:
								flds	0x8(%esp)
								flds	0x4(%esp)
							.Lfmodf:
								fprem
								fstsw	%ax
								sahf
								jp	.Lfmodf
								fstp	%st(1)
								ret
							/* fmodl */
							.global fmodl
							.type fmodl,@function
							fmodl:
								fldt	0x10(%esp)
								fldt	0x04(%esp)
							.Lfmodl:
								fprem
								fstsw	%ax
								sahf
								jp	.Lfmodl
								fstp	%st(1)
								ret
							/* frexp */
							.global frexp
							.type frexp,@function
							frexp:
								fldl	0x4(%esp)
								mov	0xc(%esp), %eax
								fxtract
								fxch
								fistpl	(%eax)
								push	0x3f000000	/* 1/2 */
								fmuls	(%esp)
								incl	(%eax)
								pop	%eax
								ret
							/* frexpf */
							.global frexpf
							.type frexpf,@function
							frexpf:
								flds	0x4(%esp)
								mov	0x8(%esp), %eax
								fxtract
								fxch
								fistpl	(%eax)
								push	0x3f000000	/* 1/2 */
								fmuls	(%esp)
								incl	(%eax)
								pop	%eax
								ret
							/* frexpl */
							.global frexpl
							.type frexpl,@function
							frexpl:
								fldt	0x4(%esp)
								mov	0xc(%esp), %eax
								fxtract
								fxch
								fistpl	(%eax)
								push	0x3f000000	/* 1/2 */
								fmuls	(%esp)
								incl	(%eax)
								pop	%eax
								ret
							/* hypot */
							.global hypot
							.type hypot,@function
							hypot:
								fldl	0xc(%esp)
								fldl	0x4(%esp)
								fmul	%st(0), %st(0)
								fxch
								fmul	%st(0), %st(0)
								faddp
								fsqrt
								ret
							/* hypotf */
							.global hypotf
							.type hypotf,@function
							hypotf:
								flds	0x8(%esp)
								flds	0x4(%esp)
								fmul	%st(0), %st(0)
								fxch
								fmul	%st(0), %st(0)
								faddp
								fsqrt
								ret
							/* hypotl */
							.global hypotl
							.type hypotl,@function
							hypotl:
								fldt	0x10(%esp)
								fldt	0x04(%esp)
								fmul	%st(0), %st(0)
								fxch
								fmul	%st(0), %st(0)
								faddp
								fsqrt
								ret
							/* ldexp */
							.global ldexp
							.type ldexp,@function
							ldexp:
								fildl	0xc(%esp)
								fldl	0x4(%esp)
								fscale
								ret
							/* ldexpf */
							.global ldexpf
							.type ldexpf,@function
							ldexpf:
								filds	0x8(%esp)
								flds	0x4(%esp)
								fscale
								ret
							/* log */
							.global log
							.type log,@function
							log:
								fldln2
								fldl	0x4(%esp)
								fyl2x
								ret
							/* powl */
							.global powl
							.type powl,@function
							powl:
								fldt	0x04(%esp)
								fldt	0x10(%esp)
								ftst			/* y = 0 ? */
								fstsw	%ax
								fld1			/* st(0)=1, st(1)=y, st(2)=x */
								sahf
								jz	 1f		/* return 1 */
								fcomp	%st(1)		/* y = 1 ? */
								fstsw	%ax
								fxch			/* st(0)=x, st(1)=y */
								sahf
								jz	1f		/* return x */
								ftst			/* x = 0 ? */
								fstsw	%ax
								sahf
								jz	1f
								jnc	.Lfinpow	/* x > 0 */
								fxch			/* st(0)=y, st(1)=x */
								fld	%st(0)		/* st(0)=y, st(1)=y, st(2)=x */
								frndint			/* st(0)=int(y) */
								fcomp	%st(1)		/* y = int(y)? */
								fstsw	%ax
								fxch
								sahf
								jnz	.Lfinpow	/* fyl2x -> st(0) = NaN */
								/* y even or odd ? */
								fld1
								fadd	%st(0)		/* st(0) = 2 */
								fdivr	%st(2),%st(0)	/* st(0)=st(2)/2 */
								frndint
								fadd	%st(0),%st(0)
								fcomp	%st(2)		/* st(0) = x, st(1) = y */
								fstsw	%ax
								fchs			/* st(0) = -x */
								sahf
								jz	.Lfinpow	/* y even */
								call	.Lfinpow	/* y odd */
								fchs
							1:	ret
							.Lfinpow:
								fyl2x
							#ifdef __PIC__
								jmp __finexp@PLT
							#else
								jmp __finexp
							#endif
							/* round */
							.global round
							.type round,@function
							round:
								fldl	0x4(%esp)
								frndint
								ret
							/* roundf */
							.global roundf
							.type roundf,@function
							roundf:
								flds	0x4(%esp)
								frndint
								ret
							/* roundl */
							.global roundl
							.type roundl,@function
							roundl:
								fldt	0x4(%esp)
								frndint
								ret
							/* sin */
							.global sin
							.type sin,@function
							sin:
								fldl	0x4(%esp)
							1:	fsin
								fnstsw	%ax
								test	$0x4, %ah
								je	3f
								fldpi
								fadd	%st
								fxch	%st(1)
							2:	fprem1
								fnstsw	%ax
								test	$0x4, %ah
								jne	2b
								fstp	%st(1)
								fsin
							3:	ret
							/* sinf */
							.global sinf
							.type sinf,@function
							sinf:
								flds	0x4(%esp)
							1:	fsin
								fnstsw	%ax
								test	$0x4, %ah
								je	3f
								fldpi
								fadd	%st
								fxch	%st(1)
							2:	fprem1
								fnstsw	%ax
								test	$0x4, %ah
								jne	2b
								fstp	%st(1)
								fsin
							3:	ret
							/* sinl */
							.global sinl
							.type sinl,@function
							sinl:
								fldt	0x4(%esp)
							1:	fsin
								fnstsw	%ax
								test	$0x4, %ah
								je	3f
								fldpi
								fadd	%st
								fxch	%st(1)
							2:	fprem1
								fnstsw	%ax
								test	$0x4, %ah
								jne	2b
								fstp	%st(1)
								fsin
							3:	ret
							/* sqrt */
							.global sqrt
							.type sqrt,@function
							sqrt:
								fldl	0x4(%esp)
								fsqrt
								ret
							/* sqrtf */
							.global sqrtf
							.type sqrtf,@function
							sqrtf:
								flds	0x4(%esp)
								fsqrt
								ret
							/* sqrtl */
							.global sqrtl
							.type sqrtl,@function
							sqrtl:
								fldt	0x4(%esp)
								fsqrt
								ret
							