NetBSD/lib/libm/arch/i387/e_expf.S
drochner 39ba286079 as in exp(), treat +/-Inf and NaN arguments specially, should fix
eg expf(-Inf) which was Nan previously
(We could avoid touching the i387 on amd64 in these cases, but we'd
need to bypass the ABI abstraction macros, so leave it the old way
for now.)
2008-06-24 17:27:56 +00:00

56 lines
1022 B
ArmAsm

/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_expf.S,v 1.6 2008/06/24 17:27:56 drochner Exp $")
/* e^x = 2^(x * log2(e)) */
ENTRY(__ieee754_expf)
XMM_ONE_ARG_FLOAT_PROLOGUE
/*
* catch +/-Inf and NaN arguments
*/
movl ARG_FLOAT_ONE,%eax
andl $0x7fffffff,%eax
cmpl $0x7f800000,%eax
jae x_Inf_or_NaN
flds ARG_FLOAT_ONE
fldl2e
fmulp /* x * log2(e) */
fld %st(0)
frndint /* int(x * log2(e)) */
fsubr %st(0),%st(1) /* fract(x * log2(e)) */
fxch
f2xm1 /* 2^(fract(x * log2(e))) - 1 */
fld1
faddp /* 2^(fract(x * log2(e))) */
fscale /* e^x */
fstp %st(1)
XMM_FLOAT_EPILOGUE
ret
x_Inf_or_NaN:
/*
* Return 0 if x is -Inf. Otherwise just return x, although the
* C version would return (x + x) (Real Indefinite) if x is a NaN.
*/
movl ARG_FLOAT_ONE,%eax
cmpl $0xff800000,%eax
jne x_not_minus_Inf
fldz
XMM_FLOAT_EPILOGUE
ret
x_not_minus_Inf:
flds ARG_FLOAT_ONE
XMM_FLOAT_EPILOGUE
ret