summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartynas Venckus <martynas@cvs.openbsd.org>2008-09-07 20:36:11 +0000
committerMartynas Venckus <martynas@cvs.openbsd.org>2008-09-07 20:36:11 +0000
commit319618ea76ca9de5c1e1b02bff3bddbdf5c46dc7 (patch)
tree402fb699f6a3a45a23dce26a3952cfee3d992421
parent6e9298963b5a9bb500e3f8308cd681b32638fb31 (diff)
- replace dtoa w/ David's gdtoa, version 2008-03-15
- provide proper dtoa locks - use the real strtof implementation - add strtold, __hdtoa, __hldtoa - add %a/%A support - don't lose precision in printf, don't round to double anymore - implement extended-precision versions of libc functions: fpclassify, isnan, isinf, signbit, isnormal, isfinite, now that the ieee.h is fixed - separate vax versions of strtof, and __hdtoa - add complex math support. added functions: cacos, casin, catan, ccos, csin, ctan, cacosh, casinh, catanh, ccosh, csinh, ctanh, cexp, clog, cabs, cpow, csqrt, carg, cimag, conj, cproj, creal, cacosf, casinf, catanf, ccosf, csinf, ctanf, cacoshf, casinhf, catanhf, ccoshf, csinhf, ctanhf, cexpf, clogf, cabsf, cpowf, csqrtf, cargf, cimagf, conjf, cprojf, crealf - add fdim, fmax, fmin - add log2. (adapted implementation e_log.c. could be more acruate & faster, but it's good enough for now) - remove wrappers & cruft in libm, supposed to work-around mistakes in SVID, etc.; use ieee versions. fixes issues in python 2.6 for djm@ - make _digittoint static - proper definitions for i386, and amd64 in ieee.h - sh, powerpc don't really have extended-precision - add missing definitions for mips64 (quad), m{6,8}k (96-bit) float.h for LDBL_* - merge lead to frac for m{6,8}k, for gdtoa to work properly - add FRAC*BITS & EXT_TO_ARRAY32 definitions in ieee.h, for hdtoa&ldtoa to use - add EXT_IMPLICIT_NBIT definition, which indicates implicit normalization bit - add regression tests for libc: fpclassify and printf - arith.h & gd_qnan.h definitions - update ieee.h: hppa doesn't have quad-precision, hppa64 does - add missing prototypes to gdtoaimp - on 64-bit platforms make sure gdtoa doesn't use a long when it really wants an int - etc., what i may have forgotten... - bump libm major, due to removed&changed symbols - no libc bump, since this is riding on djm's libc major crank from a day ago discussed with / requested by / testing theo, sthen@, djm@, jsg@, merdely@, jsing@, tedu@, brad@, jakemsr@, and others. looks good to millert@ parts of the diff ok kettenis@ this commit does not include: - man page changes
-rw-r--r--include/Makefile4
-rw-r--r--include/complex.h122
-rw-r--r--include/math.h81
-rw-r--r--include/stdlib.h4
-rw-r--r--lib/libc/Makefile.inc3
-rw-r--r--lib/libc/arch/alpha/gdtoa/Makefile.inc3
-rw-r--r--lib/libc/arch/alpha/gdtoa/arith.h6
-rw-r--r--lib/libc/arch/alpha/gdtoa/gd_qnan.h12
-rw-r--r--lib/libc/arch/amd64/gdtoa/Makefile.inc3
-rw-r--r--lib/libc/arch/amd64/gdtoa/arith.h6
-rw-r--r--lib/libc/arch/amd64/gdtoa/gd_qnan.h12
-rw-r--r--lib/libc/arch/amd64/gdtoa/strtold.c45
-rw-r--r--lib/libc/arch/amd64/gen/Makefile.inc3
-rw-r--r--lib/libc/arch/amd64/gen/fpclassifyl.c44
-rw-r--r--lib/libc/arch/amd64/gen/isfinitel.c27
-rw-r--r--lib/libc/arch/amd64/gen/isinfl.c30
-rw-r--r--lib/libc/arch/amd64/gen/isnanl.c30
-rw-r--r--lib/libc/arch/amd64/gen/isnormall.c27
-rw-r--r--lib/libc/arch/arm/gdtoa/Makefile.inc3
-rw-r--r--lib/libc/arch/arm/gdtoa/arith.h2
-rw-r--r--lib/libc/arch/arm/gdtoa/gd_qnan.h12
-rw-r--r--lib/libc/arch/hppa/gdtoa/Makefile.inc3
-rw-r--r--lib/libc/arch/hppa/gdtoa/arith.h3
-rw-r--r--lib/libc/arch/hppa/gdtoa/gd_qnan.h12
-rw-r--r--lib/libc/arch/hppa64/gdtoa/Makefile.inc3
-rw-r--r--lib/libc/arch/hppa64/gdtoa/arith.h1
-rw-r--r--lib/libc/arch/hppa64/gdtoa/gd_qnan.h1
-rw-r--r--lib/libc/arch/hppa64/gdtoa/strtold.c45
-rw-r--r--lib/libc/arch/hppa64/gen/Makefile.inc3
-rw-r--r--lib/libc/arch/hppa64/gen/fpclassifyl.c44
-rw-r--r--lib/libc/arch/hppa64/gen/isfinitel.c27
-rw-r--r--lib/libc/arch/hppa64/gen/isinfl.c29
-rw-r--r--lib/libc/arch/hppa64/gen/isnanl.c29
-rw-r--r--lib/libc/arch/hppa64/gen/isnormall.c27
-rw-r--r--lib/libc/arch/i386/gdtoa/Makefile.inc3
-rw-r--r--lib/libc/arch/i386/gdtoa/arith.h2
-rw-r--r--lib/libc/arch/i386/gdtoa/gd_qnan.h12
-rw-r--r--lib/libc/arch/i386/gdtoa/strtold.c45
-rw-r--r--lib/libc/arch/i386/gen/Makefile.inc3
-rw-r--r--lib/libc/arch/i386/gen/fpclassifyl.c44
-rw-r--r--lib/libc/arch/i386/gen/isfinitel.c27
-rw-r--r--lib/libc/arch/i386/gen/isinfl.c30
-rw-r--r--lib/libc/arch/i386/gen/isnanl.c30
-rw-r--r--lib/libc/arch/i386/gen/isnormall.c27
-rw-r--r--lib/libc/arch/m68k/gdtoa/Makefile.inc3
-rw-r--r--lib/libc/arch/m68k/gdtoa/arith.h2
-rw-r--r--lib/libc/arch/m68k/gdtoa/gd_qnan.h12
-rw-r--r--lib/libc/arch/m68k/gdtoa/strtold.c45
-rw-r--r--lib/libc/arch/m68k/gen/Makefile.inc3
-rw-r--r--lib/libc/arch/m68k/gen/fpclassifyl.c44
-rw-r--r--lib/libc/arch/m68k/gen/isfinitel.c27
-rw-r--r--lib/libc/arch/m68k/gen/isinfl.c30
-rw-r--r--lib/libc/arch/m68k/gen/isnanl.c30
-rw-r--r--lib/libc/arch/m68k/gen/isnormall.c27
-rw-r--r--lib/libc/arch/m88k/gdtoa/Makefile.inc3
-rw-r--r--lib/libc/arch/m88k/gdtoa/arith.h2
-rw-r--r--lib/libc/arch/m88k/gdtoa/gd_qnan.h12
-rw-r--r--lib/libc/arch/m88k/gdtoa/strtold.c45
-rw-r--r--lib/libc/arch/m88k/gen/Makefile.inc3
-rw-r--r--lib/libc/arch/m88k/gen/fpclassifyl.c44
-rw-r--r--lib/libc/arch/m88k/gen/isfinitel.c27
-rw-r--r--lib/libc/arch/m88k/gen/isinfl.c30
-rw-r--r--lib/libc/arch/m88k/gen/isnanl.c30
-rw-r--r--lib/libc/arch/m88k/gen/isnormall.c27
-rw-r--r--lib/libc/arch/mips64/gdtoa/Makefile.inc3
-rw-r--r--lib/libc/arch/mips64/gdtoa/arith.h6
-rw-r--r--lib/libc/arch/mips64/gdtoa/gd_qnan.h12
-rw-r--r--lib/libc/arch/mips64/gdtoa/strtold.c45
-rw-r--r--lib/libc/arch/mips64/gen/Makefile.inc3
-rw-r--r--lib/libc/arch/mips64/gen/fpclassifyl.c44
-rw-r--r--lib/libc/arch/mips64/gen/isfinitel.c27
-rw-r--r--lib/libc/arch/mips64/gen/isinfl.c29
-rw-r--r--lib/libc/arch/mips64/gen/isnanl.c29
-rw-r--r--lib/libc/arch/mips64/gen/isnormall.c27
-rw-r--r--lib/libc/arch/mips64/gen/nan.c6
-rw-r--r--lib/libc/arch/powerpc/gdtoa/Makefile.inc3
-rw-r--r--lib/libc/arch/powerpc/gdtoa/arith.h3
-rw-r--r--lib/libc/arch/powerpc/gdtoa/gd_qnan.h12
-rw-r--r--lib/libc/arch/sh/gdtoa/Makefile.inc3
-rw-r--r--lib/libc/arch/sh/gdtoa/arith.h3
-rw-r--r--lib/libc/arch/sh/gdtoa/gd_qnan.h12
-rw-r--r--lib/libc/arch/sparc/gdtoa/Makefile.inc3
-rw-r--r--lib/libc/arch/sparc/gdtoa/arith.h3
-rw-r--r--lib/libc/arch/sparc/gdtoa/gd_qnan.h12
-rw-r--r--lib/libc/arch/sparc/gdtoa/strtold.c45
-rw-r--r--lib/libc/arch/sparc/gen/Makefile.inc3
-rw-r--r--lib/libc/arch/sparc/gen/fpclassifyl.c44
-rw-r--r--lib/libc/arch/sparc/gen/isfinitel.c27
-rw-r--r--lib/libc/arch/sparc/gen/isinfl.c29
-rw-r--r--lib/libc/arch/sparc/gen/isnanl.c29
-rw-r--r--lib/libc/arch/sparc/gen/isnormall.c27
-rw-r--r--lib/libc/arch/sparc64/gdtoa/Makefile.inc3
-rw-r--r--lib/libc/arch/sparc64/gdtoa/arith.h6
-rw-r--r--lib/libc/arch/sparc64/gdtoa/gd_qnan.h12
-rw-r--r--lib/libc/arch/sparc64/gdtoa/strtold.c45
-rw-r--r--lib/libc/arch/sparc64/gen/Makefile.inc3
-rw-r--r--lib/libc/arch/sparc64/gen/fpclassifyl.c44
-rw-r--r--lib/libc/arch/sparc64/gen/isfinitel.c27
-rw-r--r--lib/libc/arch/sparc64/gen/isinfl.c29
-rw-r--r--lib/libc/arch/sparc64/gen/isnanl.c29
-rw-r--r--lib/libc/arch/sparc64/gen/isnormall.c27
-rw-r--r--lib/libc/arch/vax/gdtoa/Makefile.inc3
-rw-r--r--lib/libc/arch/vax/gdtoa/arith.h2
-rw-r--r--lib/libc/arch/vax/gdtoa/gd_qnan.h0
-rw-r--r--lib/libc/arch/vax/gdtoa/hdtoa.c224
-rw-r--r--lib/libc/arch/vax/gdtoa/strtof.c67
-rw-r--r--lib/libc/gdtoa/Makefile.inc17
-rw-r--r--lib/libc/gdtoa/arithchk.c183
-rw-r--r--lib/libc/gdtoa/dmisc.c216
-rw-r--r--lib/libc/gdtoa/dtoa.c753
-rw-r--r--lib/libc/gdtoa/g_Qfmt.c114
-rw-r--r--lib/libc/gdtoa/g__fmt.c99
-rw-r--r--lib/libc/gdtoa/g_ddfmt.c154
-rw-r--r--lib/libc/gdtoa/g_dfmt.c89
-rw-r--r--lib/libc/gdtoa/g_ffmt.c88
-rw-r--r--lib/libc/gdtoa/g_xLfmt.c108
-rw-r--r--lib/libc/gdtoa/g_xfmt.c114
-rw-r--r--lib/libc/gdtoa/gdtoa.c758
-rw-r--r--lib/libc/gdtoa/gdtoa.h153
-rw-r--r--lib/libc/gdtoa/gdtoaimp.h659
-rw-r--r--lib/libc/gdtoa/gethex.c250
-rw-r--r--lib/libc/gdtoa/gmisc.c86
-rw-r--r--lib/libc/gdtoa/hd_init.c55
-rw-r--r--lib/libc/gdtoa/hdtoa.c328
-rw-r--r--lib/libc/gdtoa/hexnan.c150
-rw-r--r--lib/libc/gdtoa/ldtoa.c124
-rw-r--r--lib/libc/gdtoa/locks.c7
-rw-r--r--lib/libc/gdtoa/misc.c865
-rw-r--r--lib/libc/gdtoa/qnan.c110
-rw-r--r--lib/libc/gdtoa/smisc.c191
-rw-r--r--lib/libc/gdtoa/strtoIQ.c63
-rw-r--r--lib/libc/gdtoa/strtoId.c60
-rw-r--r--lib/libc/gdtoa/strtoIdd.c66
-rw-r--r--lib/libc/gdtoa/strtoIf.c58
-rw-r--r--lib/libc/gdtoa/strtoIg.c133
-rw-r--r--lib/libc/gdtoa/strtoIx.c64
-rw-r--r--lib/libc/gdtoa/strtoIxL.c62
-rw-r--r--lib/libc/gdtoa/strtod.c982
-rw-r--r--lib/libc/gdtoa/strtodI.c167
-rw-r--r--lib/libc/gdtoa/strtodg.c1010
-rw-r--r--lib/libc/gdtoa/strtodnrp.c87
-rw-r--r--lib/libc/gdtoa/strtof.c73
-rw-r--r--lib/libc/gdtoa/strtold.c40
-rw-r--r--lib/libc/gdtoa/strtopQ.c101
-rw-r--r--lib/libc/gdtoa/strtopd.c49
-rw-r--r--lib/libc/gdtoa/strtopdd.c178
-rw-r--r--lib/libc/gdtoa/strtopf.c73
-rw-r--r--lib/libc/gdtoa/strtopx.c103
-rw-r--r--lib/libc/gdtoa/strtopxL.c91
-rw-r--r--lib/libc/gdtoa/strtorQ.c117
-rw-r--r--lib/libc/gdtoa/strtord.c93
-rw-r--r--lib/libc/gdtoa/strtordd.c199
-rw-r--r--lib/libc/gdtoa/strtorf.c89
-rw-r--r--lib/libc/gdtoa/strtorx.c119
-rw-r--r--lib/libc/gdtoa/strtorxL.c107
-rw-r--r--lib/libc/gdtoa/sum.c98
-rw-r--r--lib/libc/gdtoa/ulp.c70
-rw-r--r--lib/libc/gen/fpclassify.c28
-rw-r--r--lib/libc/gen/isfinite.c12
-rw-r--r--lib/libc/gen/isinf.c15
-rw-r--r--lib/libc/gen/isnan.c15
-rw-r--r--lib/libc/gen/isnormal.c12
-rw-r--r--lib/libc/stdio/floatio.h18
-rw-r--r--lib/libc/stdio/vfprintf.c356
-rw-r--r--lib/libc/stdlib/Makefile.inc4
-rw-r--r--lib/libc/stdlib/strtod.c2459
-rw-r--r--lib/libm/Makefile75
-rw-r--r--lib/libm/arch/amd64/e_acos.S4
-rw-r--r--lib/libm/arch/amd64/e_asin.S4
-rw-r--r--lib/libm/arch/amd64/e_atan2.S4
-rw-r--r--lib/libm/arch/amd64/e_atan2f.S4
-rw-r--r--lib/libm/arch/amd64/e_exp.S4
-rw-r--r--lib/libm/arch/amd64/e_fmod.S4
-rw-r--r--lib/libm/arch/amd64/e_log.S4
-rw-r--r--lib/libm/arch/amd64/e_log10.S4
-rw-r--r--lib/libm/arch/amd64/e_remainder.S4
-rw-r--r--lib/libm/arch/amd64/e_remainderf.S4
-rw-r--r--lib/libm/arch/amd64/e_scalb.S4
-rw-r--r--lib/libm/arch/amd64/e_sqrt.S4
-rw-r--r--lib/libm/arch/amd64/e_sqrtf.S4
-rw-r--r--lib/libm/arch/hppa/e_remainder.c4
-rw-r--r--lib/libm/arch/hppa/e_remainderf.c4
-rw-r--r--lib/libm/arch/hppa/e_sqrt.c4
-rw-r--r--lib/libm/arch/hppa/e_sqrtf.c4
-rw-r--r--lib/libm/arch/i387/e_acos.S4
-rw-r--r--lib/libm/arch/i387/e_asin.S4
-rw-r--r--lib/libm/arch/i387/e_atan2.S4
-rw-r--r--lib/libm/arch/i387/e_atan2f.S4
-rw-r--r--lib/libm/arch/i387/e_exp.S4
-rw-r--r--lib/libm/arch/i387/e_fmod.S4
-rw-r--r--lib/libm/arch/i387/e_log.S4
-rw-r--r--lib/libm/arch/i387/e_log10.S4
-rw-r--r--lib/libm/arch/i387/e_remainder.S4
-rw-r--r--lib/libm/arch/i387/e_remainderf.S4
-rw-r--r--lib/libm/arch/i387/e_scalb.S4
-rw-r--r--lib/libm/arch/i387/e_sqrt.S4
-rw-r--r--lib/libm/arch/i387/e_sqrtf.S4
-rw-r--r--lib/libm/arch/mc68881/e_acos.S4
-rw-r--r--lib/libm/arch/mc68881/e_asin.S4
-rw-r--r--lib/libm/arch/mc68881/e_atanh.S4
-rw-r--r--lib/libm/arch/mc68881/e_cosh.S4
-rw-r--r--lib/libm/arch/mc68881/e_exp.S4
-rw-r--r--lib/libm/arch/mc68881/e_log.S4
-rw-r--r--lib/libm/arch/mc68881/e_log10.S4
-rw-r--r--lib/libm/arch/mc68881/e_remainder.S4
-rw-r--r--lib/libm/arch/mc68881/e_scalb.S4
-rw-r--r--lib/libm/arch/mc68881/e_sinh.S4
-rw-r--r--lib/libm/arch/mc68881/e_sqrt.S4
-rw-r--r--lib/libm/shlib_version2
-rw-r--r--lib/libm/src/e_acos.c10
-rw-r--r--lib/libm/src/e_acosf.c6
-rw-r--r--lib/libm/src/e_acosh.c8
-rw-r--r--lib/libm/src/e_acoshf.c6
-rw-r--r--lib/libm/src/e_asin.c6
-rw-r--r--lib/libm/src/e_asinf.c4
-rw-r--r--lib/libm/src/e_atan2.c4
-rw-r--r--lib/libm/src/e_atan2f.c2
-rw-r--r--lib/libm/src/e_atanh.c4
-rw-r--r--lib/libm/src/e_atanhf.c2
-rw-r--r--lib/libm/src/e_cosh.c10
-rw-r--r--lib/libm/src/e_coshf.c8
-rw-r--r--lib/libm/src/e_exp.c4
-rw-r--r--lib/libm/src/e_expf.c2
-rw-r--r--lib/libm/src/e_fmod.c4
-rw-r--r--lib/libm/src/e_fmodf.c4
-rw-r--r--lib/libm/src/e_hypot.c8
-rw-r--r--lib/libm/src/e_hypotf.c6
-rw-r--r--lib/libm/src/e_j0.c10
-rw-r--r--lib/libm/src/e_j0f.c8
-rw-r--r--lib/libm/src/e_j1.c8
-rw-r--r--lib/libm/src/e_j1f.c6
-rw-r--r--lib/libm/src/e_jn.c26
-rw-r--r--lib/libm/src/e_jnf.c24
-rw-r--r--lib/libm/src/e_lgamma_r.c18
-rw-r--r--lib/libm/src/e_lgammaf_r.c16
-rw-r--r--lib/libm/src/e_log.c4
-rw-r--r--lib/libm/src/e_log10.c6
-rw-r--r--lib/libm/src/e_log10f.c4
-rw-r--r--lib/libm/src/e_log2.c74
-rw-r--r--lib/libm/src/e_log2f.c76
-rw-r--r--lib/libm/src/e_logf.c2
-rw-r--r--lib/libm/src/e_pow.c6
-rw-r--r--lib/libm/src/e_powf.c4
-rw-r--r--lib/libm/src/e_remainder.c6
-rw-r--r--lib/libm/src/e_remainderf.c4
-rw-r--r--lib/libm/src/e_scalb.c6
-rw-r--r--lib/libm/src/e_scalbf.c4
-rw-r--r--lib/libm/src/e_sinh.c8
-rw-r--r--lib/libm/src/e_sinhf.c6
-rw-r--r--lib/libm/src/e_sqrt.c4
-rw-r--r--lib/libm/src/e_sqrtf.c2
-rw-r--r--lib/libm/src/k_standard.c773
-rw-r--r--lib/libm/src/math_private.h64
-rw-r--r--lib/libm/src/s_asinh.c6
-rw-r--r--lib/libm/src/s_asinhf.c6
-rw-r--r--lib/libm/src/s_cabs.c25
-rw-r--r--lib/libm/src/s_cabsf.c (renamed from lib/libc/stdlib/strtof.c)24
-rw-r--r--lib/libm/src/s_cacos.c60
-rw-r--r--lib/libm/src/s_cacosf.c60
-rw-r--r--lib/libm/src/s_cacosh.c55
-rw-r--r--lib/libm/src/s_cacoshf.c55
-rw-r--r--lib/libm/src/s_carg.c25
-rw-r--r--lib/libm/src/s_cargf.c25
-rw-r--r--lib/libm/src/s_casin.c129
-rw-r--r--lib/libm/src/s_casinf.c132
-rw-r--r--lib/libm/src/s_casinh.c55
-rw-r--r--lib/libm/src/s_casinhf.c55
-rw-r--r--lib/libm/src/s_catan.c126
-rw-r--r--lib/libm/src/s_catanf.c124
-rw-r--r--lib/libm/src/s_catanh.c55
-rw-r--r--lib/libm/src/s_catanhf.c55
-rw-r--r--lib/libm/src/s_ccos.c84
-rw-r--r--lib/libm/src/s_ccosf.c84
-rw-r--r--lib/libm/src/s_ccosh.c58
-rw-r--r--lib/libm/src/s_ccoshf.c58
-rw-r--r--lib/libm/src/s_cexp.c70
-rw-r--r--lib/libm/src/s_cexpf.c67
-rw-r--r--lib/libm/src/s_cimag.c25
-rw-r--r--lib/libm/src/s_cimagf.c25
-rw-r--r--lib/libm/src/s_clog.c72
-rw-r--r--lib/libm/src/s_clogf.c72
-rw-r--r--lib/libm/src/s_conj.c25
-rw-r--r--lib/libm/src/s_conjf.c25
-rw-r--r--lib/libm/src/s_cpow.c71
-rw-r--r--lib/libm/src/s_cpowf.c71
-rw-r--r--lib/libm/src/s_cproj.c32
-rw-r--r--lib/libm/src/s_cprojf.c32
-rw-r--r--lib/libm/src/s_creal.c25
-rw-r--r--lib/libm/src/s_crealf.c25
-rw-r--r--lib/libm/src/s_csin.c86
-rw-r--r--lib/libm/src/s_csinf.c85
-rw-r--r--lib/libm/src/s_csinh.c57
-rw-r--r--lib/libm/src/s_csinhf.c57
-rw-r--r--lib/libm/src/s_csqrt.c131
-rw-r--r--lib/libm/src/s_csqrtf.c131
-rw-r--r--lib/libm/src/s_ctan.c152
-rw-r--r--lib/libm/src/s_ctanf.c148
-rw-r--r--lib/libm/src/s_ctanh.c59
-rw-r--r--lib/libm/src/s_ctanhf.c59
-rw-r--r--lib/libm/src/s_erf.c5
-rw-r--r--lib/libm/src/s_erff.c5
-rw-r--r--lib/libm/src/s_fdim.c44
-rw-r--r--lib/libm/src/s_fmax.c55
-rw-r--r--lib/libm/src/s_fmaxf.c51
-rw-r--r--lib/libm/src/s_fmin.c55
-rw-r--r--lib/libm/src/s_fminf.c51
-rw-r--r--lib/libm/src/s_lib_version.c39
-rw-r--r--lib/libm/src/s_matherr.c26
-rw-r--r--lib/libm/src/s_nan.c4
-rw-r--r--lib/libm/src/s_significand.c2
-rw-r--r--lib/libm/src/s_significandf.c2
-rw-r--r--lib/libm/src/w_acos.c38
-rw-r--r--lib/libm/src/w_acosf.c42
-rw-r--r--lib/libm/src/w_acosh.c38
-rw-r--r--lib/libm/src/w_acoshf.c43
-rw-r--r--lib/libm/src/w_asin.c39
-rw-r--r--lib/libm/src/w_asinf.c42
-rw-r--r--lib/libm/src/w_atan2.c38
-rw-r--r--lib/libm/src/w_atan2f.c42
-rw-r--r--lib/libm/src/w_atanh.c42
-rw-r--r--lib/libm/src/w_atanhf.c47
-rw-r--r--lib/libm/src/w_cabs.c19
-rw-r--r--lib/libm/src/w_cabsf.c20
-rw-r--r--lib/libm/src/w_cosh.c38
-rw-r--r--lib/libm/src/w_coshf.c42
-rw-r--r--lib/libm/src/w_exp.c45
-rw-r--r--lib/libm/src/w_expf.c50
-rw-r--r--lib/libm/src/w_fmod.c39
-rw-r--r--lib/libm/src/w_fmodf.c42
-rw-r--r--lib/libm/src/w_gamma.c15
-rw-r--r--lib/libm/src/w_gamma_r.c15
-rw-r--r--lib/libm/src/w_gammaf.c44
-rw-r--r--lib/libm/src/w_gammaf_r.c46
-rw-r--r--lib/libm/src/w_hypot.c38
-rw-r--r--lib/libm/src/w_hypotf.c42
-rw-r--r--lib/libm/src/w_j0.c61
-rw-r--r--lib/libm/src/w_j0f.c66
-rw-r--r--lib/libm/src/w_j1.c62
-rw-r--r--lib/libm/src/w_j1f.c67
-rw-r--r--lib/libm/src/w_jn.c84
-rw-r--r--lib/libm/src/w_jnf.c63
-rw-r--r--lib/libm/src/w_lgamma.c45
-rw-r--r--lib/libm/src/w_lgamma_r.c42
-rw-r--r--lib/libm/src/w_lgammaf.c44
-rw-r--r--lib/libm/src/w_lgammaf_r.c47
-rw-r--r--lib/libm/src/w_log.c38
-rw-r--r--lib/libm/src/w_log10.c41
-rw-r--r--lib/libm/src/w_log10f.c46
-rw-r--r--lib/libm/src/w_logf.c43
-rw-r--r--lib/libm/src/w_pow.c56
-rw-r--r--lib/libm/src/w_powf.c67
-rw-r--r--lib/libm/src/w_remainder.c38
-rw-r--r--lib/libm/src/w_remainderf.c42
-rw-r--r--lib/libm/src/w_scalb.c52
-rw-r--r--lib/libm/src/w_scalbf.c57
-rw-r--r--lib/libm/src/w_sinh.c38
-rw-r--r--lib/libm/src/w_sinhf.c42
-rw-r--r--lib/libm/src/w_sqrt.c38
-rw-r--r--lib/libm/src/w_sqrtf.c42
-rw-r--r--regress/lib/libc/Makefile8
-rw-r--r--regress/lib/libc/fpclassify/Makefile5
-rw-r--r--regress/lib/libc/fpclassify/fpclassify.c76
-rw-r--r--regress/lib/libc/printf/Makefile5
-rw-r--r--regress/lib/libc/printf/fp.c217
-rw-r--r--regress/lib/libm/tgamma/tgamma.c14
-rw-r--r--sys/arch/alpha/include/ieee.h4
-rw-r--r--sys/arch/amd64/include/ieee.h19
-rw-r--r--sys/arch/arm/include/ieee.h10
-rw-r--r--sys/arch/hppa/include/ieee.h19
-rw-r--r--sys/arch/hppa64/include/ieee.h17
-rw-r--r--sys/arch/i386/include/ieee.h18
-rw-r--r--sys/arch/m68k/include/float.h28
-rw-r--r--sys/arch/m68k/include/ieee.h14
-rw-r--r--sys/arch/m88k/include/float.h28
-rw-r--r--sys/arch/m88k/include/ieee.h14
-rw-r--r--sys/arch/mips64/include/float.h28
-rw-r--r--sys/arch/mips64/include/ieee.h17
-rw-r--r--sys/arch/powerpc/include/ieee.h19
-rw-r--r--sys/arch/sh/include/ieee.h19
-rw-r--r--sys/arch/sparc/include/ieee.h17
-rw-r--r--sys/arch/sparc64/include/ieee.h17
381 files changed, 16633 insertions, 6239 deletions
diff --git a/include/Makefile b/include/Makefile
index d4ff6feb66b..13ea9e5629e 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.145 2008/08/22 13:02:53 kettenis Exp $
+# $OpenBSD: Makefile,v 1.146 2008/09/07 20:36:07 martynas Exp $
# $NetBSD: Makefile,v 1.59 1996/05/15 21:36:43 jtc Exp $
# @(#)Makefile 5.45.1.1 (Berkeley) 5/6/91
@@ -12,7 +12,7 @@ USE_GCC3?=No
# Missing: mp.h
FILES= a.out.h ar.h assert.h bitstring.h blf.h bm.h bsd_auth.h cast.h \
- cpio.h ctype.h curses.h db.h dbm.h des.h dirent.h disktab.h \
+ complex.h cpio.h ctype.h curses.h db.h dbm.h des.h dirent.h disktab.h \
dlfcn.h elf_abi.h err.h errno.h fnmatch.h fstab.h fts.h ftw.h getopt.h \
glob.h grp.h ifaddrs.h inttypes.h iso646.h kvm.h langinfo.h \
libgen.h limits.h locale.h login_cap.h malloc.h math.h md4.h \
diff --git a/include/complex.h b/include/complex.h
new file mode 100644
index 00000000000..36cc3f9994b
--- /dev/null
+++ b/include/complex.h
@@ -0,0 +1,122 @@
+/* $OpenBSD: complex.h,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+#ifndef _COMPLEX_H_
+#define _COMPLEX_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * C99
+ */
+#ifdef __GNUC__
+#if __STDC_VERSION__ < 199901
+#define _Complex __complex__
+#endif
+#define _Complex_I 1.0fi
+#endif
+
+#define complex _Complex
+
+/* XXX switch to _Imaginary_I */
+#undef I
+#define I _Complex_I
+
+__BEGIN_DECLS
+/*
+ * Double versions of C99 functions
+ */
+double complex cacos(double complex);
+double complex casin(double complex);
+double complex catan(double complex);
+double complex ccos(double complex);
+double complex csin(double complex);
+double complex ctan(double complex);
+double complex cacosh(double complex);
+double complex casinh(double complex);
+double complex catanh(double complex);
+double complex ccosh(double complex);
+double complex csinh(double complex);
+double complex ctanh(double complex);
+double complex cexp(double complex);
+double complex clog(double complex);
+double cabs(double complex);
+double complex cpow(double complex, double complex);
+double complex csqrt(double complex);
+double carg(double complex);
+double cimag(double complex);
+double complex conj(double complex);
+double complex cproj(double complex);
+double creal(double complex);
+
+/*
+ * Float versions of C99 functions
+ */
+float complex cacosf(float complex);
+float complex casinf(float complex);
+float complex catanf(float complex);
+float complex ccosf(float complex);
+float complex csinf(float complex);
+float complex ctanf(float complex);
+float complex cacoshf(float complex);
+float complex casinhf(float complex);
+float complex catanhf(float complex);
+float complex ccoshf(float complex);
+float complex csinhf(float complex);
+float complex ctanhf(float complex);
+float complex cexpf(float complex);
+float complex clogf(float complex);
+float cabsf(float complex);
+float complex cpowf(float complex, float complex);
+float complex csqrtf(float complex);
+float cargf(float complex);
+float cimagf(float complex);
+float complex conjf(float complex);
+float complex cprojf(float complex);
+float crealf(float complex);
+
+/*
+ * Long double versions of C99 functions
+ */
+#if 0
+long double complex cacosl(long double complex);
+long double complex casinl(long double complex);
+long double complex catanl(long double complex);
+long double complex ccosl(long double complex);
+long double complex csinl(long double complex);
+long double complex ctanl(long double complex);
+long double complex cacoshl(long double complex);
+long double complex casinhl(long double complex);
+long double complex catanhl(long double complex);
+long double complex ccoshl(long double complex);
+long double complex csinhl(long double complex);
+long double complex ctanhl(long double complex);
+long double complex cexpl(long double complex);
+long double complex clogl(long double complex);
+long double cabsl(long double complex);
+long double complex cpowl(long double complex,
+ long double complex);
+long double complex csqrtl(long double complex);
+long double cargl(long double complex);
+long double cimagl(long double complex);
+long double complex conjl(long double complex);
+long double complex cprojl(long double complex);
+long double creall(long double complex);
+#endif
+__END_DECLS
+
+#endif _COMPLEX_H_ /* !_COMPLEX_H_ */
diff --git a/include/math.h b/include/math.h
index ba64e75117c..bb953739684 100644
--- a/include/math.h
+++ b/include/math.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: math.h,v 1.20 2008/07/24 09:41:58 martynas Exp $ */
+/* $OpenBSD: math.h,v 1.21 2008/09/07 20:36:07 martynas Exp $ */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -63,18 +63,6 @@ extern char __nan[];
: (sizeof (x) == sizeof (double)) ? \
__isfinite(x) \
: __isfinitel(x))
-#define isinf(x) \
- ((sizeof (x) == sizeof (float)) ? \
- isinff(x) \
- : (sizeof (x) == sizeof (double)) ? \
- __isinf(x) \
- : __isinfl(x))
-#define isnan(x) \
- ((sizeof (x) == sizeof (float)) ? \
- isnanf(x) \
- : (sizeof (x) == sizeof (double)) ? \
- __isnan(x) \
- : __isnanl(x))
#define isnormal(x) \
((sizeof (x) == sizeof (float)) ? \
__isnormalf(x) \
@@ -97,6 +85,19 @@ extern char __nan[];
#define isunordered(x, y) (isnan(x) || isnan(y))
#endif /* __ISO_C_VISIBLE >= 1999 */
+#define isinf(x) \
+ ((sizeof (x) == sizeof (float)) ? \
+ isinff(x) \
+ : (sizeof (x) == sizeof (double)) ? \
+ __isinf(x) \
+ : __isinfl(x))
+#define isnan(x) \
+ ((sizeof (x) == sizeof (float)) ? \
+ isnanf(x) \
+ : (sizeof (x) == sizeof (double)) ? \
+ __isnan(x) \
+ : __isnanl(x))
+
/*
* XOPEN/SVID
*/
@@ -125,51 +126,7 @@ extern int signgam;
#endif /* __BSD_VISIBLE || __XPG_VISIBLE */
#if __BSD_VISIBLE
-enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix};
-
-#define _LIB_VERSION_TYPE enum fdversion
-#define _LIB_VERSION _fdlib_version
-
-/* if global variable _LIB_VERSION is not desirable, one may
- * change the following to be a constant by:
- * #define _LIB_VERSION_TYPE const enum version
- * In that case, after one initializes the value _LIB_VERSION (see
- * s_lib_version.c) during compile time, it cannot be modified
- * in the middle of a program
- */
-extern _LIB_VERSION_TYPE _LIB_VERSION;
-
-#define _IEEE_ fdlibm_ieee
-#define _SVID_ fdlibm_svid
-#define _XOPEN_ fdlibm_xopen
-#define _POSIX_ fdlibm_posix
-
-#ifndef __cplusplus
-struct exception {
- int type;
- char *name;
- double arg1;
- double arg2;
- double retval;
-};
-#endif /* !__cplusplus */
-
#define HUGE MAXFLOAT
-
-/*
- * set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
- * (one may replace the following line by "#include <values.h>")
- */
-
-#define X_TLOSS 1.41484755040568800000e+16
-
-#define DOMAIN 1
-#define SING 2
-#define OVERFLOW 3
-#define UNDERFLOW 4
-#define TLOSS 5
-#define PLOSS 6
-
#endif /* __BSD_VISIBLE */
__BEGIN_DECLS
@@ -215,9 +172,7 @@ extern double exp2(double);
extern double expm1(double);
extern int ilogb(double);
extern double log1p(double);
-#if 0
extern double log2(double);
-#endif
extern double logb(double);
extern double scalbn(double, int);
#if 0
@@ -253,11 +208,9 @@ extern double nextafter(double, double);
extern double nexttoward(double, long double);
#endif
-#if 0
extern double fdim(double, double);
extern double fmax(double, double);
extern double fmin(double, double);
-#endif
#if 0
extern double fma(double, double, double);
@@ -292,10 +245,6 @@ extern int finite(double);
extern double gamma_r(double, int *);
extern double lgamma_r(double, int *);
-#ifdef __LIBM_PRIVATE
-extern int matherr(struct exception *);
-#endif /* __LIBM_PRIVATE */
-
/*
* IEEE Test Vector
*/
@@ -375,11 +324,9 @@ extern float nextafterf(float, float);
extern float nexttowardf(float, long double);
#endif
-#if 0
extern float fdimf(float, float);
extern float fmaxf(float, float);
extern float fminf(float, float);
-#endif
#if 0
extern float fmaf(float, float, float);
diff --git a/include/stdlib.h b/include/stdlib.h
index bd1a28386b8..496090a50db 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: stdlib.h,v 1.44 2008/06/24 06:01:33 otto Exp $ */
+/* $OpenBSD: stdlib.h,v 1.45 2008/09/07 20:36:07 martynas Exp $ */
/* $NetBSD: stdlib.h,v 1.25 1995/12/27 21:19:08 jtc Exp $ */
/*-
@@ -132,6 +132,8 @@ void srand(unsigned);
double strtod(const char *, char **);
float strtof(const char *, char **);
long strtol(const char *, char **, int);
+long double
+ strtold(const char *, char **);
unsigned long
strtoul(const char *, char **, int);
int system(const char *);
diff --git a/lib/libc/Makefile.inc b/lib/libc/Makefile.inc
index 2530ec86a47..cd3e853efd5 100644
--- a/lib/libc/Makefile.inc
+++ b/lib/libc/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.11 2005/06/17 20:37:31 drahn Exp $
+# $OpenBSD: Makefile.inc,v 1.12 2008/09/07 20:36:07 martynas Exp $
#
# This file contains make rules used to build libc
#
@@ -33,6 +33,7 @@ AINC+= -nostdinc -idirafter ${DESTDIR}/usr/include
.include "${LIBCSRCDIR}/compat-43/Makefile.inc"
.include "${LIBCSRCDIR}/gen/Makefile.inc"
.include "${LIBCSRCDIR}/crypt/Makefile.inc"
+.include "${LIBCSRCDIR}/gdtoa/Makefile.inc"
.include "${LIBCSRCDIR}/gmon/Makefile.inc"
.include "${LIBCSRCDIR}/hash/Makefile.inc"
.include "${LIBCSRCDIR}/locale/Makefile.inc"
diff --git a/lib/libc/arch/alpha/gdtoa/Makefile.inc b/lib/libc/arch/alpha/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..b74c512bc69
--- /dev/null
+++ b/lib/libc/arch/alpha/gdtoa/Makefile.inc
@@ -0,0 +1,3 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $
+
+SRCS+= strtord.c
diff --git a/lib/libc/arch/alpha/gdtoa/arith.h b/lib/libc/arch/alpha/gdtoa/arith.h
new file mode 100644
index 00000000000..32513b96e90
--- /dev/null
+++ b/lib/libc/arch/alpha/gdtoa/arith.h
@@ -0,0 +1,6 @@
+#define IEEE_8087
+#define Arith_Kind_ASL 1
+#define Long int
+#define Intcast (int)(long)
+#define Double_Align
+#define X64_bit_pointers
diff --git a/lib/libc/arch/alpha/gdtoa/gd_qnan.h b/lib/libc/arch/alpha/gdtoa/gd_qnan.h
new file mode 100644
index 00000000000..99313b9adca
--- /dev/null
+++ b/lib/libc/arch/alpha/gdtoa/gd_qnan.h
@@ -0,0 +1,12 @@
+#define f_QNAN 0xffc00000
+#define d_QNAN0 0x0
+#define d_QNAN1 0xfff80000
+#define ld_QNAN0 0x0
+#define ld_QNAN1 0xfff80000
+#define ld_QNAN2 0x0
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0x0
+#define ldus_QNAN1 0x0
+#define ldus_QNAN2 0x0
+#define ldus_QNAN3 0xfff8
+#define ldus_QNAN4 0x0
diff --git a/lib/libc/arch/amd64/gdtoa/Makefile.inc b/lib/libc/arch/amd64/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..9b47fc51d00
--- /dev/null
+++ b/lib/libc/arch/amd64/gdtoa/Makefile.inc
@@ -0,0 +1,3 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $
+
+SRCS+= strtord.c strtorx.c
diff --git a/lib/libc/arch/amd64/gdtoa/arith.h b/lib/libc/arch/amd64/gdtoa/arith.h
new file mode 100644
index 00000000000..32513b96e90
--- /dev/null
+++ b/lib/libc/arch/amd64/gdtoa/arith.h
@@ -0,0 +1,6 @@
+#define IEEE_8087
+#define Arith_Kind_ASL 1
+#define Long int
+#define Intcast (int)(long)
+#define Double_Align
+#define X64_bit_pointers
diff --git a/lib/libc/arch/amd64/gdtoa/gd_qnan.h b/lib/libc/arch/amd64/gdtoa/gd_qnan.h
new file mode 100644
index 00000000000..87eba8fb319
--- /dev/null
+++ b/lib/libc/arch/amd64/gdtoa/gd_qnan.h
@@ -0,0 +1,12 @@
+#define f_QNAN 0xffc00000
+#define d_QNAN0 0x0
+#define d_QNAN1 0xfff80000
+#define ld_QNAN0 0x0
+#define ld_QNAN1 0xc0000000
+#define ld_QNAN2 0xffff
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0x0
+#define ldus_QNAN1 0x0
+#define ldus_QNAN2 0x0
+#define ldus_QNAN3 0xc000
+#define ldus_QNAN4 0xffff
diff --git a/lib/libc/arch/amd64/gdtoa/strtold.c b/lib/libc/arch/amd64/gdtoa/strtold.c
new file mode 100644
index 00000000000..20b50655348
--- /dev/null
+++ b/lib/libc/arch/amd64/gdtoa/strtold.c
@@ -0,0 +1,45 @@
+/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*-
+ * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * Machine-dependent glue to integrate David Gay's gdtoa
+ * package into libc for architectures where a long double
+ * is an IEEE extended precision number.
+ */
+
+#include <float.h>
+
+#include "gdtoaimp.h"
+
+long double
+strtold(const char * __restrict s, char ** __restrict sp)
+{
+ long double result;
+
+ strtorx(s, sp, FLT_ROUNDS, &result);
+ return result;
+}
diff --git a/lib/libc/arch/amd64/gen/Makefile.inc b/lib/libc/arch/amd64/gen/Makefile.inc
index 6358bd86c61..85b61ffe27c 100644
--- a/lib/libc/arch/amd64/gen/Makefile.inc
+++ b/lib/libc/arch/amd64/gen/Makefile.inc
@@ -1,7 +1,8 @@
-# $OpenBSD: Makefile.inc,v 1.4 2008/07/24 09:31:06 martynas Exp $
+# $OpenBSD: Makefile.inc,v 1.5 2008/09/07 20:36:07 martynas Exp $
SRCS+= _setjmp.S fabs.S infinity.c ldexp.c modf.S nan.c setjmp.S \
sigsetjmp.S
+SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c
SRCS+= flt_rounds.S fpgetmask.S fpgetround.S fpgetsticky.S fpsetmask.S \
fpsetround.S fpsetsticky.S
diff --git a/lib/libc/arch/amd64/gen/fpclassifyl.c b/lib/libc/arch/amd64/gen/fpclassifyl.c
new file mode 100644
index 00000000000..19940cdd53d
--- /dev/null
+++ b/lib/libc/arch/amd64/gen/fpclassifyl.c
@@ -0,0 +1,44 @@
+/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+int
+__fpclassifyl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ if (p->ext_exp == 0) {
+ if (p->ext_frach == 0 && p->ext_fracl == 0)
+ return FP_ZERO;
+ else
+ return FP_SUBNORMAL;
+ }
+
+ p->ext_frach &= ~0x80000000; /* clear normalization bit */
+
+ if (p->ext_exp == EXT_EXP_INFNAN) {
+ if (p->ext_frach == 0 && p->ext_fracl == 0)
+ return FP_INFINITE;
+ else
+ return FP_NAN;
+ }
+
+ return FP_NORMAL;
+}
diff --git a/lib/libc/arch/amd64/gen/isfinitel.c b/lib/libc/arch/amd64/gen/isfinitel.c
new file mode 100644
index 00000000000..c86b9309da4
--- /dev/null
+++ b/lib/libc/arch/amd64/gen/isfinitel.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isfinitel(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/amd64/gen/isinfl.c b/lib/libc/arch/amd64/gen/isinfl.c
new file mode 100644
index 00000000000..862c82f97e7
--- /dev/null
+++ b/lib/libc/arch/amd64/gen/isinfl.c
@@ -0,0 +1,30 @@
+/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isinfl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ p->ext_frach &= ~0x80000000; /* clear normalization bit */
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ p->ext_frach == 0 && p->ext_fracl == 0);
+}
diff --git a/lib/libc/arch/amd64/gen/isnanl.c b/lib/libc/arch/amd64/gen/isnanl.c
new file mode 100644
index 00000000000..4db08d62be6
--- /dev/null
+++ b/lib/libc/arch/amd64/gen/isnanl.c
@@ -0,0 +1,30 @@
+/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnanl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ p->ext_frach &= ~0x80000000; /* clear normalization bit */
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ (p->ext_frach != 0 || p->ext_fracl != 0));
+}
diff --git a/lib/libc/arch/amd64/gen/isnormall.c b/lib/libc/arch/amd64/gen/isnormall.c
new file mode 100644
index 00000000000..a8b4314afc9
--- /dev/null
+++ b/lib/libc/arch/amd64/gen/isnormall.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnormall(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/arm/gdtoa/Makefile.inc b/lib/libc/arch/arm/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..b74c512bc69
--- /dev/null
+++ b/lib/libc/arch/arm/gdtoa/Makefile.inc
@@ -0,0 +1,3 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $
+
+SRCS+= strtord.c
diff --git a/lib/libc/arch/arm/gdtoa/arith.h b/lib/libc/arch/arm/gdtoa/arith.h
new file mode 100644
index 00000000000..76539f82b9d
--- /dev/null
+++ b/lib/libc/arch/arm/gdtoa/arith.h
@@ -0,0 +1,2 @@
+#define IEEE_8087
+#define Arith_Kind_ASL 1
diff --git a/lib/libc/arch/arm/gdtoa/gd_qnan.h b/lib/libc/arch/arm/gdtoa/gd_qnan.h
new file mode 100644
index 00000000000..9c59e795bf6
--- /dev/null
+++ b/lib/libc/arch/arm/gdtoa/gd_qnan.h
@@ -0,0 +1,12 @@
+#define f_QNAN 0xffffffff
+#define d_QNAN0 0xffffffff
+#define d_QNAN1 0xffffffff
+#define ld_QNAN0 0xffffffff
+#define ld_QNAN1 0xffffffff
+#define ld_QNAN2 0x0
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0xffff
+#define ldus_QNAN1 0xffff
+#define ldus_QNAN2 0xffff
+#define ldus_QNAN3 0xffff
+#define ldus_QNAN4 0x0
diff --git a/lib/libc/arch/hppa/gdtoa/Makefile.inc b/lib/libc/arch/hppa/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..b74c512bc69
--- /dev/null
+++ b/lib/libc/arch/hppa/gdtoa/Makefile.inc
@@ -0,0 +1,3 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $
+
+SRCS+= strtord.c
diff --git a/lib/libc/arch/hppa/gdtoa/arith.h b/lib/libc/arch/hppa/gdtoa/arith.h
new file mode 100644
index 00000000000..e1954befb99
--- /dev/null
+++ b/lib/libc/arch/hppa/gdtoa/arith.h
@@ -0,0 +1,3 @@
+#define IEEE_MC68k
+#define Arith_Kind_ASL 2
+#define Double_Align
diff --git a/lib/libc/arch/hppa/gdtoa/gd_qnan.h b/lib/libc/arch/hppa/gdtoa/gd_qnan.h
new file mode 100644
index 00000000000..7956000880b
--- /dev/null
+++ b/lib/libc/arch/hppa/gdtoa/gd_qnan.h
@@ -0,0 +1,12 @@
+#define f_QNAN 0x7fa00000
+#define d_QNAN0 0x7ff40000
+#define d_QNAN1 0x0
+#define ld_QNAN0 0x7ff40000
+#define ld_QNAN1 0x0
+#define ld_QNAN2 0x0
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0x7ff4
+#define ldus_QNAN1 0x0
+#define ldus_QNAN2 0x0
+#define ldus_QNAN3 0x0
+#define ldus_QNAN4 0x0
diff --git a/lib/libc/arch/hppa64/gdtoa/Makefile.inc b/lib/libc/arch/hppa64/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..08b45b067ed
--- /dev/null
+++ b/lib/libc/arch/hppa64/gdtoa/Makefile.inc
@@ -0,0 +1,3 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $
+
+SRCS+= strtorQ.c strtord.c
diff --git a/lib/libc/arch/hppa64/gdtoa/arith.h b/lib/libc/arch/hppa64/gdtoa/arith.h
new file mode 100644
index 00000000000..cf004954182
--- /dev/null
+++ b/lib/libc/arch/hppa64/gdtoa/arith.h
@@ -0,0 +1 @@
+/* TODO: put the proper definitions here. */
diff --git a/lib/libc/arch/hppa64/gdtoa/gd_qnan.h b/lib/libc/arch/hppa64/gdtoa/gd_qnan.h
new file mode 100644
index 00000000000..cf004954182
--- /dev/null
+++ b/lib/libc/arch/hppa64/gdtoa/gd_qnan.h
@@ -0,0 +1 @@
+/* TODO: put the proper definitions here. */
diff --git a/lib/libc/arch/hppa64/gdtoa/strtold.c b/lib/libc/arch/hppa64/gdtoa/strtold.c
new file mode 100644
index 00000000000..3a5e322f01a
--- /dev/null
+++ b/lib/libc/arch/hppa64/gdtoa/strtold.c
@@ -0,0 +1,45 @@
+/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*-
+ * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * Machine-dependent glue to integrate David Gay's gdtoa
+ * package into libc for architectures where a long double
+ * uses quad precision, such as sparc64.
+ */
+
+#include <float.h>
+
+#include "gdtoaimp.h"
+
+long double
+strtold(const char * __restrict s, char ** __restrict sp)
+{
+ long double result;
+
+ strtorQ(s, sp, FLT_ROUNDS, &result);
+ return result;
+}
diff --git a/lib/libc/arch/hppa64/gen/Makefile.inc b/lib/libc/arch/hppa64/gen/Makefile.inc
index 91a4d2e8ffd..c167e7e0bda 100644
--- a/lib/libc/arch/hppa64/gen/Makefile.inc
+++ b/lib/libc/arch/hppa64/gen/Makefile.inc
@@ -1,10 +1,11 @@
-# $OpenBSD: Makefile.inc,v 1.3 2008/07/24 09:31:06 martynas Exp $
+# $OpenBSD: Makefile.inc,v 1.4 2008/09/07 20:36:07 martynas Exp $
SRCS+= setjmp.S
SRCS+= fabs.c frexp.c ldexp.c
SRCS+= infinity.c nan.c setjmp.S
SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
fpsetround.c fpsetsticky.c
+SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c
SRCS+= modf.c
SRCS+= alloca.c
diff --git a/lib/libc/arch/hppa64/gen/fpclassifyl.c b/lib/libc/arch/hppa64/gen/fpclassifyl.c
new file mode 100644
index 00000000000..030e9c8aac4
--- /dev/null
+++ b/lib/libc/arch/hppa64/gen/fpclassifyl.c
@@ -0,0 +1,44 @@
+/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+int
+__fpclassifyl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ if (p->ext_exp == 0) {
+ if (p->ext_frach == 0 && p->ext_frachm == 0 &&
+ p->ext_fraclm == 0 && p->ext_fracl == 0)
+ return FP_ZERO;
+ else
+ return FP_SUBNORMAL;
+ }
+
+ if (p->ext_exp == EXT_EXP_INFNAN) {
+ if (p->ext_frach == 0 && p->ext_frachm == 0 &&
+ p->ext_fraclm == 0 && p->ext_fracl == 0)
+ return FP_INFINITE;
+ else
+ return FP_NAN;
+ }
+
+ return FP_NORMAL;
+}
diff --git a/lib/libc/arch/hppa64/gen/isfinitel.c b/lib/libc/arch/hppa64/gen/isfinitel.c
new file mode 100644
index 00000000000..c86b9309da4
--- /dev/null
+++ b/lib/libc/arch/hppa64/gen/isfinitel.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isfinitel(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/hppa64/gen/isinfl.c b/lib/libc/arch/hppa64/gen/isinfl.c
new file mode 100644
index 00000000000..c529a91cd2f
--- /dev/null
+++ b/lib/libc/arch/hppa64/gen/isinfl.c
@@ -0,0 +1,29 @@
+/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isinfl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ p->ext_frach == 0 && p->ext_frachm == 0 &&
+ p->ext_fraclm == 0 && p->ext_fracl == 0);
+}
diff --git a/lib/libc/arch/hppa64/gen/isnanl.c b/lib/libc/arch/hppa64/gen/isnanl.c
new file mode 100644
index 00000000000..1838fcfe3fa
--- /dev/null
+++ b/lib/libc/arch/hppa64/gen/isnanl.c
@@ -0,0 +1,29 @@
+/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnanl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ (p->ext_frach != 0 || p->ext_frachm != 0 ||
+ p->ext_fraclm != 0 || p->ext_fracl != 0));
+}
diff --git a/lib/libc/arch/hppa64/gen/isnormall.c b/lib/libc/arch/hppa64/gen/isnormall.c
new file mode 100644
index 00000000000..a8b4314afc9
--- /dev/null
+++ b/lib/libc/arch/hppa64/gen/isnormall.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnormall(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/i386/gdtoa/Makefile.inc b/lib/libc/arch/i386/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..9b47fc51d00
--- /dev/null
+++ b/lib/libc/arch/i386/gdtoa/Makefile.inc
@@ -0,0 +1,3 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $
+
+SRCS+= strtord.c strtorx.c
diff --git a/lib/libc/arch/i386/gdtoa/arith.h b/lib/libc/arch/i386/gdtoa/arith.h
new file mode 100644
index 00000000000..76539f82b9d
--- /dev/null
+++ b/lib/libc/arch/i386/gdtoa/arith.h
@@ -0,0 +1,2 @@
+#define IEEE_8087
+#define Arith_Kind_ASL 1
diff --git a/lib/libc/arch/i386/gdtoa/gd_qnan.h b/lib/libc/arch/i386/gdtoa/gd_qnan.h
new file mode 100644
index 00000000000..87eba8fb319
--- /dev/null
+++ b/lib/libc/arch/i386/gdtoa/gd_qnan.h
@@ -0,0 +1,12 @@
+#define f_QNAN 0xffc00000
+#define d_QNAN0 0x0
+#define d_QNAN1 0xfff80000
+#define ld_QNAN0 0x0
+#define ld_QNAN1 0xc0000000
+#define ld_QNAN2 0xffff
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0x0
+#define ldus_QNAN1 0x0
+#define ldus_QNAN2 0x0
+#define ldus_QNAN3 0xc000
+#define ldus_QNAN4 0xffff
diff --git a/lib/libc/arch/i386/gdtoa/strtold.c b/lib/libc/arch/i386/gdtoa/strtold.c
new file mode 100644
index 00000000000..20b50655348
--- /dev/null
+++ b/lib/libc/arch/i386/gdtoa/strtold.c
@@ -0,0 +1,45 @@
+/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*-
+ * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * Machine-dependent glue to integrate David Gay's gdtoa
+ * package into libc for architectures where a long double
+ * is an IEEE extended precision number.
+ */
+
+#include <float.h>
+
+#include "gdtoaimp.h"
+
+long double
+strtold(const char * __restrict s, char ** __restrict sp)
+{
+ long double result;
+
+ strtorx(s, sp, FLT_ROUNDS, &result);
+ return result;
+}
diff --git a/lib/libc/arch/i386/gen/Makefile.inc b/lib/libc/arch/i386/gen/Makefile.inc
index bafaa0e9d86..863c28d0d18 100644
--- a/lib/libc/arch/i386/gen/Makefile.inc
+++ b/lib/libc/arch/i386/gen/Makefile.inc
@@ -1,7 +1,8 @@
-# $OpenBSD: Makefile.inc,v 1.6 2008/07/24 09:31:06 martynas Exp $
+# $OpenBSD: Makefile.inc,v 1.7 2008/09/07 20:36:07 martynas Exp $
SRCS+= _setjmp.S alloca.S fabs.S infinity.c ldexp.c \
modf.S nan.c setjmp.S sigsetjmp.S
+SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c
SRCS+= flt_rounds.S fpgetmask.S fpgetround.S fpgetsticky.S fpsetmask.S \
fpsetround.S fpsetsticky.S
SRCS+= divsi3.S fixdfsi.S fixunsdfsi.S udivsi3.S
diff --git a/lib/libc/arch/i386/gen/fpclassifyl.c b/lib/libc/arch/i386/gen/fpclassifyl.c
new file mode 100644
index 00000000000..19940cdd53d
--- /dev/null
+++ b/lib/libc/arch/i386/gen/fpclassifyl.c
@@ -0,0 +1,44 @@
+/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+int
+__fpclassifyl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ if (p->ext_exp == 0) {
+ if (p->ext_frach == 0 && p->ext_fracl == 0)
+ return FP_ZERO;
+ else
+ return FP_SUBNORMAL;
+ }
+
+ p->ext_frach &= ~0x80000000; /* clear normalization bit */
+
+ if (p->ext_exp == EXT_EXP_INFNAN) {
+ if (p->ext_frach == 0 && p->ext_fracl == 0)
+ return FP_INFINITE;
+ else
+ return FP_NAN;
+ }
+
+ return FP_NORMAL;
+}
diff --git a/lib/libc/arch/i386/gen/isfinitel.c b/lib/libc/arch/i386/gen/isfinitel.c
new file mode 100644
index 00000000000..c86b9309da4
--- /dev/null
+++ b/lib/libc/arch/i386/gen/isfinitel.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isfinitel(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/i386/gen/isinfl.c b/lib/libc/arch/i386/gen/isinfl.c
new file mode 100644
index 00000000000..862c82f97e7
--- /dev/null
+++ b/lib/libc/arch/i386/gen/isinfl.c
@@ -0,0 +1,30 @@
+/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isinfl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ p->ext_frach &= ~0x80000000; /* clear normalization bit */
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ p->ext_frach == 0 && p->ext_fracl == 0);
+}
diff --git a/lib/libc/arch/i386/gen/isnanl.c b/lib/libc/arch/i386/gen/isnanl.c
new file mode 100644
index 00000000000..4db08d62be6
--- /dev/null
+++ b/lib/libc/arch/i386/gen/isnanl.c
@@ -0,0 +1,30 @@
+/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnanl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ p->ext_frach &= ~0x80000000; /* clear normalization bit */
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ (p->ext_frach != 0 || p->ext_fracl != 0));
+}
diff --git a/lib/libc/arch/i386/gen/isnormall.c b/lib/libc/arch/i386/gen/isnormall.c
new file mode 100644
index 00000000000..a8b4314afc9
--- /dev/null
+++ b/lib/libc/arch/i386/gen/isnormall.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnormall(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/m68k/gdtoa/Makefile.inc b/lib/libc/arch/m68k/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..9b47fc51d00
--- /dev/null
+++ b/lib/libc/arch/m68k/gdtoa/Makefile.inc
@@ -0,0 +1,3 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $
+
+SRCS+= strtord.c strtorx.c
diff --git a/lib/libc/arch/m68k/gdtoa/arith.h b/lib/libc/arch/m68k/gdtoa/arith.h
new file mode 100644
index 00000000000..d16e11448ef
--- /dev/null
+++ b/lib/libc/arch/m68k/gdtoa/arith.h
@@ -0,0 +1,2 @@
+#define IEEE_MC68k
+#define Arith_Kind_ASL 2
diff --git a/lib/libc/arch/m68k/gdtoa/gd_qnan.h b/lib/libc/arch/m68k/gdtoa/gd_qnan.h
new file mode 100644
index 00000000000..a660b1f623b
--- /dev/null
+++ b/lib/libc/arch/m68k/gdtoa/gd_qnan.h
@@ -0,0 +1,12 @@
+#define f_QNAN 0x7fffffff
+#define d_QNAN0 0x7fffffff
+#define d_QNAN1 0xffffffff
+#define ld_QNAN0 0x7fff0000
+#define ld_QNAN1 0xffffffff
+#define ld_QNAN2 0xffffffff
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0x7fff
+#define ldus_QNAN1 0x0
+#define ldus_QNAN2 0xffff
+#define ldus_QNAN3 0xffff
+#define ldus_QNAN4 0xffff
diff --git a/lib/libc/arch/m68k/gdtoa/strtold.c b/lib/libc/arch/m68k/gdtoa/strtold.c
new file mode 100644
index 00000000000..20b50655348
--- /dev/null
+++ b/lib/libc/arch/m68k/gdtoa/strtold.c
@@ -0,0 +1,45 @@
+/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*-
+ * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * Machine-dependent glue to integrate David Gay's gdtoa
+ * package into libc for architectures where a long double
+ * is an IEEE extended precision number.
+ */
+
+#include <float.h>
+
+#include "gdtoaimp.h"
+
+long double
+strtold(const char * __restrict s, char ** __restrict sp)
+{
+ long double result;
+
+ strtorx(s, sp, FLT_ROUNDS, &result);
+ return result;
+}
diff --git a/lib/libc/arch/m68k/gen/Makefile.inc b/lib/libc/arch/m68k/gen/Makefile.inc
index 698f4debf45..ae4b21ae368 100644
--- a/lib/libc/arch/m68k/gen/Makefile.inc
+++ b/lib/libc/arch/m68k/gen/Makefile.inc
@@ -1,9 +1,10 @@
-# $OpenBSD: Makefile.inc,v 1.6 2008/07/24 09:31:06 martynas Exp $
+# $OpenBSD: Makefile.inc,v 1.7 2008/09/07 20:36:07 martynas Exp $
SRCS+= _setjmp.S fabs.S infinity.c ldexp.S \
modf.S nan.c setjmp.S sigsetjmp.S
SRCS+= flt_rounds.S fpgetmask.S fpgetround.S fpgetsticky.S fpsetmask.S \
fpsetround.S fpsetsticky.S
+SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c
SRCS+= adddf3.S addsf3.S ashlsi3.S ashrsi3.S cmpdf2.S cmpsf2.S divdf3.S \
divsf3.S divsi3.S extendsfdf2.S fixdfsi.S fixunsdfsi.S \
floatsidf.S lshlsi3.S lshrsi3.S modsi3.S muldf3.S mulsf3.S mulsi3.S \
diff --git a/lib/libc/arch/m68k/gen/fpclassifyl.c b/lib/libc/arch/m68k/gen/fpclassifyl.c
new file mode 100644
index 00000000000..19940cdd53d
--- /dev/null
+++ b/lib/libc/arch/m68k/gen/fpclassifyl.c
@@ -0,0 +1,44 @@
+/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+int
+__fpclassifyl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ if (p->ext_exp == 0) {
+ if (p->ext_frach == 0 && p->ext_fracl == 0)
+ return FP_ZERO;
+ else
+ return FP_SUBNORMAL;
+ }
+
+ p->ext_frach &= ~0x80000000; /* clear normalization bit */
+
+ if (p->ext_exp == EXT_EXP_INFNAN) {
+ if (p->ext_frach == 0 && p->ext_fracl == 0)
+ return FP_INFINITE;
+ else
+ return FP_NAN;
+ }
+
+ return FP_NORMAL;
+}
diff --git a/lib/libc/arch/m68k/gen/isfinitel.c b/lib/libc/arch/m68k/gen/isfinitel.c
new file mode 100644
index 00000000000..c86b9309da4
--- /dev/null
+++ b/lib/libc/arch/m68k/gen/isfinitel.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isfinitel(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/m68k/gen/isinfl.c b/lib/libc/arch/m68k/gen/isinfl.c
new file mode 100644
index 00000000000..862c82f97e7
--- /dev/null
+++ b/lib/libc/arch/m68k/gen/isinfl.c
@@ -0,0 +1,30 @@
+/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isinfl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ p->ext_frach &= ~0x80000000; /* clear normalization bit */
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ p->ext_frach == 0 && p->ext_fracl == 0);
+}
diff --git a/lib/libc/arch/m68k/gen/isnanl.c b/lib/libc/arch/m68k/gen/isnanl.c
new file mode 100644
index 00000000000..4db08d62be6
--- /dev/null
+++ b/lib/libc/arch/m68k/gen/isnanl.c
@@ -0,0 +1,30 @@
+/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnanl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ p->ext_frach &= ~0x80000000; /* clear normalization bit */
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ (p->ext_frach != 0 || p->ext_fracl != 0));
+}
diff --git a/lib/libc/arch/m68k/gen/isnormall.c b/lib/libc/arch/m68k/gen/isnormall.c
new file mode 100644
index 00000000000..a8b4314afc9
--- /dev/null
+++ b/lib/libc/arch/m68k/gen/isnormall.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnormall(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/m88k/gdtoa/Makefile.inc b/lib/libc/arch/m88k/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..9b47fc51d00
--- /dev/null
+++ b/lib/libc/arch/m88k/gdtoa/Makefile.inc
@@ -0,0 +1,3 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $
+
+SRCS+= strtord.c strtorx.c
diff --git a/lib/libc/arch/m88k/gdtoa/arith.h b/lib/libc/arch/m88k/gdtoa/arith.h
new file mode 100644
index 00000000000..d16e11448ef
--- /dev/null
+++ b/lib/libc/arch/m88k/gdtoa/arith.h
@@ -0,0 +1,2 @@
+#define IEEE_MC68k
+#define Arith_Kind_ASL 2
diff --git a/lib/libc/arch/m88k/gdtoa/gd_qnan.h b/lib/libc/arch/m88k/gdtoa/gd_qnan.h
new file mode 100644
index 00000000000..a660b1f623b
--- /dev/null
+++ b/lib/libc/arch/m88k/gdtoa/gd_qnan.h
@@ -0,0 +1,12 @@
+#define f_QNAN 0x7fffffff
+#define d_QNAN0 0x7fffffff
+#define d_QNAN1 0xffffffff
+#define ld_QNAN0 0x7fff0000
+#define ld_QNAN1 0xffffffff
+#define ld_QNAN2 0xffffffff
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0x7fff
+#define ldus_QNAN1 0x0
+#define ldus_QNAN2 0xffff
+#define ldus_QNAN3 0xffff
+#define ldus_QNAN4 0xffff
diff --git a/lib/libc/arch/m88k/gdtoa/strtold.c b/lib/libc/arch/m88k/gdtoa/strtold.c
new file mode 100644
index 00000000000..20b50655348
--- /dev/null
+++ b/lib/libc/arch/m88k/gdtoa/strtold.c
@@ -0,0 +1,45 @@
+/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*-
+ * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * Machine-dependent glue to integrate David Gay's gdtoa
+ * package into libc for architectures where a long double
+ * is an IEEE extended precision number.
+ */
+
+#include <float.h>
+
+#include "gdtoaimp.h"
+
+long double
+strtold(const char * __restrict s, char ** __restrict sp)
+{
+ long double result;
+
+ strtorx(s, sp, FLT_ROUNDS, &result);
+ return result;
+}
diff --git a/lib/libc/arch/m88k/gen/Makefile.inc b/lib/libc/arch/m88k/gen/Makefile.inc
index 62bf28c6c51..a6d82239bed 100644
--- a/lib/libc/arch/m88k/gen/Makefile.inc
+++ b/lib/libc/arch/m88k/gen/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.6 2008/07/24 09:31:06 martynas Exp $
+# $OpenBSD: Makefile.inc,v 1.7 2008/09/07 20:36:07 martynas Exp $
# $NetBSD: Makefile.inc,v 1.3 1995/04/10 21:09:06 jtc Exp $
#SRCS+= _setjmp.S fabs.S infinity.c ldexp.c modf.S nan.c
@@ -9,6 +9,7 @@
SRCS+= _setjmp.S fabs.S frexp.c infinity.c ldexp.c nan.c
SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
fpsetround.c fpsetsticky.c
+SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c
SRCS+= setjmp.S sigsetjmp.S
SRCS+= modf.c
diff --git a/lib/libc/arch/m88k/gen/fpclassifyl.c b/lib/libc/arch/m88k/gen/fpclassifyl.c
new file mode 100644
index 00000000000..19940cdd53d
--- /dev/null
+++ b/lib/libc/arch/m88k/gen/fpclassifyl.c
@@ -0,0 +1,44 @@
+/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+int
+__fpclassifyl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ if (p->ext_exp == 0) {
+ if (p->ext_frach == 0 && p->ext_fracl == 0)
+ return FP_ZERO;
+ else
+ return FP_SUBNORMAL;
+ }
+
+ p->ext_frach &= ~0x80000000; /* clear normalization bit */
+
+ if (p->ext_exp == EXT_EXP_INFNAN) {
+ if (p->ext_frach == 0 && p->ext_fracl == 0)
+ return FP_INFINITE;
+ else
+ return FP_NAN;
+ }
+
+ return FP_NORMAL;
+}
diff --git a/lib/libc/arch/m88k/gen/isfinitel.c b/lib/libc/arch/m88k/gen/isfinitel.c
new file mode 100644
index 00000000000..c86b9309da4
--- /dev/null
+++ b/lib/libc/arch/m88k/gen/isfinitel.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isfinitel(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/m88k/gen/isinfl.c b/lib/libc/arch/m88k/gen/isinfl.c
new file mode 100644
index 00000000000..862c82f97e7
--- /dev/null
+++ b/lib/libc/arch/m88k/gen/isinfl.c
@@ -0,0 +1,30 @@
+/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isinfl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ p->ext_frach &= ~0x80000000; /* clear normalization bit */
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ p->ext_frach == 0 && p->ext_fracl == 0);
+}
diff --git a/lib/libc/arch/m88k/gen/isnanl.c b/lib/libc/arch/m88k/gen/isnanl.c
new file mode 100644
index 00000000000..4db08d62be6
--- /dev/null
+++ b/lib/libc/arch/m88k/gen/isnanl.c
@@ -0,0 +1,30 @@
+/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnanl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ p->ext_frach &= ~0x80000000; /* clear normalization bit */
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ (p->ext_frach != 0 || p->ext_fracl != 0));
+}
diff --git a/lib/libc/arch/m88k/gen/isnormall.c b/lib/libc/arch/m88k/gen/isnormall.c
new file mode 100644
index 00000000000..a8b4314afc9
--- /dev/null
+++ b/lib/libc/arch/m88k/gen/isnormall.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnormall(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/mips64/gdtoa/Makefile.inc b/lib/libc/arch/mips64/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..9a21a743db8
--- /dev/null
+++ b/lib/libc/arch/mips64/gdtoa/Makefile.inc
@@ -0,0 +1,3 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $
+
+SRCS+= strtord.c strtorQ.c
diff --git a/lib/libc/arch/mips64/gdtoa/arith.h b/lib/libc/arch/mips64/gdtoa/arith.h
new file mode 100644
index 00000000000..0b84f84f763
--- /dev/null
+++ b/lib/libc/arch/mips64/gdtoa/arith.h
@@ -0,0 +1,6 @@
+#define IEEE_MC68k
+#define Arith_Kind_ASL 2
+#define Long int
+#define Intcast (int)(long)
+#define Double_Align
+#define X64_bit_pointers
diff --git a/lib/libc/arch/mips64/gdtoa/gd_qnan.h b/lib/libc/arch/mips64/gdtoa/gd_qnan.h
new file mode 100644
index 00000000000..d65c5a53b7c
--- /dev/null
+++ b/lib/libc/arch/mips64/gdtoa/gd_qnan.h
@@ -0,0 +1,12 @@
+#define f_QNAN 0x7fbfffff
+#define d_QNAN0 0x7ff7ffff
+#define d_QNAN1 0xffffffff
+#define ld_QNAN0 0x7fff8000
+#define ld_QNAN1 0x0
+#define ld_QNAN2 0x0
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0x7fff
+#define ldus_QNAN1 0x8000
+#define ldus_QNAN2 0x0
+#define ldus_QNAN3 0x0
+#define ldus_QNAN4 0x0
diff --git a/lib/libc/arch/mips64/gdtoa/strtold.c b/lib/libc/arch/mips64/gdtoa/strtold.c
new file mode 100644
index 00000000000..3a5e322f01a
--- /dev/null
+++ b/lib/libc/arch/mips64/gdtoa/strtold.c
@@ -0,0 +1,45 @@
+/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*-
+ * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * Machine-dependent glue to integrate David Gay's gdtoa
+ * package into libc for architectures where a long double
+ * uses quad precision, such as sparc64.
+ */
+
+#include <float.h>
+
+#include "gdtoaimp.h"
+
+long double
+strtold(const char * __restrict s, char ** __restrict sp)
+{
+ long double result;
+
+ strtorQ(s, sp, FLT_ROUNDS, &result);
+ return result;
+}
diff --git a/lib/libc/arch/mips64/gen/Makefile.inc b/lib/libc/arch/mips64/gen/Makefile.inc
index 3063795496a..2098bcc4d93 100644
--- a/lib/libc/arch/mips64/gen/Makefile.inc
+++ b/lib/libc/arch/mips64/gen/Makefile.inc
@@ -1,8 +1,9 @@
-# $OpenBSD: Makefile.inc,v 1.5 2008/07/25 08:00:01 martynas Exp $
+# $OpenBSD: Makefile.inc,v 1.6 2008/09/07 20:36:07 martynas Exp $
SRCS+= _setjmp.S fabs.S infinity.c ldexp.S modf.S nan.c
SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
fpsetround.c fpsetsticky.c
+SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c
SRCS+= setjmp.S sigsetjmp.S
SRCS+= alloca.c
diff --git a/lib/libc/arch/mips64/gen/fpclassifyl.c b/lib/libc/arch/mips64/gen/fpclassifyl.c
new file mode 100644
index 00000000000..030e9c8aac4
--- /dev/null
+++ b/lib/libc/arch/mips64/gen/fpclassifyl.c
@@ -0,0 +1,44 @@
+/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+int
+__fpclassifyl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ if (p->ext_exp == 0) {
+ if (p->ext_frach == 0 && p->ext_frachm == 0 &&
+ p->ext_fraclm == 0 && p->ext_fracl == 0)
+ return FP_ZERO;
+ else
+ return FP_SUBNORMAL;
+ }
+
+ if (p->ext_exp == EXT_EXP_INFNAN) {
+ if (p->ext_frach == 0 && p->ext_frachm == 0 &&
+ p->ext_fraclm == 0 && p->ext_fracl == 0)
+ return FP_INFINITE;
+ else
+ return FP_NAN;
+ }
+
+ return FP_NORMAL;
+}
diff --git a/lib/libc/arch/mips64/gen/isfinitel.c b/lib/libc/arch/mips64/gen/isfinitel.c
new file mode 100644
index 00000000000..c86b9309da4
--- /dev/null
+++ b/lib/libc/arch/mips64/gen/isfinitel.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isfinitel(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/mips64/gen/isinfl.c b/lib/libc/arch/mips64/gen/isinfl.c
new file mode 100644
index 00000000000..c529a91cd2f
--- /dev/null
+++ b/lib/libc/arch/mips64/gen/isinfl.c
@@ -0,0 +1,29 @@
+/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isinfl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ p->ext_frach == 0 && p->ext_frachm == 0 &&
+ p->ext_fraclm == 0 && p->ext_fracl == 0);
+}
diff --git a/lib/libc/arch/mips64/gen/isnanl.c b/lib/libc/arch/mips64/gen/isnanl.c
new file mode 100644
index 00000000000..1838fcfe3fa
--- /dev/null
+++ b/lib/libc/arch/mips64/gen/isnanl.c
@@ -0,0 +1,29 @@
+/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnanl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ (p->ext_frach != 0 || p->ext_frachm != 0 ||
+ p->ext_fraclm != 0 || p->ext_fracl != 0));
+}
diff --git a/lib/libc/arch/mips64/gen/isnormall.c b/lib/libc/arch/mips64/gen/isnormall.c
new file mode 100644
index 00000000000..a8b4314afc9
--- /dev/null
+++ b/lib/libc/arch/mips64/gen/isnormall.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnormall(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/mips64/gen/nan.c b/lib/libc/arch/mips64/gen/nan.c
index 62f2e1ad916..73ebf3b9a0f 100644
--- a/lib/libc/arch/mips64/gen/nan.c
+++ b/lib/libc/arch/mips64/gen/nan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nan.c,v 1.1 2008/07/24 09:31:06 martynas Exp $ */
+/* $OpenBSD: nan.c,v 1.2 2008/09/07 20:36:07 martynas Exp $ */
/* Written by Martynas Venckus. Public Domain. */
@@ -9,7 +9,7 @@
/* bytes for qNaN on a mips64 (IEEE single format) */
char __nan[] __attribute__((__aligned__(sizeof(float)))) =
#if BYTE_ORDER == BIG_ENDIAN
- { 0x7f, 0xa0, 0, 0 };
+ { 0x7f, 0xc0, 0, 0 };
#else /* BYTE_ORDER == BIG_ENDIAN */
- { 0, 0, 0xa0, 0x7f };
+ { 0, 0, 0xc0, 0x7f };
#endif /* BYTE_ORDER == BIG_ENDIAN */
diff --git a/lib/libc/arch/powerpc/gdtoa/Makefile.inc b/lib/libc/arch/powerpc/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..b74c512bc69
--- /dev/null
+++ b/lib/libc/arch/powerpc/gdtoa/Makefile.inc
@@ -0,0 +1,3 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $
+
+SRCS+= strtord.c
diff --git a/lib/libc/arch/powerpc/gdtoa/arith.h b/lib/libc/arch/powerpc/gdtoa/arith.h
new file mode 100644
index 00000000000..e1954befb99
--- /dev/null
+++ b/lib/libc/arch/powerpc/gdtoa/arith.h
@@ -0,0 +1,3 @@
+#define IEEE_MC68k
+#define Arith_Kind_ASL 2
+#define Double_Align
diff --git a/lib/libc/arch/powerpc/gdtoa/gd_qnan.h b/lib/libc/arch/powerpc/gdtoa/gd_qnan.h
new file mode 100644
index 00000000000..3327dc12024
--- /dev/null
+++ b/lib/libc/arch/powerpc/gdtoa/gd_qnan.h
@@ -0,0 +1,12 @@
+#define f_QNAN 0x7fc00000
+#define d_QNAN0 0x7ff80000
+#define d_QNAN1 0x0
+#define ld_QNAN0 0x7ff80000
+#define ld_QNAN1 0x0
+#define ld_QNAN2 0x0
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0x7ff8
+#define ldus_QNAN1 0x0
+#define ldus_QNAN2 0x0
+#define ldus_QNAN3 0x0
+#define ldus_QNAN4 0x0
diff --git a/lib/libc/arch/sh/gdtoa/Makefile.inc b/lib/libc/arch/sh/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..b74c512bc69
--- /dev/null
+++ b/lib/libc/arch/sh/gdtoa/Makefile.inc
@@ -0,0 +1,3 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $
+
+SRCS+= strtord.c
diff --git a/lib/libc/arch/sh/gdtoa/arith.h b/lib/libc/arch/sh/gdtoa/arith.h
new file mode 100644
index 00000000000..ef6e7f4c433
--- /dev/null
+++ b/lib/libc/arch/sh/gdtoa/arith.h
@@ -0,0 +1,3 @@
+#define IEEE_8087
+#define Arith_Kind_ASL 1
+#define Sudden_Underflow
diff --git a/lib/libc/arch/sh/gdtoa/gd_qnan.h b/lib/libc/arch/sh/gdtoa/gd_qnan.h
new file mode 100644
index 00000000000..9bb017d51e0
--- /dev/null
+++ b/lib/libc/arch/sh/gdtoa/gd_qnan.h
@@ -0,0 +1,12 @@
+#define f_QNAN 0x7fbfffff
+#define d_QNAN0 0xffffffff
+#define d_QNAN1 0x7ff7ffff
+#define ld_QNAN0 0xffffffff
+#define ld_QNAN1 0x7ff7ffff
+#define ld_QNAN2 0x0
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0xffff
+#define ldus_QNAN1 0xffff
+#define ldus_QNAN2 0xffff
+#define ldus_QNAN3 0x7ff7
+#define ldus_QNAN4 0x0
diff --git a/lib/libc/arch/sparc/gdtoa/Makefile.inc b/lib/libc/arch/sparc/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..9a21a743db8
--- /dev/null
+++ b/lib/libc/arch/sparc/gdtoa/Makefile.inc
@@ -0,0 +1,3 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $
+
+SRCS+= strtord.c strtorQ.c
diff --git a/lib/libc/arch/sparc/gdtoa/arith.h b/lib/libc/arch/sparc/gdtoa/arith.h
new file mode 100644
index 00000000000..e1954befb99
--- /dev/null
+++ b/lib/libc/arch/sparc/gdtoa/arith.h
@@ -0,0 +1,3 @@
+#define IEEE_MC68k
+#define Arith_Kind_ASL 2
+#define Double_Align
diff --git a/lib/libc/arch/sparc/gdtoa/gd_qnan.h b/lib/libc/arch/sparc/gdtoa/gd_qnan.h
new file mode 100644
index 00000000000..b25361613d6
--- /dev/null
+++ b/lib/libc/arch/sparc/gdtoa/gd_qnan.h
@@ -0,0 +1,12 @@
+#define f_QNAN 0x7fffffff
+#define d_QNAN0 0x7fffffff
+#define d_QNAN1 0xffffffff
+#define ld_QNAN0 0x7fffffff
+#define ld_QNAN1 0xffffffff
+#define ld_QNAN2 0x0
+#define ld_QNAN3 0x0
+#define ldus_QNAN0 0x7fff
+#define ldus_QNAN1 0xffff
+#define ldus_QNAN2 0xffff
+#define ldus_QNAN3 0xffff
+#define ldus_QNAN4 0x0
diff --git a/lib/libc/arch/sparc/gdtoa/strtold.c b/lib/libc/arch/sparc/gdtoa/strtold.c
new file mode 100644
index 00000000000..3a5e322f01a
--- /dev/null
+++ b/lib/libc/arch/sparc/gdtoa/strtold.c
@@ -0,0 +1,45 @@
+/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */
+/*-
+ * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * Machine-dependent glue to integrate David Gay's gdtoa
+ * package into libc for architectures where a long double
+ * uses quad precision, such as sparc64.
+ */
+
+#include <float.h>
+
+#include "gdtoaimp.h"
+
+long double
+strtold(const char * __restrict s, char ** __restrict sp)
+{
+ long double result;
+
+ strtorQ(s, sp, FLT_ROUNDS, &result);
+ return result;
+}
diff --git a/lib/libc/arch/sparc/gen/Makefile.inc b/lib/libc/arch/sparc/gen/Makefile.inc
index 85710859f3b..4d0fcc097c8 100644
--- a/lib/libc/arch/sparc/gen/Makefile.inc
+++ b/lib/libc/arch/sparc/gen/Makefile.inc
@@ -1,8 +1,9 @@
-# $OpenBSD: Makefile.inc,v 1.6 2008/07/24 09:31:06 martynas Exp $
+# $OpenBSD: Makefile.inc,v 1.7 2008/09/07 20:36:08 martynas Exp $
SRCS+= _setjmp.S fabs.S infinity.c ldexp.c modf.S nan.c
SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
fpsetround.c fpsetsticky.c
+SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c
SRCS+= fixunsdfsi.S mul.S umul.S saveregs.S setjmp.S sigsetjmp.S
SRCS+= alloca.c
diff --git a/lib/libc/arch/sparc/gen/fpclassifyl.c b/lib/libc/arch/sparc/gen/fpclassifyl.c
new file mode 100644
index 00000000000..d569ef90430
--- /dev/null
+++ b/lib/libc/arch/sparc/gen/fpclassifyl.c
@@ -0,0 +1,44 @@
+/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+int
+__fpclassifyl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ if (p->ext_exp == 0) {
+ if (p->ext_frach == 0 && p->ext_frachm == 0 &&
+ p->ext_fraclm == 0 && p->ext_fracl == 0)
+ return FP_ZERO;
+ else
+ return FP_SUBNORMAL;
+ }
+
+ if (p->ext_exp == EXT_EXP_INFNAN) {
+ if (p->ext_frach == 0 && p->ext_frachm == 0 &&
+ p->ext_fraclm == 0 && p->ext_fracl == 0)
+ return FP_INFINITE;
+ else
+ return FP_NAN;
+ }
+
+ return FP_NORMAL;
+}
diff --git a/lib/libc/arch/sparc/gen/isfinitel.c b/lib/libc/arch/sparc/gen/isfinitel.c
new file mode 100644
index 00000000000..f60c9f1af85
--- /dev/null
+++ b/lib/libc/arch/sparc/gen/isfinitel.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isfinitel(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/sparc/gen/isinfl.c b/lib/libc/arch/sparc/gen/isinfl.c
new file mode 100644
index 00000000000..8c11b447689
--- /dev/null
+++ b/lib/libc/arch/sparc/gen/isinfl.c
@@ -0,0 +1,29 @@
+/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isinfl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ p->ext_frach == 0 && p->ext_frachm == 0 &&
+ p->ext_fraclm == 0 && p->ext_fracl == 0);
+}
diff --git a/lib/libc/arch/sparc/gen/isnanl.c b/lib/libc/arch/sparc/gen/isnanl.c
new file mode 100644
index 00000000000..e5cfb5ae788
--- /dev/null
+++ b/lib/libc/arch/sparc/gen/isnanl.c
@@ -0,0 +1,29 @@
+/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnanl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ (p->ext_frach != 0 || p->ext_frachm != 0 ||
+ p->ext_fraclm != 0 || p->ext_fracl != 0));
+}
diff --git a/lib/libc/arch/sparc/gen/isnormall.c b/lib/libc/arch/sparc/gen/isnormall.c
new file mode 100644
index 00000000000..91df6fe51d0
--- /dev/null
+++ b/lib/libc/arch/sparc/gen/isnormall.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnormall(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/sparc64/gdtoa/Makefile.inc b/lib/libc/arch/sparc64/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..4a6106dbaa6
--- /dev/null
+++ b/lib/libc/arch/sparc64/gdtoa/Makefile.inc
@@ -0,0 +1,3 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:08 martynas Exp $
+
+SRCS+= strtord.c strtorQ.c
diff --git a/lib/libc/arch/sparc64/gdtoa/arith.h b/lib/libc/arch/sparc64/gdtoa/arith.h
new file mode 100644
index 00000000000..0b84f84f763
--- /dev/null
+++ b/lib/libc/arch/sparc64/gdtoa/arith.h
@@ -0,0 +1,6 @@
+#define IEEE_MC68k
+#define Arith_Kind_ASL 2
+#define Long int
+#define Intcast (int)(long)
+#define Double_Align
+#define X64_bit_pointers
diff --git a/lib/libc/arch/sparc64/gdtoa/gd_qnan.h b/lib/libc/arch/sparc64/gdtoa/gd_qnan.h
new file mode 100644
index 00000000000..e9245803b2a
--- /dev/null
+++ b/lib/libc/arch/sparc64/gdtoa/gd_qnan.h
@@ -0,0 +1,12 @@
+#define f_QNAN 0x7fffffff
+#define d_QNAN0 0x7fffffff
+#define d_QNAN1 0xffffffff
+#define ld_QNAN0 0x7fffffff
+#define ld_QNAN1 0xffffffff
+#define ld_QNAN2 0xffffffff
+#define ld_QNAN3 0xffffffff
+#define ldus_QNAN0 0x7fff
+#define ldus_QNAN1 0xffff
+#define ldus_QNAN2 0xffff
+#define ldus_QNAN3 0xffff
+#define ldus_QNAN4 0xffff
diff --git a/lib/libc/arch/sparc64/gdtoa/strtold.c b/lib/libc/arch/sparc64/gdtoa/strtold.c
new file mode 100644
index 00000000000..ecbfd5507fa
--- /dev/null
+++ b/lib/libc/arch/sparc64/gdtoa/strtold.c
@@ -0,0 +1,45 @@
+/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*-
+ * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * Machine-dependent glue to integrate David Gay's gdtoa
+ * package into libc for architectures where a long double
+ * uses quad precision, such as sparc64.
+ */
+
+#include <float.h>
+
+#include "gdtoaimp.h"
+
+long double
+strtold(const char * __restrict s, char ** __restrict sp)
+{
+ long double result;
+
+ strtorQ(s, sp, FLT_ROUNDS, &result);
+ return result;
+}
diff --git a/lib/libc/arch/sparc64/gen/Makefile.inc b/lib/libc/arch/sparc64/gen/Makefile.inc
index 2fa31fd3071..8a7fafce703 100644
--- a/lib/libc/arch/sparc64/gen/Makefile.inc
+++ b/lib/libc/arch/sparc64/gen/Makefile.inc
@@ -1,8 +1,9 @@
-# $OpenBSD: Makefile.inc,v 1.5 2008/07/24 09:31:07 martynas Exp $
+# $OpenBSD: Makefile.inc,v 1.6 2008/09/07 20:36:08 martynas Exp $
SRCS+= _setjmp.S fabs.S infinity.c ldexp.c modf.S nan.c
SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
fpsetround.c fpsetsticky.c
+SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c
SRCS+= fixunsdfsi.S mul.S umul.S saveregs.S setjmp.S sigsetjmp.S
SRCS+= alloca.c
diff --git a/lib/libc/arch/sparc64/gen/fpclassifyl.c b/lib/libc/arch/sparc64/gen/fpclassifyl.c
new file mode 100644
index 00000000000..d569ef90430
--- /dev/null
+++ b/lib/libc/arch/sparc64/gen/fpclassifyl.c
@@ -0,0 +1,44 @@
+/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+int
+__fpclassifyl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ if (p->ext_exp == 0) {
+ if (p->ext_frach == 0 && p->ext_frachm == 0 &&
+ p->ext_fraclm == 0 && p->ext_fracl == 0)
+ return FP_ZERO;
+ else
+ return FP_SUBNORMAL;
+ }
+
+ if (p->ext_exp == EXT_EXP_INFNAN) {
+ if (p->ext_frach == 0 && p->ext_frachm == 0 &&
+ p->ext_fraclm == 0 && p->ext_fracl == 0)
+ return FP_INFINITE;
+ else
+ return FP_NAN;
+ }
+
+ return FP_NORMAL;
+}
diff --git a/lib/libc/arch/sparc64/gen/isfinitel.c b/lib/libc/arch/sparc64/gen/isfinitel.c
new file mode 100644
index 00000000000..f60c9f1af85
--- /dev/null
+++ b/lib/libc/arch/sparc64/gen/isfinitel.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isfinitel(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/sparc64/gen/isinfl.c b/lib/libc/arch/sparc64/gen/isinfl.c
new file mode 100644
index 00000000000..8c11b447689
--- /dev/null
+++ b/lib/libc/arch/sparc64/gen/isinfl.c
@@ -0,0 +1,29 @@
+/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isinfl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ p->ext_frach == 0 && p->ext_frachm == 0 &&
+ p->ext_fraclm == 0 && p->ext_fracl == 0);
+}
diff --git a/lib/libc/arch/sparc64/gen/isnanl.c b/lib/libc/arch/sparc64/gen/isnanl.c
new file mode 100644
index 00000000000..e5cfb5ae788
--- /dev/null
+++ b/lib/libc/arch/sparc64/gen/isnanl.c
@@ -0,0 +1,29 @@
+/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnanl(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp == EXT_EXP_INFNAN &&
+ (p->ext_frach != 0 || p->ext_frachm != 0 ||
+ p->ext_fraclm != 0 || p->ext_fracl != 0));
+}
diff --git a/lib/libc/arch/sparc64/gen/isnormall.c b/lib/libc/arch/sparc64/gen/isnormall.c
new file mode 100644
index 00000000000..91df6fe51d0
--- /dev/null
+++ b/lib/libc/arch/sparc64/gen/isnormall.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <sys/types.h>
+#include <machine/ieee.h>
+
+int
+__isnormall(long double e)
+{
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+
+ return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN);
+}
diff --git a/lib/libc/arch/vax/gdtoa/Makefile.inc b/lib/libc/arch/vax/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..53e0b7aef69
--- /dev/null
+++ b/lib/libc/arch/vax/gdtoa/Makefile.inc
@@ -0,0 +1,3 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:08 martynas Exp $
+
+CFLAGS+= -DNO_HEX_FP
diff --git a/lib/libc/arch/vax/gdtoa/arith.h b/lib/libc/arch/vax/gdtoa/arith.h
new file mode 100644
index 00000000000..bd5c83a65ff
--- /dev/null
+++ b/lib/libc/arch/vax/gdtoa/arith.h
@@ -0,0 +1,2 @@
+#define VAX
+#define Arith_Kind_ASL 4
diff --git a/lib/libc/arch/vax/gdtoa/gd_qnan.h b/lib/libc/arch/vax/gdtoa/gd_qnan.h
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/lib/libc/arch/vax/gdtoa/gd_qnan.h
diff --git a/lib/libc/arch/vax/gdtoa/hdtoa.c b/lib/libc/arch/vax/gdtoa/hdtoa.c
new file mode 100644
index 00000000000..dc95c0e2eae
--- /dev/null
+++ b/lib/libc/arch/vax/gdtoa/hdtoa.c
@@ -0,0 +1,224 @@
+/* $OpenBSD: hdtoa.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*-
+ * Copyright (c) 2004, 2005 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/types.h>
+#include <machine/vaxfp.h>
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+
+#include "gdtoaimp.h"
+
+/* Strings values used by dtoa() */
+#define INFSTR "Infinity"
+#define NANSTR "NaN"
+
+#define DBL_ADJ (DBL_MAX_EXP - 2 + ((DBL_MANT_DIG - 1) % 4))
+#define LDBL_ADJ (LDBL_MAX_EXP - 2 + ((LDBL_MANT_DIG - 1) % 4))
+
+/*
+ * Round up the given digit string. If the digit string is fff...f,
+ * this procedure sets it to 100...0 and returns 1 to indicate that
+ * the exponent needs to be bumped. Otherwise, 0 is returned.
+ */
+static int
+roundup(char *s0, int ndigits)
+{
+ char *s;
+
+ for (s = s0 + ndigits - 1; *s == 0xf; s--) {
+ if (s == s0) {
+ *s = 1;
+ return (1);
+ }
+ *s = 0;
+ }
+ ++*s;
+ return (0);
+}
+
+/*
+ * Round the given digit string to ndigits digits according to the
+ * current rounding mode. Note that this could produce a string whose
+ * value is not representable in the corresponding floating-point
+ * type. The exponent pointed to by decpt is adjusted if necessary.
+ */
+static void
+dorounding(char *s0, int ndigits, int sign, int *decpt)
+{
+ int adjust = 0; /* do we need to adjust the exponent? */
+
+ switch (FLT_ROUNDS) {
+ case 0: /* toward zero */
+ default: /* implementation-defined */
+ break;
+ case 1: /* to nearest, halfway rounds to even */
+ if ((s0[ndigits] > 8) ||
+ (s0[ndigits] == 8 && s0[ndigits + 1] & 1))
+ adjust = roundup(s0, ndigits);
+ break;
+ case 2: /* toward +inf */
+ if (sign == 0)
+ adjust = roundup(s0, ndigits);
+ break;
+ case 3: /* toward -inf */
+ if (sign != 0)
+ adjust = roundup(s0, ndigits);
+ break;
+ }
+
+ if (adjust)
+ *decpt += 4;
+}
+
+/*
+ * This procedure converts a double-precision number in IEEE format
+ * into a string of hexadecimal digits and an exponent of 2. Its
+ * behavior is bug-for-bug compatible with dtoa() in mode 2, with the
+ * following exceptions:
+ *
+ * - An ndigits < 0 causes it to use as many digits as necessary to
+ * represent the number exactly.
+ * - The additional xdigs argument should point to either the string
+ * "0123456789ABCDEF" or the string "0123456789abcdef", depending on
+ * which case is desired.
+ * - This routine does not repeat dtoa's mistake of setting decpt
+ * to 9999 in the case of an infinity or NaN. INT_MAX is used
+ * for this purpose instead.
+ *
+ * Note that the C99 standard does not specify what the leading digit
+ * should be for non-zero numbers. For instance, 0x1.3p3 is the same
+ * as 0x2.6p2 is the same as 0x4.cp3. This implementation chooses the
+ * first digit so that subsequent digits are aligned on nibble
+ * boundaries (before rounding).
+ *
+ * Inputs: d, xdigs, ndigits
+ * Outputs: decpt, sign, rve
+ */
+char *
+__hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign,
+ char **rve)
+{
+ static const int sigfigs = (DBL_MANT_DIG + 3) / 4;
+ struct vax_d_floating *p = (struct vax_d_floating *)&d;
+ char *s, *s0;
+ int bufsize;
+
+ *sign = p->dflt_sign;
+
+ switch (fpclassify(d)) {
+ case FP_NORMAL:
+ *decpt = p->dflt_exp - DBL_ADJ;
+ break;
+ case FP_ZERO:
+ *decpt = 1;
+ return (nrv_alloc("0", rve, 1));
+ case FP_SUBNORMAL:
+ d *= 0x1p514;
+ *decpt = p->dflt_exp - (514 + DBL_ADJ);
+ break;
+ case FP_INFINITE:
+ *decpt = INT_MAX;
+ return (nrv_alloc(INFSTR, rve, sizeof(INFSTR) - 1));
+ case FP_NAN:
+ *decpt = INT_MAX;
+ return (nrv_alloc(NANSTR, rve, sizeof(NANSTR) - 1));
+ default:
+ abort();
+ }
+
+ /* FP_NORMAL or FP_SUBNORMAL */
+
+ if (ndigits == 0) /* dtoa() compatibility */
+ ndigits = 1;
+
+ /*
+ * For simplicity, we generate all the digits even if the
+ * caller has requested fewer.
+ */
+ bufsize = (sigfigs > ndigits) ? sigfigs : ndigits;
+ s0 = rv_alloc(bufsize);
+
+ /*
+ * We work from right to left, first adding any requested zero
+ * padding, then the least significant portion of the
+ * mantissa, followed by the most significant. The buffer is
+ * filled with the byte values 0x0 through 0xf, which are
+ * converted to xdigs[0x0] through xdigs[0xf] after the
+ * rounding phase.
+ */
+ for (s = s0 + bufsize - 1; s > s0 + sigfigs - 1; s--)
+ *s = 0;
+ for (; s > s0 + sigfigs - (DFLT_FRACLBITS / 4) - 1 && s > s0; s--) {
+ *s = p->dflt_fracl & 0xf;
+ p->dflt_fracl >>= 4;
+ }
+ for (; s > s0; s--) {
+ *s = p->dflt_fracm & 0xf;
+ p->dflt_fracm >>= 4;
+ }
+ for (; s > s0; s--) {
+ *s = p->dflt_frach & 0xf;
+ p->dflt_frach >>= 4;
+ }
+
+ /*
+ * At this point, we have snarfed all the bits in the
+ * mantissa, with the possible exception of the highest-order
+ * (partial) nibble, which is dealt with by the next
+ * statement. We also tack on the implicit normalization bit.
+ */
+ *s = p->dflt_frach | (1U << ((DBL_MANT_DIG - 1) % 4));
+
+ /* If ndigits < 0, we are expected to auto-size the precision. */
+ if (ndigits < 0) {
+ for (ndigits = sigfigs; s0[ndigits - 1] == 0; ndigits--)
+ ;
+ }
+
+ if (sigfigs > ndigits && s0[ndigits] != 0)
+ dorounding(s0, ndigits, p->dflt_sign, decpt);
+
+ s = s0 + ndigits;
+ if (rve != NULL)
+ *rve = s;
+ *s-- = '\0';
+ for (; s >= s0; s--)
+ *s = xdigs[(unsigned int)*s];
+
+ return (s0);
+}
+
+/*
+ * This is the long double version of __hdtoa().
+ */
+char *
+__hldtoa(long double e, const char *xdigs, int ndigits, int *decpt, int *sign,
+ char **rve)
+{
+ return (__hdtoa((double)e, xdigs, ndigits, decpt, sign, rve));
+}
diff --git a/lib/libc/arch/vax/gdtoa/strtof.c b/lib/libc/arch/vax/gdtoa/strtof.c
new file mode 100644
index 00000000000..f0472c2558d
--- /dev/null
+++ b/lib/libc/arch/vax/gdtoa/strtof.c
@@ -0,0 +1,67 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ float
+#ifdef KR_headers
+strtof(s, sp) CONST char *s; char **sp;
+#else
+strtof(CONST char *s, char **sp)
+#endif
+{
+ static FPI fpi = { 24, 1-128-1-24+1, 255-128-1-24+1, 1, SI };
+ ULong bits[1];
+ Long exp;
+ int k;
+ union { ULong L[1]; float f; } u;
+
+ k = strtodg(s, sp, &fpi, &exp, bits);
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ u.L[0] = 0;
+ break;
+
+ case STRTOG_Normal:
+ u.L[0] = ((bits[0] & 0x0000ffff) << 16) | /* FracLo */
+ ((bits[0] & 0x007f0000) >> 16) | /* FracHi */
+ ((exp + 128 + 1 + 23) << 7); /* Exp */
+ break;
+
+ case STRTOG_Infinite:
+ u.L[0] = 0xffff7fff;
+ break;
+ }
+ if (k & STRTOG_Neg)
+ u.L[0] |= 0x00008000L;
+ return u.f;
+ }
diff --git a/lib/libc/gdtoa/Makefile.inc b/lib/libc/gdtoa/Makefile.inc
new file mode 100644
index 00000000000..d32754336ec
--- /dev/null
+++ b/lib/libc/gdtoa/Makefile.inc
@@ -0,0 +1,17 @@
+# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:08 martynas Exp $
+
+# gdtoa sources
+.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/gdtoa ${LIBCSRCDIR}/gdtoa
+
+CFLAGS+= -I${LIBCSRCDIR}/gdtoa
+CFLAGS+= -I${LIBCSRCDIR}/arch/${MACHINE_ARCH}/gdtoa
+
+CFLAGS+= -DINFNAN_CHECK
+CFLAGS+= -DMULTIPLE_THREADS
+CFLAGS+= -DNO_FENV_H
+
+SRCS+= dmisc.c dtoa.c gdtoa.c gethex.c gmisc.c hd_init.c hdtoa.c \
+ hexnan.c ldtoa.c locks.c misc.c smisc.c strtod.c strtodg.c \
+ strtof.c strtold.c sum.c ulp.c
+
+.include "${LIBCSRCDIR}/arch/${MACHINE_ARCH}/gdtoa/Makefile.inc"
diff --git a/lib/libc/gdtoa/arithchk.c b/lib/libc/gdtoa/arithchk.c
new file mode 100644
index 00000000000..3211aeda42c
--- /dev/null
+++ b/lib/libc/gdtoa/arithchk.c
@@ -0,0 +1,183 @@
+/****************************************************************
+Copyright (C) 1997, 1998 Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+****************************************************************/
+
+/* Try to deduce arith.h from arithmetic properties. */
+
+#include <stdio.h>
+
+ static int dalign;
+ typedef struct
+Akind {
+ char *name;
+ int kind;
+ } Akind;
+
+ static Akind
+IEEE_8087 = { "IEEE_8087", 1 },
+IEEE_MC68k = { "IEEE_MC68k", 2 },
+IBM = { "IBM", 3 },
+VAX = { "VAX", 4 },
+CRAY = { "CRAY", 5};
+
+ static Akind *
+Lcheck()
+{
+ union {
+ double d;
+ long L[2];
+ } u;
+ struct {
+ double d;
+ long L;
+ } x[2];
+
+ if (sizeof(x) > 2*(sizeof(double) + sizeof(long)))
+ dalign = 1;
+ u.L[0] = u.L[1] = 0;
+ u.d = 1e13;
+ if (u.L[0] == 1117925532 && u.L[1] == -448790528)
+ return &IEEE_MC68k;
+ if (u.L[1] == 1117925532 && u.L[0] == -448790528)
+ return &IEEE_8087;
+ if (u.L[0] == -2065213935 && u.L[1] == 10752)
+ return &VAX;
+ if (u.L[0] == 1267827943 && u.L[1] == 704643072)
+ return &IBM;
+ return 0;
+ }
+
+ static Akind *
+icheck()
+{
+ union {
+ double d;
+ int L[2];
+ } u;
+ struct {
+ double d;
+ int L;
+ } x[2];
+
+ if (sizeof(x) > 2*(sizeof(double) + sizeof(int)))
+ dalign = 1;
+ u.L[0] = u.L[1] = 0;
+ u.d = 1e13;
+ if (u.L[0] == 1117925532 && u.L[1] == -448790528)
+ return &IEEE_MC68k;
+ if (u.L[1] == 1117925532 && u.L[0] == -448790528)
+ return &IEEE_8087;
+ if (u.L[0] == -2065213935 && u.L[1] == 10752)
+ return &VAX;
+ if (u.L[0] == 1267827943 && u.L[1] == 704643072)
+ return &IBM;
+ return 0;
+ }
+
+char *emptyfmt = ""; /* avoid possible warning message with printf("") */
+
+ static Akind *
+ccheck()
+{
+ union {
+ double d;
+ long L;
+ } u;
+ long Cray1;
+
+ /* Cray1 = 4617762693716115456 -- without overflow on non-Crays */
+ Cray1 = printf(emptyfmt) < 0 ? 0 : 4617762;
+ if (printf(emptyfmt, Cray1) >= 0)
+ Cray1 = 1000000*Cray1 + 693716;
+ if (printf(emptyfmt, Cray1) >= 0)
+ Cray1 = 1000000*Cray1 + 115456;
+ u.d = 1e13;
+ if (u.L == Cray1)
+ return &CRAY;
+ return 0;
+ }
+
+ static int
+fzcheck()
+{
+ double a, b;
+ int i;
+
+ a = 1.;
+ b = .1;
+ for(i = 155;; b *= b, i >>= 1) {
+ if (i & 1) {
+ a *= b;
+ if (i == 1)
+ break;
+ }
+ }
+ b = a * a;
+ return b == 0.;
+ }
+
+ int
+main()
+{
+ Akind *a = 0;
+ int Ldef = 0;
+ FILE *f;
+
+#ifdef WRITE_ARITH_H /* for Symantec's buggy "make" */
+ f = fopen("arith.h", "w");
+ if (!f) {
+ printf("Cannot open arith.h\n");
+ return 1;
+ }
+#else
+ f = stdout;
+#endif
+
+ if (sizeof(double) == 2*sizeof(long))
+ a = Lcheck();
+ else if (sizeof(double) == 2*sizeof(int)) {
+ Ldef = 1;
+ a = icheck();
+ }
+ else if (sizeof(double) == sizeof(long))
+ a = ccheck();
+ if (a) {
+ fprintf(f, "#define %s\n#define Arith_Kind_ASL %d\n",
+ a->name, a->kind);
+ if (Ldef)
+ fprintf(f, "#define Long int\n#define Intcast (int)(long)\n");
+ if (dalign)
+ fprintf(f, "#define Double_Align\n");
+ if (sizeof(char*) == 8)
+ fprintf(f, "#define X64_bit_pointers\n");
+#ifndef NO_LONG_LONG
+ if (sizeof(long long) < 8)
+#endif
+ fprintf(f, "#define NO_LONG_LONG\n");
+ if (a->kind <= 2 && fzcheck())
+ fprintf(f, "#define Sudden_Underflow\n");
+ return 0;
+ }
+ fprintf(f, "/* Unknown arithmetic */\n");
+ return 1;
+ }
diff --git a/lib/libc/gdtoa/dmisc.c b/lib/libc/gdtoa/dmisc.c
new file mode 100644
index 00000000000..ce170c733bf
--- /dev/null
+++ b/lib/libc/gdtoa/dmisc.c
@@ -0,0 +1,216 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+#ifndef MULTIPLE_THREADS
+ char *dtoa_result;
+#endif
+
+ char *
+#ifdef KR_headers
+rv_alloc(i) int i;
+#else
+rv_alloc(int i)
+#endif
+{
+ int j, k, *r;
+
+ j = sizeof(ULong);
+ for(k = 0;
+ sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
+ j <<= 1)
+ k++;
+ r = (int*)Balloc(k);
+ *r = k;
+ return
+#ifndef MULTIPLE_THREADS
+ dtoa_result =
+#endif
+ (char *)(r+1);
+ }
+
+ char *
+#ifdef KR_headers
+nrv_alloc(s, rve, n) char *s, **rve; int n;
+#else
+nrv_alloc(char *s, char **rve, int n)
+#endif
+{
+ char *rv, *t;
+
+ t = rv = rv_alloc(n);
+ while((*t = *s++) !=0)
+ t++;
+ if (rve)
+ *rve = t;
+ return rv;
+ }
+
+/* freedtoa(s) must be used to free values s returned by dtoa
+ * when MULTIPLE_THREADS is #defined. It should be used in all cases,
+ * but for consistency with earlier versions of dtoa, it is optional
+ * when MULTIPLE_THREADS is not defined.
+ */
+
+ void
+#ifdef KR_headers
+freedtoa(s) char *s;
+#else
+freedtoa(char *s)
+#endif
+{
+ Bigint *b = (Bigint *)((int *)s - 1);
+ b->maxwds = 1 << (b->k = *(int*)b);
+ Bfree(b);
+#ifndef MULTIPLE_THREADS
+ if (s == dtoa_result)
+ dtoa_result = 0;
+#endif
+ }
+
+ int
+quorem
+#ifdef KR_headers
+ (b, S) Bigint *b, *S;
+#else
+ (Bigint *b, Bigint *S)
+#endif
+{
+ int n;
+ ULong *bx, *bxe, q, *sx, *sxe;
+#ifdef ULLong
+ ULLong borrow, carry, y, ys;
+#else
+ ULong borrow, carry, y, ys;
+#ifdef Pack_32
+ ULong si, z, zs;
+#endif
+#endif
+
+ n = S->wds;
+#ifdef DEBUG
+ /*debug*/ if (b->wds > n)
+ /*debug*/ Bug("oversize b in quorem");
+#endif
+ if (b->wds < n)
+ return 0;
+ sx = S->x;
+ sxe = sx + --n;
+ bx = b->x;
+ bxe = bx + n;
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
+#ifdef DEBUG
+ /*debug*/ if (q > 9)
+ /*debug*/ Bug("oversized quotient in quorem");
+#endif
+ if (q) {
+ borrow = 0;
+ carry = 0;
+ do {
+#ifdef ULLong
+ ys = *sx++ * (ULLong)q + carry;
+ carry = ys >> 32;
+ y = *bx - (ys & 0xffffffffUL) - borrow;
+ borrow = y >> 32 & 1UL;
+ *bx++ = y & 0xffffffffUL;
+#else
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) * q + carry;
+ zs = (si >> 16) * q + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*bx >> 16) - (zs & 0xffff) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ * q + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *bx++ = y & 0xffff;
+#endif
+#endif
+ }
+ while(sx <= sxe);
+ if (!*bxe) {
+ bx = b->x;
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ if (cmp(b, S) >= 0) {
+ q++;
+ borrow = 0;
+ carry = 0;
+ bx = b->x;
+ sx = S->x;
+ do {
+#ifdef ULLong
+ ys = *sx++ + carry;
+ carry = ys >> 32;
+ y = *bx - (ys & 0xffffffffUL) - borrow;
+ borrow = y >> 32 & 1UL;
+ *bx++ = y & 0xffffffffUL;
+#else
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) + carry;
+ zs = (si >> 16) + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*bx >> 16) - (zs & 0xffff) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *bx++ = y & 0xffff;
+#endif
+#endif
+ }
+ while(sx <= sxe);
+ bx = b->x;
+ bxe = bx + n;
+ if (!*bxe) {
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ return q;
+ }
diff --git a/lib/libc/gdtoa/dtoa.c b/lib/libc/gdtoa/dtoa.c
new file mode 100644
index 00000000000..e808cc1f4f3
--- /dev/null
+++ b/lib/libc/gdtoa/dtoa.c
@@ -0,0 +1,753 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 1999 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the Long
+ * calculation.
+ */
+
+#ifdef Honor_FLT_ROUNDS
+#define Rounding rounding
+#undef Check_FLT_ROUNDS
+#define Check_FLT_ROUNDS
+#else
+#define Rounding Flt_Rounds
+#endif
+
+ char *
+dtoa
+#ifdef KR_headers
+ (d, mode, ndigits, decpt, sign, rve)
+ double d; int mode, ndigits, *decpt, *sign; char **rve;
+#else
+ (double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
+#endif
+{
+ /* Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4,5 ==> similar to 2 and 3, respectively, but (in
+ round-nearest mode) with the tests of mode 0 to
+ possibly return a shorter string that rounds to d.
+ With IEEE arithmetic and compilation with
+ -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
+ as modes 2 and 3 when FLT_ROUNDS != 1.
+ 6-9 ==> Debugging modes similar to mode - 4: don't try
+ fast floating-point estimate (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
+ j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
+ spec_case, try_quick;
+ Long L;
+#ifndef Sudden_Underflow
+ int denorm;
+ ULong x;
+#endif
+ Bigint *b, *b1, *delta, *mlo, *mhi, *S;
+ double d2, ds, eps;
+ char *s, *s0;
+#ifdef Honor_FLT_ROUNDS
+ int rounding;
+#endif
+#ifdef SET_INEXACT
+ int inexact, oldinexact;
+#endif
+
+#ifndef MULTIPLE_THREADS
+ if (dtoa_result) {
+ freedtoa(dtoa_result);
+ dtoa_result = 0;
+ }
+#endif
+
+ if (word0(d) & Sign_bit) {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ word0(d) &= ~Sign_bit; /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+ if ((word0(d) & Exp_mask) == Exp_mask)
+#else
+ if (word0(d) == 0x8000)
+#endif
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+#ifdef IEEE_Arith
+ if (!word1(d) && !(word0(d) & 0xfffff))
+ return nrv_alloc("Infinity", rve, 8);
+#endif
+ return nrv_alloc("NaN", rve, 3);
+ }
+#endif
+#ifdef IBM
+ dval(d) += 0; /* normalize */
+#endif
+ if (!dval(d)) {
+ *decpt = 1;
+ return nrv_alloc("0", rve, 1);
+ }
+
+#ifdef SET_INEXACT
+ try_quick = oldinexact = get_inexact();
+ inexact = 1;
+#endif
+#ifdef Honor_FLT_ROUNDS
+ if ((rounding = Flt_Rounds) >= 2) {
+ if (*sign)
+ rounding = rounding == 2 ? 0 : 2;
+ else
+ if (rounding != 2)
+ rounding = 0;
+ }
+#endif
+
+ b = d2b(dval(d), &be, &bbits);
+#ifdef Sudden_Underflow
+ i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#else
+ if (( i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) {
+#endif
+ dval(d2) = dval(d);
+ word0(d2) &= Frac_mask1;
+ word0(d2) |= Exp_11;
+#ifdef IBM
+ if (( j = 11 - hi0bits(word0(d2) & Frac_mask) )!=0)
+ dval(d2) /= 1 << j;
+#endif
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ i -= Bias;
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+#ifndef Sudden_Underflow
+ denorm = 0;
+ }
+ else {
+ /* d is denormalized */
+
+ i = bbits + be + (Bias + (P-1) - 1);
+ x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
+ : word1(d) << 32 - i;
+ dval(d2) = x;
+ word0(d2) -= 31*Exp_msk1; /* adjust exponent */
+ i -= (Bias + (P-1) - 1) + 1;
+ denorm = 1;
+ }
+#endif
+ ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ k = (int)ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax) {
+ if (dval(d) < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+
+#ifndef SET_INEXACT
+#ifdef Check_FLT_ROUNDS
+ try_quick = Rounding == 1;
+#else
+ try_quick = 1;
+#endif
+#endif /*SET_INEXACT*/
+
+ if (mode > 5) {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ switch(mode) {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ s = s0 = rv_alloc(i);
+
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1 && rounding != 1)
+ leftright = 0;
+#endif
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ dval(d2) = dval(d);
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = k >> 4;
+ if (j & Bletch) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ dval(d) /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for(; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ dval(d) /= ds;
+ }
+ else if (( j1 = -k )!=0) {
+ dval(d) *= tens[j1 & 0xf];
+ for(j = j1 >> 4; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ dval(d) *= bigtens[i];
+ }
+ }
+ if (k_check && dval(d) < 1. && ilim > 0) {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ dval(d) *= 10.;
+ ieps++;
+ }
+ dval(eps) = ieps*dval(d) + 7.;
+ word0(eps) -= (P-1)*Exp_msk1;
+ if (ilim == 0) {
+ S = mhi = 0;
+ dval(d) -= 5.;
+ if (dval(d) > dval(eps))
+ goto one_digit;
+ if (dval(d) < -dval(eps))
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ dval(eps) = 0.5/tens[ilim-1] - dval(eps);
+ for(i = 0;;) {
+ L = dval(d);
+ dval(d) -= L;
+ *s++ = '0' + (int)L;
+ if (dval(d) < dval(eps))
+ goto ret1;
+ if (1. - dval(d) < dval(eps))
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ dval(eps) *= 10.;
+ dval(d) *= 10.;
+ }
+ }
+ else {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ dval(eps) *= tens[ilim-1];
+ for(i = 1;; i++, dval(d) *= 10.) {
+ L = (Long)(dval(d));
+ if (!(dval(d) -= L))
+ ilim = i;
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ if (dval(d) > 0.5 + dval(eps))
+ goto bump_up;
+ else if (dval(d) < 0.5 - dval(eps)) {
+ while(*--s == '0');
+ s++;
+ goto ret1;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+ fast_failed:
+ s = s0;
+ dval(d) = dval(d2);
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ S = mhi = 0;
+ if (ilim < 0 || dval(d) <= 5*ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for(i = 1;; i++, dval(d) *= 10.) {
+ L = (Long)(dval(d) / ds);
+ dval(d) -= L*ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (dval(d) < 0) {
+ L--;
+ dval(d) += ds;
+ }
+#endif
+ *s++ = '0' + (int)L;
+ if (!dval(d)) {
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ break;
+ }
+ if (i == ilim) {
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1)
+ switch(rounding) {
+ case 0: goto ret1;
+ case 2: goto bump_up;
+ }
+#endif
+ dval(d) += dval(d);
+ if (dval(d) > ds || dval(d) == ds && L & 1) {
+ bump_up:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ break;
+ }
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ mhi = mlo = 0;
+ if (leftright) {
+ i =
+#ifndef Sudden_Underflow
+ denorm ? be + (Bias + (P-1) - 1 + 1) :
+#endif
+#ifdef IBM
+ 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+ 1 + P - bbits;
+#endif
+ b2 += i;
+ s2 += i;
+ mhi = i2b(1);
+ }
+ if (m2 > 0 && s2 > 0) {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0) {
+ if (leftright) {
+ if (m5 > 0) {
+ mhi = pow5mult(mhi, m5);
+ b1 = mult(mhi, b);
+ Bfree(b);
+ b = b1;
+ }
+ if (( j = b5 - m5 )!=0)
+ b = pow5mult(b, j);
+ }
+ else
+ b = pow5mult(b, b5);
+ }
+ S = i2b(1);
+ if (s5 > 0)
+ S = pow5mult(S, s5);
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ spec_case = 0;
+ if ((mode < 2 || leftright)
+#ifdef Honor_FLT_ROUNDS
+ && rounding == 1
+#endif
+ ) {
+ if (!word1(d) && !(word0(d) & Bndry_mask)
+#ifndef Sudden_Underflow
+ && word0(d) & (Exp_mask & ~Exp_msk1)
+#endif
+ ) {
+ /* The special case */
+ b2 += Log2P;
+ s2 += Log2P;
+ spec_case = 1;
+ }
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+#ifdef Pack_32
+ if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f )!=0)
+ i = 32 - i;
+#else
+ if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf )!=0)
+ i = 16 - i;
+#endif
+ if (i > 4) {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ else if (i < 4) {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ if (b2 > 0)
+ b = lshift(b, b2);
+ if (s2 > 0)
+ S = lshift(S, s2);
+ if (k_check) {
+ if (cmp(b,S) < 0) {
+ k--;
+ b = multadd(b, 10, 0); /* we botched the k estimate */
+ if (leftright)
+ mhi = multadd(mhi, 10, 0);
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && (mode == 3 || mode == 5)) {
+ if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ goto ret;
+ }
+ one_digit:
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright) {
+ if (m2 > 0)
+ mhi = lshift(mhi, m2);
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case) {
+ mhi = Balloc(mhi->k);
+ Bcopy(mhi, mlo);
+ mhi = lshift(mhi, Log2P);
+ }
+
+ for(i = 1;;i++) {
+ dig = quorem(b,S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp(b, mlo);
+ delta = diff(S, mhi);
+ j1 = delta->sign ? 1 : cmp(b, delta);
+ Bfree(delta);
+#ifndef ROUND_BIASED
+ if (j1 == 0 && mode != 1 && !(word1(d) & 1)
+#ifdef Honor_FLT_ROUNDS
+ && rounding >= 1
+#endif
+ ) {
+ if (dig == '9')
+ goto round_9_up;
+ if (j > 0)
+ dig++;
+#ifdef SET_INEXACT
+ else if (!b->x[0] && b->wds <= 1)
+ inexact = 0;
+#endif
+ *s++ = dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || j == 0 && mode != 1
+#ifndef ROUND_BIASED
+ && !(word1(d) & 1)
+#endif
+ ) {
+ if (!b->x[0] && b->wds <= 1) {
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ goto accept_dig;
+ }
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1)
+ switch(rounding) {
+ case 0: goto accept_dig;
+ case 2: goto keep_dig;
+ }
+#endif /*Honor_FLT_ROUNDS*/
+ if (j1 > 0) {
+ b = lshift(b, 1);
+ j1 = cmp(b, S);
+ if ((j1 > 0 || j1 == 0 && dig & 1)
+ && dig++ == '9')
+ goto round_9_up;
+ }
+ accept_dig:
+ *s++ = dig;
+ goto ret;
+ }
+ if (j1 > 0) {
+#ifdef Honor_FLT_ROUNDS
+ if (!rounding)
+ goto accept_dig;
+#endif
+ if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+ *s++ = '9';
+ goto roundoff;
+ }
+ *s++ = dig + 1;
+ goto ret;
+ }
+#ifdef Honor_FLT_ROUNDS
+ keep_dig:
+#endif
+ *s++ = dig;
+ if (i == ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (mlo == mhi)
+ mlo = mhi = multadd(mhi, 10, 0);
+ else {
+ mlo = multadd(mlo, 10, 0);
+ mhi = multadd(mhi, 10, 0);
+ }
+ }
+ }
+ else
+ for(i = 1;; i++) {
+ *s++ = dig = quorem(b,S) + '0';
+ if (!b->x[0] && b->wds <= 1) {
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ goto ret;
+ }
+ if (i >= ilim)
+ break;
+ b = multadd(b, 10, 0);
+ }
+
+ /* Round off last digit */
+
+#ifdef Honor_FLT_ROUNDS
+ switch(rounding) {
+ case 0: goto trimzeros;
+ case 2: goto roundoff;
+ }
+#endif
+ b = lshift(b, 1);
+ j = cmp(b, S);
+ if (j > 0 || j == 0 && dig & 1) {
+ roundoff:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ ++*s++;
+ }
+ else {
+ trimzeros:
+ while(*--s == '0');
+ s++;
+ }
+ ret:
+ Bfree(S);
+ if (mhi) {
+ if (mlo && mlo != mhi)
+ Bfree(mlo);
+ Bfree(mhi);
+ }
+ ret1:
+#ifdef SET_INEXACT
+ if (inexact) {
+ if (!oldinexact) {
+ word0(d) = Exp_1 + (70 << Exp_shift);
+ word1(d) = 0;
+ dval(d) += 1.;
+ }
+ }
+ else if (!oldinexact)
+ clear_inexact();
+#endif
+ Bfree(b);
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ return s0;
+ }
diff --git a/lib/libc/gdtoa/g_Qfmt.c b/lib/libc/gdtoa/g_Qfmt.c
new file mode 100644
index 00000000000..2b9b3679963
--- /dev/null
+++ b/lib/libc/gdtoa/g_Qfmt.c
@@ -0,0 +1,114 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+#undef _0
+#undef _1
+
+/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
+
+#ifdef IEEE_MC68k
+#define _0 0
+#define _1 1
+#define _2 2
+#define _3 3
+#endif
+#ifdef IEEE_8087
+#define _0 3
+#define _1 2
+#define _2 1
+#define _3 0
+#endif
+
+ char*
+#ifdef KR_headers
+g_Qfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize;
+#else
+g_Qfmt(char *buf, void *V, int ndig, unsigned bufsize)
+#endif
+{
+ static FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0 };
+ char *b, *s, *se;
+ ULong bits[4], *L, sign;
+ int decpt, ex, i, mode;
+
+ if (ndig < 0)
+ ndig = 0;
+ if (bufsize < ndig + 10)
+ return 0;
+
+ L = (ULong*)V;
+ sign = L[_0] & 0x80000000L;
+ bits[3] = L[_0] & 0xffff;
+ bits[2] = L[_1];
+ bits[1] = L[_2];
+ bits[0] = L[_3];
+ b = buf;
+ if ( (ex = (L[_0] & 0x7fff0000L) >> 16) !=0) {
+ if (ex == 0x7fff) {
+ /* Infinity or NaN */
+ if (bits[0] | bits[1] | bits[2] | bits[3])
+ b = strcp(b, "NaN");
+ else {
+ b = buf;
+ if (sign)
+ *b++ = '-';
+ b = strcp(b, "Infinity");
+ }
+ return b;
+ }
+ i = STRTOG_Normal;
+ bits[3] |= 0x10000;
+ }
+ else if (bits[0] | bits[1] | bits[2] | bits[3]) {
+ i = STRTOG_Denormal;
+ ex = 1;
+ }
+ else {
+#ifndef IGNORE_ZERO_SIGN
+ if (sign)
+ *b++ = '-';
+#endif
+ *b++ = '0';
+ *b = 0;
+ return b;
+ }
+ ex -= 0x3fff + 112;
+ mode = 2;
+ if (ndig <= 0) {
+ if (bufsize < 48)
+ return 0;
+ mode = 0;
+ }
+ s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
+ return g__fmt(buf, s, se, decpt, sign);
+ }
diff --git a/lib/libc/gdtoa/g__fmt.c b/lib/libc/gdtoa/g__fmt.c
new file mode 100644
index 00000000000..021ecfb5728
--- /dev/null
+++ b/lib/libc/gdtoa/g__fmt.c
@@ -0,0 +1,99 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+#ifdef USE_LOCALE
+#include "locale.h"
+#endif
+
+ char *
+#ifdef KR_headers
+g__fmt(b, s, se, decpt, sign) char *b; char *s; char *se; int decpt; ULong sign;
+#else
+g__fmt(char *b, char *s, char *se, int decpt, ULong sign)
+#endif
+{
+ int i, j, k;
+ char *s0 = s;
+#ifdef USE_LOCALE
+ char decimalpoint = *localeconv()->decimal_point;
+#else
+#define decimalpoint '.'
+#endif
+ if (sign)
+ *b++ = '-';
+ if (decpt <= -4 || decpt > se - s + 5) {
+ *b++ = *s++;
+ if (*s) {
+ *b++ = decimalpoint;
+ while((*b = *s++) !=0)
+ b++;
+ }
+ *b++ = 'e';
+ /* sprintf(b, "%+.2d", decpt - 1); */
+ if (--decpt < 0) {
+ *b++ = '-';
+ decpt = -decpt;
+ }
+ else
+ *b++ = '+';
+ for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){}
+ for(;;) {
+ i = decpt / k;
+ *b++ = i + '0';
+ if (--j <= 0)
+ break;
+ decpt -= i*k;
+ decpt *= 10;
+ }
+ *b = 0;
+ }
+ else if (decpt <= 0) {
+ *b++ = decimalpoint;
+ for(; decpt < 0; decpt++)
+ *b++ = '0';
+ while((*b = *s++) !=0)
+ b++;
+ }
+ else {
+ while((*b = *s++) !=0) {
+ b++;
+ if (--decpt == 0 && *s)
+ *b++ = decimalpoint;
+ }
+ for(; decpt > 0; decpt--)
+ *b++ = '0';
+ *b = 0;
+ }
+ freedtoa(s0);
+ return b;
+ }
diff --git a/lib/libc/gdtoa/g_ddfmt.c b/lib/libc/gdtoa/g_ddfmt.c
new file mode 100644
index 00000000000..7fc30578a90
--- /dev/null
+++ b/lib/libc/gdtoa/g_ddfmt.c
@@ -0,0 +1,154 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg@acm.org). */
+
+#include "gdtoaimp.h"
+#include <string.h>
+
+ char *
+#ifdef KR_headers
+g_ddfmt(buf, dd, ndig, bufsize) char *buf; double *dd; int ndig; unsigned bufsize;
+#else
+g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize)
+#endif
+{
+ FPI fpi;
+ char *b, *s, *se;
+ ULong *L, bits0[4], *bits, *zx;
+ int bx, by, decpt, ex, ey, i, j, mode;
+ Bigint *x, *y, *z;
+ double ddx[2];
+
+ if (bufsize < 10 || bufsize < ndig + 8)
+ return 0;
+
+ L = (ULong*)dd;
+ if ((L[_0] & 0x7ff00000L) == 0x7ff00000L) {
+ /* Infinity or NaN */
+ if (L[_0] & 0xfffff || L[_1]) {
+ nanret:
+ return strcp(buf, "NaN");
+ }
+ if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) {
+ if (L[2+_0] & 0xfffff || L[2+_1])
+ goto nanret;
+ if ((L[_0] ^ L[2+_0]) & 0x80000000L)
+ goto nanret; /* Infinity - Infinity */
+ }
+ infret:
+ b = buf;
+ if (L[_0] & 0x80000000L)
+ *b++ = '-';
+ return strcp(b, "Infinity");
+ }
+ if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) {
+ L += 2;
+ if (L[_0] & 0xfffff || L[_1])
+ goto nanret;
+ goto infret;
+ }
+ if (dd[0] + dd[1] == 0.) {
+ b = buf;
+#ifndef IGNORE_ZERO_SIGN
+ if (L[_0] & L[2+_0] & 0x80000000L)
+ *b++ = '-';
+#endif
+ *b++ = '0';
+ *b = 0;
+ return b;
+ }
+ if ((L[_0] & 0x7ff00000L) < (L[2+_0] & 0x7ff00000L)) {
+ ddx[1] = dd[0];
+ ddx[0] = dd[1];
+ dd = ddx;
+ L = (ULong*)dd;
+ }
+ z = d2b(dd[0], &ex, &bx);
+ if (dd[1] == 0.)
+ goto no_y;
+ x = z;
+ y = d2b(dd[1], &ey, &by);
+ if ( (i = ex - ey) !=0) {
+ if (i > 0) {
+ x = lshift(x, i);
+ ex = ey;
+ }
+ else
+ y = lshift(y, -i);
+ }
+ if ((L[_0] ^ L[2+_0]) & 0x80000000L) {
+ z = diff(x, y);
+ if (L[_0] & 0x80000000L)
+ z->sign = 1 - z->sign;
+ }
+ else {
+ z = sum(x, y);
+ if (L[_0] & 0x80000000L)
+ z->sign = 1;
+ }
+ Bfree(x);
+ Bfree(y);
+ no_y:
+ bits = zx = z->x;
+ for(i = 0; !*zx; zx++)
+ i += 32;
+ i += lo0bits(zx);
+ if (i) {
+ rshift(z, i);
+ ex += i;
+ }
+ fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]);
+ if (fpi.nbits < 106) {
+ fpi.nbits = 106;
+ if (j < 3) {
+ for(i = 0; i <= j; i++)
+ bits0[i] = bits[i];
+ while(i < 4)
+ bits0[i++] = 0;
+ bits = bits0;
+ }
+ }
+ mode = 2;
+ if (ndig <= 0) {
+ if (bufsize < (int)(fpi.nbits * .301029995664) + 10) {
+ Bfree(z);
+ return 0;
+ }
+ mode = 0;
+ }
+ fpi.emin = 1-1023-53+1;
+ fpi.emax = 2046-1023-106+1;
+ fpi.rounding = FPI_Round_near;
+ fpi.sudden_underflow = 0;
+ i = STRTOG_Normal;
+ s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
+ b = g__fmt(buf, s, se, decpt, z->sign);
+ Bfree(z);
+ return b;
+ }
diff --git a/lib/libc/gdtoa/g_dfmt.c b/lib/libc/gdtoa/g_dfmt.c
new file mode 100644
index 00000000000..db2636f6da9
--- /dev/null
+++ b/lib/libc/gdtoa/g_dfmt.c
@@ -0,0 +1,89 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ char*
+#ifdef KR_headers
+g_dfmt(buf, d, ndig, bufsize) char *buf; double *d; int ndig; unsigned bufsize;
+#else
+g_dfmt(char *buf, double *d, int ndig, unsigned bufsize)
+#endif
+{
+ static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 };
+ char *b, *s, *se;
+ ULong bits[2], *L, sign;
+ int decpt, ex, i, mode;
+
+ if (ndig < 0)
+ ndig = 0;
+ if (bufsize < ndig + 10)
+ return 0;
+
+ L = (ULong*)d;
+ sign = L[_0] & 0x80000000L;
+ if ((L[_0] & 0x7ff00000) == 0x7ff00000) {
+ /* Infinity or NaN */
+ if (L[_0] & 0xfffff || L[_1]) {
+ return strcp(buf, "NaN");
+ }
+ b = buf;
+ if (sign)
+ *b++ = '-';
+ return strcp(b, "Infinity");
+ }
+ if (L[_1] == 0 && (L[_0] ^ sign) == 0 /*d == 0.*/) {
+ b = buf;
+#ifndef IGNORE_ZERO_SIGN
+ if (L[_0] & 0x80000000L)
+ *b++ = '-';
+#endif
+ *b++ = '0';
+ *b = 0;
+ return b;
+ }
+ bits[0] = L[_1];
+ bits[1] = L[_0] & 0xfffff;
+ if ( (ex = (L[_0] >> 20) & 0x7ff) !=0)
+ bits[1] |= 0x100000;
+ else
+ ex = 1;
+ ex -= 0x3ff + 52;
+ mode = 2;
+ if (ndig <= 0) {
+ if (bufsize < 25)
+ return 0;
+ mode = 0;
+ }
+ i = STRTOG_Normal;
+ s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
+ return g__fmt(buf, s, se, decpt, sign);
+ }
diff --git a/lib/libc/gdtoa/g_ffmt.c b/lib/libc/gdtoa/g_ffmt.c
new file mode 100644
index 00000000000..612adfae382
--- /dev/null
+++ b/lib/libc/gdtoa/g_ffmt.c
@@ -0,0 +1,88 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ char*
+#ifdef KR_headers
+g_ffmt(buf, f, ndig, bufsize) char *buf; float *f; int ndig; unsigned bufsize;
+#else
+g_ffmt(char *buf, float *f, int ndig, unsigned bufsize)
+#endif
+{
+ static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 0 };
+ char *b, *s, *se;
+ ULong bits[1], *L, sign;
+ int decpt, ex, i, mode;
+
+ if (ndig < 0)
+ ndig = 0;
+ if (bufsize < ndig + 10)
+ return 0;
+
+ L = (ULong*)f;
+ sign = L[0] & 0x80000000L;
+ if ((L[0] & 0x7f800000) == 0x7f800000) {
+ /* Infinity or NaN */
+ if (L[0] & 0x7fffff) {
+ return strcp(buf, "NaN");
+ }
+ b = buf;
+ if (sign)
+ *b++ = '-';
+ return strcp(b, "Infinity");
+ }
+ if (*f == 0.) {
+ b = buf;
+#ifndef IGNORE_ZERO_SIGN
+ if (L[0] & 0x80000000L)
+ *b++ = '-';
+#endif
+ *b++ = '0';
+ *b = 0;
+ return b;
+ }
+ bits[0] = L[0] & 0x7fffff;
+ if ( (ex = (L[0] >> 23) & 0xff) !=0)
+ bits[0] |= 0x800000;
+ else
+ ex = 1;
+ ex -= 0x7f + 23;
+ mode = 2;
+ if (ndig <= 0) {
+ if (bufsize < 16)
+ return 0;
+ mode = 0;
+ }
+ i = STRTOG_Normal;
+ s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
+ return g__fmt(buf, s, se, decpt, sign);
+ }
diff --git a/lib/libc/gdtoa/g_xLfmt.c b/lib/libc/gdtoa/g_xLfmt.c
new file mode 100644
index 00000000000..1bbc6e215ed
--- /dev/null
+++ b/lib/libc/gdtoa/g_xLfmt.c
@@ -0,0 +1,108 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+#undef _0
+#undef _1
+
+/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
+
+#ifdef IEEE_MC68k
+#define _0 0
+#define _1 1
+#define _2 2
+#endif
+#ifdef IEEE_8087
+#define _0 2
+#define _1 1
+#define _2 0
+#endif
+
+ char*
+#ifdef KR_headers
+g_xLfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize;
+#else
+g_xLfmt(char *buf, void *V, int ndig, unsigned bufsize)
+#endif
+{
+ static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
+ char *b, *s, *se;
+ ULong bits[2], *L, sign;
+ int decpt, ex, i, mode;
+
+ if (ndig < 0)
+ ndig = 0;
+ if (bufsize < ndig + 10)
+ return 0;
+
+ L = (ULong*)V;
+ sign = L[_0] & 0x80000000L;
+ bits[1] = L[_1];
+ bits[0] = L[_2];
+ if ( (ex = (L[_0] >> 16) & 0x7fff) !=0) {
+ if (ex == 0x7fff) {
+ /* Infinity or NaN */
+ if (bits[0] | bits[1])
+ b = strcp(buf, "NaN");
+ else {
+ b = buf;
+ if (sign)
+ *b++ = '-';
+ b = strcp(b, "Infinity");
+ }
+ return b;
+ }
+ i = STRTOG_Normal;
+ }
+ else if (bits[0] | bits[1]) {
+ i = STRTOG_Denormal;
+ }
+ else {
+ b = buf;
+#ifndef IGNORE_ZERO_SIGN
+ if (sign)
+ *b++ = '-';
+#endif
+ *b++ = '0';
+ *b = 0;
+ return b;
+ }
+ ex -= 0x3fff + 63;
+ mode = 2;
+ if (ndig <= 0) {
+ if (bufsize < 32)
+ return 0;
+ mode = 0;
+ }
+ s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
+ return g__fmt(buf, s, se, decpt, sign);
+ }
diff --git a/lib/libc/gdtoa/g_xfmt.c b/lib/libc/gdtoa/g_xfmt.c
new file mode 100644
index 00000000000..47a862d6bc7
--- /dev/null
+++ b/lib/libc/gdtoa/g_xfmt.c
@@ -0,0 +1,114 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+#undef _0
+#undef _1
+
+/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
+
+#ifdef IEEE_MC68k
+#define _0 0
+#define _1 1
+#define _2 2
+#define _3 3
+#define _4 4
+#endif
+#ifdef IEEE_8087
+#define _0 4
+#define _1 3
+#define _2 2
+#define _3 1
+#define _4 0
+#endif
+
+ char*
+#ifdef KR_headers
+g_xfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize;
+#else
+g_xfmt(char *buf, void *V, int ndig, unsigned bufsize)
+#endif
+{
+ static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
+ char *b, *s, *se;
+ ULong bits[2], sign;
+ UShort *L;
+ int decpt, ex, i, mode;
+
+ if (ndig < 0)
+ ndig = 0;
+ if (bufsize < ndig + 10)
+ return 0;
+
+ L = (UShort *)V;
+ sign = L[_0] & 0x8000;
+ bits[1] = (L[_1] << 16) | L[_2];
+ bits[0] = (L[_3] << 16) | L[_4];
+ if ( (ex = L[_0] & 0x7fff) !=0) {
+ if (ex == 0x7fff) {
+ /* Infinity or NaN */
+ if (bits[0] | bits[1])
+ b = strcp(buf, "NaN");
+ else {
+ b = buf;
+ if (sign)
+ *b++ = '-';
+ b = strcp(b, "Infinity");
+ }
+ return b;
+ }
+ i = STRTOG_Normal;
+ }
+ else if (bits[0] | bits[1]) {
+ i = STRTOG_Denormal;
+ ex = 1;
+ }
+ else {
+ b = buf;
+#ifndef IGNORE_ZERO_SIGN
+ if (sign)
+ *b++ = '-';
+#endif
+ *b++ = '0';
+ *b = 0;
+ return b;
+ }
+ ex -= 0x3fff + 63;
+ mode = 2;
+ if (ndig <= 0) {
+ if (bufsize < 32)
+ return 0;
+ mode = 0;
+ }
+ s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
+ return g__fmt(buf, s, se, decpt, sign);
+ }
diff --git a/lib/libc/gdtoa/gdtoa.c b/lib/libc/gdtoa/gdtoa.c
new file mode 100644
index 00000000000..8ff8cc587ea
--- /dev/null
+++ b/lib/libc/gdtoa/gdtoa.c
@@ -0,0 +1,758 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 1999 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ static Bigint *
+#ifdef KR_headers
+bitstob(bits, nbits, bbits) ULong *bits; int nbits; int *bbits;
+#else
+bitstob(ULong *bits, int nbits, int *bbits)
+#endif
+{
+ int i, k;
+ Bigint *b;
+ ULong *be, *x, *x0;
+
+ i = ULbits;
+ k = 0;
+ while(i < nbits) {
+ i <<= 1;
+ k++;
+ }
+#ifndef Pack_32
+ if (!k)
+ k = 1;
+#endif
+ b = Balloc(k);
+ be = bits + ((nbits - 1) >> kshift);
+ x = x0 = b->x;
+ do {
+ *x++ = *bits & ALL_ON;
+#ifdef Pack_16
+ *x++ = (*bits >> 16) & ALL_ON;
+#endif
+ } while(++bits <= be);
+ i = x - x0;
+ while(!x0[--i])
+ if (!i) {
+ b->wds = 0;
+ *bbits = 0;
+ goto ret;
+ }
+ b->wds = i + 1;
+ *bbits = i*ULbits + 32 - hi0bits(b->x[i]);
+ ret:
+ return b;
+ }
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the Long
+ * calculation.
+ */
+
+ char *
+gdtoa
+#ifdef KR_headers
+ (fpi, be, bits, kindp, mode, ndigits, decpt, rve)
+ FPI *fpi; int be; ULong *bits;
+ int *kindp, mode, ndigits, *decpt; char **rve;
+#else
+ (FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve)
+#endif
+{
+ /* Arguments ndigits and decpt are similar to the second and third
+ arguments of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4-9 should give the same return values as 2-3, i.e.,
+ 4 <= mode <= 9 ==> same return as mode
+ 2 + (mode & 1). These modes are mainly for
+ debugging; often they run slower but sometimes
+ faster than modes 2-3.
+ 4,5,8,9 ==> left-to-right digit generation.
+ 6-9 ==> don't try fast floating-point estimate
+ (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ int bbits, b2, b5, be0, dig, i, ieps, ilim, ilim0, ilim1, inex;
+ int j, j1, k, k0, k_check, kind, leftright, m2, m5, nbits;
+ int rdir, s2, s5, spec_case, try_quick;
+ Long L;
+ Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S;
+ double d, d2, ds, eps;
+ char *s, *s0;
+
+#ifndef MULTIPLE_THREADS
+ if (dtoa_result) {
+ freedtoa(dtoa_result);
+ dtoa_result = 0;
+ }
+#endif
+ inex = 0;
+ kind = *kindp &= ~STRTOG_Inexact;
+ switch(kind & STRTOG_Retmask) {
+ case STRTOG_Zero:
+ goto ret_zero;
+ case STRTOG_Normal:
+ case STRTOG_Denormal:
+ break;
+ case STRTOG_Infinite:
+ *decpt = -32768;
+ return nrv_alloc("Infinity", rve, 8);
+ case STRTOG_NaN:
+ *decpt = -32768;
+ return nrv_alloc("NaN", rve, 3);
+ default:
+ return 0;
+ }
+ b = bitstob(bits, nbits = fpi->nbits, &bbits);
+ be0 = be;
+ if ( (i = trailz(b)) !=0) {
+ rshift(b, i);
+ be += i;
+ bbits -= i;
+ }
+ if (!b->wds) {
+ Bfree(b);
+ ret_zero:
+ *decpt = 1;
+ return nrv_alloc("0", rve, 1);
+ }
+
+ dval(d) = b2d(b, &i);
+ i = be + bbits - 1;
+ word0(d) &= Frac_mask1;
+ word0(d) |= Exp_11;
+#ifdef IBM
+ if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0)
+ dval(d) /= 1 << j;
+#endif
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+ ds = (dval(d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+
+ /* correct assumption about exponent range */
+ if ((j = i) < 0)
+ j = -j;
+ if ((j -= 1077) > 0)
+ ds += j * 7e-17;
+
+ k = (int)ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+#ifdef IBM
+ j = be + bbits - 1;
+ if ( (j1 = j & 3) !=0)
+ dval(d) *= 1 << j1;
+ word0(d) += j << Exp_shift - 2 & Exp_mask;
+#else
+ word0(d) += (be + bbits - 1) << Exp_shift;
+#endif
+ if (k >= 0 && k <= Ten_pmax) {
+ if (dval(d) < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+ try_quick = 1;
+ if (mode > 5) {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ switch(mode) {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = (int)(nbits * .30103) + 3;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ s = s0 = rv_alloc(i);
+
+ if ( (rdir = fpi->rounding - 1) !=0) {
+ if (rdir < 0)
+ rdir = 2;
+ if (kind & STRTOG_Neg)
+ rdir = 3 - rdir;
+ }
+
+ /* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir
+#ifndef IMPRECISE_INEXACT
+ && k == 0
+#endif
+ ) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ d2 = dval(d);
+#ifdef IBM
+ if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0)
+ dval(d) /= 1 << j;
+#endif
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = k >> 4;
+ if (j & Bletch) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ dval(d) /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for(; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ }
+ else {
+ ds = 1.;
+ if ( (j1 = -k) !=0) {
+ dval(d) *= tens[j1 & 0xf];
+ for(j = j1 >> 4; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ dval(d) *= bigtens[i];
+ }
+ }
+ }
+ if (k_check && dval(d) < 1. && ilim > 0) {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ dval(d) *= 10.;
+ ieps++;
+ }
+ dval(eps) = ieps*dval(d) + 7.;
+ word0(eps) -= (P-1)*Exp_msk1;
+ if (ilim == 0) {
+ S = mhi = 0;
+ dval(d) -= 5.;
+ if (dval(d) > dval(eps))
+ goto one_digit;
+ if (dval(d) < -dval(eps))
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ dval(eps) = ds*0.5/tens[ilim-1] - dval(eps);
+ for(i = 0;;) {
+ L = (Long)(dval(d)/ds);
+ dval(d) -= L*ds;
+ *s++ = '0' + (int)L;
+ if (dval(d) < dval(eps)) {
+ if (dval(d))
+ inex = STRTOG_Inexlo;
+ goto ret1;
+ }
+ if (ds - dval(d) < dval(eps))
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ dval(eps) *= 10.;
+ dval(d) *= 10.;
+ }
+ }
+ else {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ dval(eps) *= tens[ilim-1];
+ for(i = 1;; i++, dval(d) *= 10.) {
+ if ( (L = (Long)(dval(d)/ds)) !=0)
+ dval(d) -= L*ds;
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ ds *= 0.5;
+ if (dval(d) > ds + dval(eps))
+ goto bump_up;
+ else if (dval(d) < ds - dval(eps)) {
+ while(*--s == '0'){}
+ s++;
+ if (dval(d))
+ inex = STRTOG_Inexlo;
+ goto ret1;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+ fast_failed:
+ s = s0;
+ dval(d) = d2;
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ S = mhi = 0;
+ if (ilim < 0 || dval(d) <= 5*ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for(i = 1;; i++, dval(d) *= 10.) {
+ L = dval(d) / ds;
+ dval(d) -= L*ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (dval(d) < 0) {
+ L--;
+ dval(d) += ds;
+ }
+#endif
+ *s++ = '0' + (int)L;
+ if (dval(d) == 0.)
+ break;
+ if (i == ilim) {
+ if (rdir) {
+ if (rdir == 1)
+ goto bump_up;
+ inex = STRTOG_Inexlo;
+ goto ret1;
+ }
+ dval(d) += dval(d);
+ if (dval(d) > ds || dval(d) == ds && L & 1) {
+ bump_up:
+ inex = STRTOG_Inexhi;
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ else
+ inex = STRTOG_Inexlo;
+ break;
+ }
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ mhi = mlo = 0;
+ if (leftright) {
+ if (mode < 2) {
+ i = nbits - bbits;
+ if (be - i++ < fpi->emin)
+ /* denormal */
+ i = be - fpi->emin + 1;
+ }
+ else {
+ j = ilim - 1;
+ if (m5 >= j)
+ m5 -= j;
+ else {
+ s5 += j -= m5;
+ b5 += j;
+ m5 = 0;
+ }
+ if ((i = ilim) < 0) {
+ m2 -= i;
+ i = 0;
+ }
+ }
+ b2 += i;
+ s2 += i;
+ mhi = i2b(1);
+ }
+ if (m2 > 0 && s2 > 0) {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0) {
+ if (leftright) {
+ if (m5 > 0) {
+ mhi = pow5mult(mhi, m5);
+ b1 = mult(mhi, b);
+ Bfree(b);
+ b = b1;
+ }
+ if ( (j = b5 - m5) !=0)
+ b = pow5mult(b, j);
+ }
+ else
+ b = pow5mult(b, b5);
+ }
+ S = i2b(1);
+ if (s5 > 0)
+ S = pow5mult(S, s5);
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ spec_case = 0;
+ if (mode < 2) {
+ if (bbits == 1 && be0 > fpi->emin + 1) {
+ /* The special case */
+ b2++;
+ s2++;
+ spec_case = 1;
+ }
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+#ifdef Pack_32
+ if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) !=0)
+ i = 32 - i;
+#else
+ if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) !=0)
+ i = 16 - i;
+#endif
+ if (i > 4) {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ else if (i < 4) {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ if (b2 > 0)
+ b = lshift(b, b2);
+ if (s2 > 0)
+ S = lshift(S, s2);
+ if (k_check) {
+ if (cmp(b,S) < 0) {
+ k--;
+ b = multadd(b, 10, 0); /* we botched the k estimate */
+ if (leftright)
+ mhi = multadd(mhi, 10, 0);
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && mode > 2) {
+ if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ inex = STRTOG_Inexlo;
+ goto ret;
+ }
+ one_digit:
+ inex = STRTOG_Inexhi;
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright) {
+ if (m2 > 0)
+ mhi = lshift(mhi, m2);
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case) {
+ mhi = Balloc(mhi->k);
+ Bcopy(mhi, mlo);
+ mhi = lshift(mhi, 1);
+ }
+
+ for(i = 1;;i++) {
+ dig = quorem(b,S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp(b, mlo);
+ delta = diff(S, mhi);
+ j1 = delta->sign ? 1 : cmp(b, delta);
+ Bfree(delta);
+#ifndef ROUND_BIASED
+ if (j1 == 0 && !mode && !(bits[0] & 1) && !rdir) {
+ if (dig == '9')
+ goto round_9_up;
+ if (j <= 0) {
+ if (b->wds > 1 || b->x[0])
+ inex = STRTOG_Inexlo;
+ }
+ else {
+ dig++;
+ inex = STRTOG_Inexhi;
+ }
+ *s++ = dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || j == 0 && !mode
+#ifndef ROUND_BIASED
+ && !(bits[0] & 1)
+#endif
+ ) {
+ if (rdir && (b->wds > 1 || b->x[0])) {
+ if (rdir == 2) {
+ inex = STRTOG_Inexlo;
+ goto accept;
+ }
+ while (cmp(S,mhi) > 0) {
+ *s++ = dig;
+ mhi1 = multadd(mhi, 10, 0);
+ if (mlo == mhi)
+ mlo = mhi1;
+ mhi = mhi1;
+ b = multadd(b, 10, 0);
+ dig = quorem(b,S) + '0';
+ }
+ if (dig++ == '9')
+ goto round_9_up;
+ inex = STRTOG_Inexhi;
+ goto accept;
+ }
+ if (j1 > 0) {
+ b = lshift(b, 1);
+ j1 = cmp(b, S);
+ if ((j1 > 0 || j1 == 0 && dig & 1)
+ && dig++ == '9')
+ goto round_9_up;
+ inex = STRTOG_Inexhi;
+ }
+ if (b->wds > 1 || b->x[0])
+ inex = STRTOG_Inexlo;
+ accept:
+ *s++ = dig;
+ goto ret;
+ }
+ if (j1 > 0 && rdir != 2) {
+ if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+ *s++ = '9';
+ inex = STRTOG_Inexhi;
+ goto roundoff;
+ }
+ inex = STRTOG_Inexhi;
+ *s++ = dig + 1;
+ goto ret;
+ }
+ *s++ = dig;
+ if (i == ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (mlo == mhi)
+ mlo = mhi = multadd(mhi, 10, 0);
+ else {
+ mlo = multadd(mlo, 10, 0);
+ mhi = multadd(mhi, 10, 0);
+ }
+ }
+ }
+ else
+ for(i = 1;; i++) {
+ *s++ = dig = quorem(b,S) + '0';
+ if (i >= ilim)
+ break;
+ b = multadd(b, 10, 0);
+ }
+
+ /* Round off last digit */
+
+ if (rdir) {
+ if (rdir == 2 || b->wds <= 1 && !b->x[0])
+ goto chopzeros;
+ goto roundoff;
+ }
+ b = lshift(b, 1);
+ j = cmp(b, S);
+ if (j > 0 || j == 0 && dig & 1) {
+ roundoff:
+ inex = STRTOG_Inexhi;
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ ++*s++;
+ }
+ else {
+ chopzeros:
+ if (b->wds > 1 || b->x[0])
+ inex = STRTOG_Inexlo;
+ while(*--s == '0'){}
+ s++;
+ }
+ ret:
+ Bfree(S);
+ if (mhi) {
+ if (mlo && mlo != mhi)
+ Bfree(mlo);
+ Bfree(mhi);
+ }
+ ret1:
+ Bfree(b);
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ *kindp |= inex;
+ return s0;
+ }
diff --git a/lib/libc/gdtoa/gdtoa.h b/lib/libc/gdtoa/gdtoa.h
new file mode 100644
index 00000000000..ee6a9e53faf
--- /dev/null
+++ b/lib/libc/gdtoa/gdtoa.h
@@ -0,0 +1,153 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#ifndef GDTOA_H_INCLUDED
+#define GDTOA_H_INCLUDED
+
+#include "arith.h"
+
+#ifndef Long
+#define Long long
+#endif
+#ifndef ULong
+typedef unsigned Long ULong;
+#endif
+#ifndef UShort
+typedef unsigned short UShort;
+#endif
+
+#ifndef ANSI
+#ifdef KR_headers
+#define ANSI(x) ()
+#define Void /*nothing*/
+#else
+#define ANSI(x) x
+#define Void void
+#endif
+#endif /* ANSI */
+
+#ifndef CONST
+#ifdef KR_headers
+#define CONST /* blank */
+#else
+#define CONST const
+#endif
+#endif /* CONST */
+
+ enum { /* return values from strtodg */
+ STRTOG_Zero = 0,
+ STRTOG_Normal = 1,
+ STRTOG_Denormal = 2,
+ STRTOG_Infinite = 3,
+ STRTOG_NaN = 4,
+ STRTOG_NaNbits = 5,
+ STRTOG_NoNumber = 6,
+ STRTOG_Retmask = 7,
+
+ /* The following may be or-ed into one of the above values. */
+
+ STRTOG_Neg = 0x08,
+ STRTOG_Inexlo = 0x10,
+ STRTOG_Inexhi = 0x20,
+ STRTOG_Inexact = 0x30,
+ STRTOG_Underflow= 0x40,
+ STRTOG_Overflow = 0x80
+ };
+
+ typedef struct
+FPI {
+ int nbits;
+ int emin;
+ int emax;
+ int rounding;
+ int sudden_underflow;
+ } FPI;
+
+enum { /* FPI.rounding values: same as FLT_ROUNDS */
+ FPI_Round_zero = 0,
+ FPI_Round_near = 1,
+ FPI_Round_up = 2,
+ FPI_Round_down = 3
+ };
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char* dtoa ANSI((double d, int mode, int ndigits, int *decpt,
+ int *sign, char **rve));
+extern char* gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp,
+ int mode, int ndigits, int *decpt, char **rve));
+extern void freedtoa ANSI((char*));
+extern float strtof ANSI((CONST char *, char **));
+extern double strtod ANSI((CONST char *, char **));
+extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*));
+
+extern char* g_ddfmt ANSI((char*, double*, int, unsigned));
+extern char* g_dfmt ANSI((char*, double*, int, unsigned));
+extern char* g_ffmt ANSI((char*, float*, int, unsigned));
+extern char* g_Qfmt ANSI((char*, void*, int, unsigned));
+extern char* g_xfmt ANSI((char*, void*, int, unsigned));
+extern char* g_xLfmt ANSI((char*, void*, int, unsigned));
+
+extern int strtoId ANSI((CONST char*, char**, double*, double*));
+extern int strtoIdd ANSI((CONST char*, char**, double*, double*));
+extern int strtoIf ANSI((CONST char*, char**, float*, float*));
+extern int strtoIQ ANSI((CONST char*, char**, void*, void*));
+extern int strtoIx ANSI((CONST char*, char**, void*, void*));
+extern int strtoIxL ANSI((CONST char*, char**, void*, void*));
+extern int strtord ANSI((CONST char*, char**, int, double*));
+extern int strtordd ANSI((CONST char*, char**, int, double*));
+extern int strtorf ANSI((CONST char*, char**, int, float*));
+extern int strtorQ ANSI((CONST char*, char**, int, void*));
+extern int strtorx ANSI((CONST char*, char**, int, void*));
+extern int strtorxL ANSI((CONST char*, char**, int, void*));
+#if 1
+extern int strtodI ANSI((CONST char*, char**, double*));
+extern int strtopd ANSI((CONST char*, char**, double*));
+extern int strtopdd ANSI((CONST char*, char**, double*));
+extern int strtopf ANSI((CONST char*, char**, float*));
+extern int strtopQ ANSI((CONST char*, char**, void*));
+extern int strtopx ANSI((CONST char*, char**, void*));
+extern int strtopxL ANSI((CONST char*, char**, void*));
+#else
+#define strtopd(s,se,x) strtord(s,se,1,x)
+#define strtopdd(s,se,x) strtordd(s,se,1,x)
+#define strtopf(s,se,x) strtorf(s,se,1,x)
+#define strtopQ(s,se,x) strtorQ(s,se,1,x)
+#define strtopx(s,se,x) strtorx(s,se,1,x)
+#define strtopxL(s,se,x) strtorxL(s,se,1,x)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* GDTOA_H_INCLUDED */
diff --git a/lib/libc/gdtoa/gdtoaimp.h b/lib/libc/gdtoa/gdtoaimp.h
new file mode 100644
index 00000000000..e850dae5a55
--- /dev/null
+++ b/lib/libc/gdtoa/gdtoaimp.h
@@ -0,0 +1,659 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998-2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* This is a variation on dtoa.c that converts arbitary binary
+ floating-point formats to and from decimal notation. It uses
+ double-precision arithmetic internally, so there are still
+ various #ifdefs that adapt the calculations to the native
+ double-precision arithmetic (any of IEEE, VAX D_floating,
+ or IBM mainframe arithmetic).
+
+ Please send bug reports to David M. Gay (dmg at acm dot org,
+ with " at " changed at "@" and " dot " changed to ".").
+ */
+
+/* On a machine with IEEE extended-precision registers, it is
+ * necessary to specify double-precision (53-bit) rounding precision
+ * before invoking strtod or dtoa. If the machine uses (the equivalent
+ * of) Intel 80x87 arithmetic, the call
+ * _control87(PC_53, MCW_PC);
+ * does this with many compilers. Whether this or another call is
+ * appropriate depends on the compiler; for this to work, it may be
+ * necessary to #include "float.h" or another system-dependent header
+ * file.
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule. Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 112-126].
+ *
+ * Modifications:
+ *
+ * 1. We only require IEEE, IBM, or VAX double-precision
+ * arithmetic (not IEEE double-extended).
+ * 2. We get by with floating-point arithmetic in a case that
+ * Clinger missed -- when we're computing d * 10^n
+ * for a small integer d and the integer n is not too
+ * much larger than 22 (the maximum integer k for which
+ * we can represent 10^k exactly), we may be able to
+ * compute (d*10^k) * 10^(e-k) with just one roundoff.
+ * 3. Rather than a bit-at-a-time adjustment of the binary
+ * result in the hard case, we use floating-point
+ * arithmetic to determine the adjustment to within
+ * one bit; only in really hard cases do we need to
+ * compute a second residual.
+ * 4. Because of 3., we don't need a large table of powers of 10
+ * for ten-to-e (just some small tables, e.g. of 10^k
+ * for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_8087 for IEEE-arithmetic machines where the least
+ * significant byte has the lowest address.
+ * #define IEEE_MC68k for IEEE-arithmetic machines where the most
+ * significant byte has the lowest address.
+ * #define Long int on machines with 32-bit ints and 64-bit longs.
+ * #define Sudden_Underflow for IEEE-format machines without gradual
+ * underflow (i.e., that flush to zero on underflow).
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic (D_floating).
+ * #define No_leftright to omit left-right logic in fast floating-point
+ * computation of dtoa.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ * that use extended-precision instructions to compute rounded
+ * products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ * products but inaccurate quotients, e.g., for Intel i860.
+ * #define NO_LONG_LONG on machines that do not have a "long long"
+ * integer type (of >= 64 bits). On such machines, you can
+ * #define Just_16 to store 16 bits per 32-bit Long when doing
+ * high-precision integer arithmetic. Whether this speeds things
+ * up or slows things down depends on the machine and the number
+ * being converted. If long long is available and the name is
+ * something other than "long long", #define Llong to be the name,
+ * and if "unsigned Llong" does not work as an unsigned version of
+ * Llong, #define #ULLong to be the corresponding unsigned type.
+ * #define KR_headers for old-style C function headers.
+ * #define Bad_float_h if your system lacks a float.h or if it does not
+ * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
+ * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
+ * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
+ * if memory is available and otherwise does something you deem
+ * appropriate. If MALLOC is undefined, malloc will be invoked
+ * directly -- and assumed always to succeed.
+ * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
+ * memory allocations from a private pool of memory when possible.
+ * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes,
+ * unless #defined to be a different length. This default length
+ * suffices to get rid of MALLOC calls except for unusual cases,
+ * such as decimal-to-binary conversion of a very long string of
+ * digits. When converting IEEE double precision values, the
+ * longest string gdtoa can return is about 751 bytes long. For
+ * conversions by strtod of strings of 800 digits and all gdtoa
+ * conversions of IEEE doubles in single-threaded executions with
+ * 8-byte pointers, PRIVATE_MEM >= 7400 appears to suffice; with
+ * 4-byte pointers, PRIVATE_MEM >= 7112 appears adequate.
+ * #define INFNAN_CHECK on IEEE systems to cause strtod to check for
+ * Infinity and NaN (case insensitively).
+ * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined,
+ * strtodg also accepts (case insensitively) strings of the form
+ * NaN(x), where x is a string of hexadecimal digits (optionally
+ * preceded by 0x or 0X) and spaces; if there is only one string
+ * of hexadecimal digits, it is taken for the fraction bits of the
+ * resulting NaN; if there are two or more strings of hexadecimal
+ * digits, each string is assigned to the next available sequence
+ * of 32-bit words of fractions bits (starting with the most
+ * significant), right-aligned in each sequence.
+ * Unless GDTOA_NON_PEDANTIC_NANCHECK is #defined, input "NaN(...)"
+ * is consumed even when ... has the wrong form (in which case the
+ * "(...)" is consumed but ignored).
+ * #define MULTIPLE_THREADS if the system offers preemptively scheduled
+ * multiple threads. In this case, you must provide (or suitably
+ * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed
+ * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed
+ * in pow5mult, ensures lazy evaluation of only one copy of high
+ * powers of 5; omitting this lock would introduce a small
+ * probability of wasting memory, but would otherwise be harmless.)
+ * You must also invoke freedtoa(s) to free the value s returned by
+ * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined.
+ * #define IMPRECISE_INEXACT if you do not care about the setting of
+ * the STRTOG_Inexact bits in the special case of doing IEEE double
+ * precision conversions (which could also be done by the strtog in
+ * dtoa.c).
+ * #define NO_HEX_FP to disable recognition of C9x's hexadecimal
+ * floating-point constants.
+ * #define -DNO_ERRNO to suppress setting errno (in strtod.c and
+ * strtodg.c).
+ * #define NO_STRING_H to use private versions of memcpy.
+ * On some K&R systems, it may also be necessary to
+ * #define DECLARE_SIZE_T in this case.
+ * #define YES_ALIAS to permit aliasing certain double values with
+ * arrays of ULongs. This leads to slightly better code with
+ * some compilers and was always used prior to 19990916, but it
+ * is not strictly legal and can cause trouble with aggressively
+ * optimizing compilers (e.g., gcc 2.95.1 under -O2).
+ * #define USE_LOCALE to use the current locale's decimal_point value.
+ */
+
+#ifndef GDTOAIMP_H_INCLUDED
+#define GDTOAIMP_H_INCLUDED
+
+#define Long int
+
+#include "gdtoa.h"
+#include "gd_qnan.h"
+
+#ifdef DEBUG
+#include "stdio.h"
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#endif
+
+#include "stdlib.h"
+#include "string.h"
+
+#ifdef KR_headers
+#define Char char
+#else
+#define Char void
+#endif
+
+#ifdef MALLOC
+extern Char *MALLOC ANSI((size_t));
+#else
+#define MALLOC malloc
+#endif
+
+#undef IEEE_Arith
+#undef Avoid_Underflow
+#ifdef IEEE_MC68k
+#define IEEE_Arith
+#endif
+#ifdef IEEE_8087
+#define IEEE_Arith
+#endif
+
+#include "errno.h"
+#ifdef Bad_float_h
+
+#ifdef IEEE_Arith
+#define DBL_DIG 15
+#define DBL_MAX_10_EXP 308
+#define DBL_MAX_EXP 1024
+#define FLT_RADIX 2
+#define DBL_MAX 1.7976931348623157e+308
+#endif
+
+#ifdef IBM
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 75
+#define DBL_MAX_EXP 63
+#define FLT_RADIX 16
+#define DBL_MAX 7.2370055773322621e+75
+#endif
+
+#ifdef VAX
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 38
+#define DBL_MAX_EXP 127
+#define FLT_RADIX 2
+#define DBL_MAX 1.7014118346046923e+38
+#define n_bigtens 2
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX 2147483647
+#endif
+
+#else /* ifndef Bad_float_h */
+#include "float.h"
+#endif /* Bad_float_h */
+
+#ifdef IEEE_Arith
+#define Scale_Bit 0x10
+#define n_bigtens 5
+#endif
+
+#ifdef IBM
+#define n_bigtens 3
+#endif
+
+#ifdef VAX
+#define n_bigtens 2
+#endif
+
+#ifndef __MATH_H__
+#include "math.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
+Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
+#endif
+
+typedef union { double d; ULong L[2]; } U;
+
+#ifdef YES_ALIAS
+#define dval(x) x
+#ifdef IEEE_8087
+#define word0(x) ((ULong *)&x)[1]
+#define word1(x) ((ULong *)&x)[0]
+#else
+#define word0(x) ((ULong *)&x)[0]
+#define word1(x) ((ULong *)&x)[1]
+#endif
+#else /* !YES_ALIAS */
+#ifdef IEEE_8087
+#define word0(x) ((U*)&x)->L[1]
+#define word1(x) ((U*)&x)->L[0]
+#else
+#define word0(x) ((U*)&x)->L[0]
+#define word1(x) ((U*)&x)->L[1]
+#endif
+#define dval(x) ((U*)&x)->d
+#endif /* YES_ALIAS */
+
+/* The following definition of Storeinc is appropriate for MIPS processors.
+ * An alternative that might be better on some machines is
+ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+ */
+#if defined(IEEE_8087) + defined(VAX)
+#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
+((unsigned short *)a)[0] = (unsigned short)c, a++)
+#else
+#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
+((unsigned short *)a)[1] = (unsigned short)c, a++)
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#ifdef IEEE_Arith
+#define Exp_shift 20
+#define Exp_shift1 20
+#define Exp_msk1 0x100000
+#define Exp_msk11 0x100000
+#define Exp_mask 0x7ff00000
+#define P 53
+#define Bias 1023
+#define Emin (-1022)
+#define Exp_1 0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask 0xfffff
+#define Frac_mask1 0xfffff
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask 0xfffff
+#define Bndry_mask1 0xfffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+
+#ifndef Flt_Rounds
+#ifdef FLT_ROUNDS
+#define Flt_Rounds FLT_ROUNDS
+#else
+#define Flt_Rounds 1
+#endif
+#endif /*Flt_Rounds*/
+
+#else /* ifndef IEEE_Arith */
+#undef Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#undef Flt_Rounds
+#define Flt_Rounds 0
+#define Exp_shift 24
+#define Exp_shift1 24
+#define Exp_msk1 0x1000000
+#define Exp_msk11 0x1000000
+#define Exp_mask 0x7f000000
+#define P 14
+#define Bias 65
+#define Exp_1 0x41000000
+#define Exp_11 0x41000000
+#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask 0xffffff
+#define Frac_mask1 0xffffff
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask 0xefffff
+#define Bndry_mask1 0xffffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 4
+#define Tiny0 0x100000
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#undef Flt_Rounds
+#define Flt_Rounds 1
+#define Exp_shift 23
+#define Exp_shift1 7
+#define Exp_msk1 0x80
+#define Exp_msk11 0x800000
+#define Exp_mask 0x7f80
+#define P 56
+#define Bias 129
+#define Exp_1 0x40800000
+#define Exp_11 0x4080
+#define Ebits 8
+#define Frac_mask 0x7fffff
+#define Frac_mask1 0xffff007f
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask 0xffff007f
+#define Bndry_mask1 0xffff007f
+#define LSB 0x10000
+#define Sign_bit 0x8000
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif /* IBM, VAX */
+#endif /* IEEE_Arith */
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+#ifdef KR_headers
+extern double rnd_prod(), rnd_quot();
+#else
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#endif
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+
+#undef Pack_16
+#ifndef Pack_32
+#define Pack_32
+#endif
+
+#ifdef NO_LONG_LONG
+#undef ULLong
+#ifdef Just_16
+#undef Pack_32
+#define Pack_16
+/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower. Hence the default is now to store 32 bits per Long.
+ */
+#endif
+#else /* long long available */
+#ifndef Llong
+#define Llong long long
+#endif
+#ifndef ULLong
+#define ULLong unsigned Llong
+#endif
+#endif /* NO_LONG_LONG */
+
+#ifdef Pack_32
+#define ULbits 32
+#define kshift 5
+#define kmask 31
+#define ALL_ON 0xffffffff
+#else
+#define ULbits 16
+#define kshift 4
+#define kmask 15
+#define ALL_ON 0xffff
+#endif
+
+#ifndef MULTIPLE_THREADS
+#define ACQUIRE_DTOA_LOCK(n) /*nothing*/
+#define FREE_DTOA_LOCK(n) /*nothing*/
+#else
+#include "thread_private.h"
+extern void *__dtoa_locks[];
+#define ACQUIRE_DTOA_LOCK(n) _MUTEX_LOCK(&__dtoa_locks[n])
+#define FREE_DTOA_LOCK(n) _MUTEX_UNLOCK(&__dtoa_locks[n])
+#endif
+
+#define Kmax 15
+
+ struct
+Bigint {
+ struct Bigint *next;
+ int k, maxwds, sign, wds;
+ ULong x[1];
+ };
+
+ typedef struct Bigint Bigint;
+
+#ifdef NO_STRING_H
+#ifdef DECLARE_SIZE_T
+typedef unsigned int size_t;
+#endif
+extern void memcpy_D2A ANSI((void*, const void*, size_t));
+#define Bcopy(x,y) memcpy_D2A(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int))
+#else /* !NO_STRING_H */
+#define Bcopy(x,y) memcpy(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int))
+#endif /* NO_STRING_H */
+
+#define dtoa __dtoa
+#define gdtoa __gdtoa
+#define freedtoa __freedtoa
+#define strtodg __strtodg
+#define g_ddfmt __g_ddfmt
+#define g_dfmt __g_dfmt
+#define g_ffmt __g_ffmt
+#define g_Qfmt __g_Qfmt
+#define g_xfmt __g_xfmt
+#define g_xLfmt __g_xLfmt
+#define strtoId __strtoId
+#define strtoIdd __strtoIdd
+#define strtoIf __strtoIf
+#define strtoIQ __strtoIQ
+#define strtoIx __strtoIx
+#define strtoIxL __strtoIxL
+#define strtord __strtord
+#define strtordd __strtordd
+#define strtorf __strtorf
+#define strtorQ __strtorQ
+#define strtorx __strtorx
+#define strtorxL __strtorxL
+#define strtodI __strtodI
+#define strtopd __strtopd
+#define strtopdd __strtopdd
+#define strtopf __strtopf
+#define strtopQ __strtopQ
+#define strtopx __strtopx
+#define strtopxL __strtopxL
+
+#define Balloc __Balloc_D2A
+#define Bfree __Bfree_D2A
+#define ULtoQ __ULtoQ_D2A
+#define ULtof __ULtof_D2A
+#define ULtod __ULtod_D2A
+#define ULtodd __ULtodd_D2A
+#define ULtox __ULtox_D2A
+#define ULtoxL __ULtoxL_D2A
+#define any_on __any_on_D2A
+#define b2d __b2d_D2A
+#define bigtens __bigtens_D2A
+#define cmp __cmp_D2A
+#define copybits __copybits_D2A
+#define d2b __d2b_D2A
+#define decrement __decrement_D2A
+#define diff __diff_D2A
+#define dtoa_result __dtoa_result_D2A
+#define g__fmt __g__fmt_D2A
+#define gethex __gethex_D2A
+#define hexdig __hexdig_D2A
+#define hexnan __hexnan_D2A
+#define hi0bits __hi0bits_D2A
+#define hi0bits_D2A __hi0bits_D2A
+#define i2b __i2b_D2A
+#define increment __increment_D2A
+#define lo0bits __lo0bits_D2A
+#define lshift __lshift_D2A
+#define match __match_D2A
+#define mult __mult_D2A
+#define multadd __multadd_D2A
+#define nrv_alloc __nrv_alloc_D2A
+#define pow5mult __pow5mult_D2A
+#define quorem __quorem_D2A
+#define ratio __ratio_D2A
+#define rshift __rshift_D2A
+#define rv_alloc __rv_alloc_D2A
+#define s2b __s2b_D2A
+#define set_ones __set_ones_D2A
+#define strcp __strcp_D2A
+#define strtoIg __strtoIg_D2A
+#define sum __sum_D2A
+#define tens __tens_D2A
+#define tinytens __tinytens_D2A
+#define tinytens __tinytens_D2A
+#define trailz __trailz_D2A
+#define ulp __ulp_D2A
+
+ extern char *dtoa_result;
+ extern CONST double bigtens[], tens[], tinytens[];
+ extern unsigned char hexdig[];
+
+ extern Bigint *Balloc ANSI((int));
+ extern void Bfree ANSI((Bigint*));
+ extern void ULtof ANSI((ULong*, ULong*, Long, int));
+ extern void ULtod ANSI((ULong*, ULong*, Long, int));
+ extern void ULtodd ANSI((ULong*, ULong*, Long, int));
+ extern void ULtoQ ANSI((ULong*, ULong*, Long, int));
+ extern void ULtox ANSI((UShort*, ULong*, Long, int));
+ extern void ULtoxL ANSI((ULong*, ULong*, Long, int));
+ extern ULong any_on ANSI((Bigint*, int));
+ extern double b2d ANSI((Bigint*, int*));
+ extern int cmp ANSI((Bigint*, Bigint*));
+ extern void copybits ANSI((ULong*, int, Bigint*));
+ extern Bigint *d2b ANSI((double, int*, int*));
+ extern int decrement ANSI((Bigint*));
+ extern Bigint *diff ANSI((Bigint*, Bigint*));
+ extern char *dtoa ANSI((double d, int mode, int ndigits,
+ int *decpt, int *sign, char **rve));
+ extern char *gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp,
+ int mode, int ndigits, int *decpt, char **rve));
+ extern char *g__fmt ANSI((char*, char*, char*, int, ULong));
+ extern int gethex ANSI((CONST char**, FPI*, Long*, Bigint**, int));
+ extern void hexdig_init_D2A(Void);
+ extern int hexnan ANSI((CONST char**, FPI*, ULong*));
+ extern int hi0bits_D2A ANSI((ULong));
+ extern Bigint *i2b ANSI((int));
+ extern Bigint *increment ANSI((Bigint*));
+ extern int lo0bits ANSI((ULong*));
+ extern Bigint *lshift ANSI((Bigint*, int));
+ extern int match ANSI((CONST char**, char*));
+ extern Bigint *mult ANSI((Bigint*, Bigint*));
+ extern Bigint *multadd ANSI((Bigint*, int, int));
+ extern char *nrv_alloc ANSI((char*, char **, int));
+ extern Bigint *pow5mult ANSI((Bigint*, int));
+ extern int quorem ANSI((Bigint*, Bigint*));
+ extern double ratio ANSI((Bigint*, Bigint*));
+ extern void rshift ANSI((Bigint*, int));
+ extern char *rv_alloc ANSI((int));
+ extern Bigint *s2b ANSI((CONST char*, int, int, ULong));
+ extern Bigint *set_ones ANSI((Bigint*, int));
+ extern char *strcp ANSI((char*, const char*));
+ extern int strtoIg ANSI((CONST char*, char**, FPI*, Long*, Bigint**, int*));
+ extern double strtod ANSI((const char *s00, char **se));
+ extern Bigint *sum ANSI((Bigint*, Bigint*));
+ extern int trailz ANSI((Bigint*));
+ extern double ulp ANSI((double));
+
+#ifdef __cplusplus
+}
+#endif
+/*
+ * NAN_WORD0 and NAN_WORD1 are only referenced in strtod.c. Prior to
+ * 20050115, they used to be hard-wired here (to 0x7ff80000 and 0,
+ * respectively), but now are determined by compiling and running
+ * qnan.c to generate gd_qnan.h, which specifies d_QNAN0 and d_QNAN1.
+ * Formerly gdtoaimp.h recommended supplying suitable -DNAN_WORD0=...
+ * and -DNAN_WORD1=... values if necessary. This should still work.
+ * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
+ */
+#ifdef IEEE_Arith
+#ifdef IEEE_MC68k
+#define _0 0
+#define _1 1
+#ifndef NAN_WORD0
+#define NAN_WORD0 d_QNAN0
+#endif
+#ifndef NAN_WORD1
+#define NAN_WORD1 d_QNAN1
+#endif
+#else
+#define _0 1
+#define _1 0
+#ifndef NAN_WORD0
+#define NAN_WORD0 d_QNAN1
+#endif
+#ifndef NAN_WORD1
+#define NAN_WORD1 d_QNAN0
+#endif
+#endif
+#else
+#undef INFNAN_CHECK
+#endif
+
+#undef SI
+#ifdef Sudden_Underflow
+#define SI 1
+#else
+#define SI 0
+#endif
+
+#endif /* GDTOAIMP_H_INCLUDED */
diff --git a/lib/libc/gdtoa/gethex.c b/lib/libc/gdtoa/gethex.c
new file mode 100644
index 00000000000..f130fd53112
--- /dev/null
+++ b/lib/libc/gdtoa/gethex.c
@@ -0,0 +1,250 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+#ifdef USE_LOCALE
+#include "locale.h"
+#endif
+
+ int
+#ifdef KR_headers
+gethex(sp, fpi, exp, bp, sign)
+ CONST char **sp; FPI *fpi; Long *exp; Bigint **bp; int sign;
+#else
+gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
+#endif
+{
+ Bigint *b;
+ CONST unsigned char *decpt, *s0, *s, *s1;
+ int esign, havedig, irv, k, n, nbits, up, zret;
+ ULong L, lostbits, *x;
+ Long e, e1;
+#ifdef USE_LOCALE
+ unsigned char decimalpoint = *localeconv()->decimal_point;
+#else
+#define decimalpoint '.'
+#endif
+
+ if (!hexdig['0'])
+ hexdig_init_D2A();
+ havedig = 0;
+ s0 = *(CONST unsigned char **)sp + 2;
+ while(s0[havedig] == '0')
+ havedig++;
+ s0 += havedig;
+ s = s0;
+ decpt = 0;
+ zret = 0;
+ e = 0;
+ if (!hexdig[*s]) {
+ zret = 1;
+ if (*s != decimalpoint)
+ goto pcheck;
+ decpt = ++s;
+ if (!hexdig[*s])
+ goto pcheck;
+ while(*s == '0')
+ s++;
+ if (hexdig[*s])
+ zret = 0;
+ havedig = 1;
+ s0 = s;
+ }
+ while(hexdig[*s])
+ s++;
+ if (*s == decimalpoint && !decpt) {
+ decpt = ++s;
+ while(hexdig[*s])
+ s++;
+ }
+ if (decpt)
+ e = -(((Long)(s-decpt)) << 2);
+ pcheck:
+ s1 = s;
+ switch(*s) {
+ case 'p':
+ case 'P':
+ esign = 0;
+ switch(*++s) {
+ case '-':
+ esign = 1;
+ /* no break */
+ case '+':
+ s++;
+ }
+ if ((n = hexdig[*s]) == 0 || n > 0x19) {
+ s = s1;
+ break;
+ }
+ e1 = n - 0x10;
+ while((n = hexdig[*++s]) !=0 && n <= 0x19)
+ e1 = 10*e1 + n - 0x10;
+ if (esign)
+ e1 = -e1;
+ e += e1;
+ }
+ *sp = (char*)s;
+ if (zret) {
+ if (!havedig)
+ *sp = s0 - 1;
+ return STRTOG_Zero;
+ }
+ n = s1 - s0 - 1;
+ for(k = 0; n > 7; n >>= 1)
+ k++;
+ b = Balloc(k);
+ x = b->x;
+ n = 0;
+ L = 0;
+ while(s1 > s0) {
+ if (*--s1 == decimalpoint)
+ continue;
+ if (n == 32) {
+ *x++ = L;
+ L = 0;
+ n = 0;
+ }
+ L |= (hexdig[*s1] & 0x0f) << n;
+ n += 4;
+ }
+ *x++ = L;
+ b->wds = n = x - b->x;
+ n = 32*n - hi0bits(L);
+ nbits = fpi->nbits;
+ lostbits = 0;
+ x = b->x;
+ if (n > nbits) {
+ n -= nbits;
+ if (any_on(b,n)) {
+ lostbits = 1;
+ k = n - 1;
+ if (x[k>>kshift] & 1 << (k & kmask)) {
+ lostbits = 2;
+ if (k > 1 && any_on(b,k-1))
+ lostbits = 3;
+ }
+ }
+ rshift(b, n);
+ e += n;
+ }
+ else if (n < nbits) {
+ n = nbits - n;
+ b = lshift(b, n);
+ e -= n;
+ x = b->x;
+ }
+ if (e > fpi->emax) {
+ ovfl:
+ Bfree(b);
+ *bp = 0;
+ return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
+ }
+ irv = STRTOG_Normal;
+ if (e < fpi->emin) {
+ irv = STRTOG_Denormal;
+ n = fpi->emin - e;
+ if (n >= nbits) {
+ switch (fpi->rounding) {
+ case FPI_Round_near:
+ if (n == nbits && (n < 2 || any_on(b,n-1)))
+ goto one_bit;
+ break;
+ case FPI_Round_up:
+ if (!sign)
+ goto one_bit;
+ break;
+ case FPI_Round_down:
+ if (sign) {
+ one_bit:
+ *exp = fpi->emin;
+ x[0] = b->wds = 1;
+ *bp = b;
+ return STRTOG_Denormal | STRTOG_Inexhi
+ | STRTOG_Underflow;
+ }
+ }
+ Bfree(b);
+ *bp = 0;
+ return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow;
+ }
+ k = n - 1;
+ if (lostbits)
+ lostbits = 1;
+ else if (k > 0)
+ lostbits = any_on(b,k);
+ if (x[k>>kshift] & 1 << (k & kmask))
+ lostbits |= 2;
+ nbits -= n;
+ rshift(b,n);
+ e = fpi->emin;
+ }
+ if (lostbits) {
+ up = 0;
+ switch(fpi->rounding) {
+ case FPI_Round_zero:
+ break;
+ case FPI_Round_near:
+ if (lostbits & 2
+ && (lostbits & 1) | x[0] & 1)
+ up = 1;
+ break;
+ case FPI_Round_up:
+ up = 1 - sign;
+ break;
+ case FPI_Round_down:
+ up = sign;
+ }
+ if (up) {
+ k = b->wds;
+ b = increment(b);
+ x = b->x;
+ if (irv == STRTOG_Denormal) {
+ if (nbits == fpi->nbits - 1
+ && x[nbits >> kshift] & 1 << (nbits & kmask))
+ irv = STRTOG_Normal;
+ }
+ else if (b->wds > k
+ || (n = nbits & kmask) !=0
+ && hi0bits(x[k-1]) < 32-n) {
+ rshift(b,1);
+ if (++e > fpi->emax)
+ goto ovfl;
+ }
+ irv |= STRTOG_Inexhi;
+ }
+ else
+ irv |= STRTOG_Inexlo;
+ }
+ *bp = b;
+ *exp = e;
+ return irv;
+ }
diff --git a/lib/libc/gdtoa/gmisc.c b/lib/libc/gdtoa/gmisc.c
new file mode 100644
index 00000000000..8270ef94479
--- /dev/null
+++ b/lib/libc/gdtoa/gmisc.c
@@ -0,0 +1,86 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ void
+#ifdef KR_headers
+rshift(b, k) Bigint *b; int k;
+#else
+rshift(Bigint *b, int k)
+#endif
+{
+ ULong *x, *x1, *xe, y;
+ int n;
+
+ x = x1 = b->x;
+ n = k >> kshift;
+ if (n < b->wds) {
+ xe = x + b->wds;
+ x += n;
+ if (k &= kmask) {
+ n = ULbits - k;
+ y = *x++ >> k;
+ while(x < xe) {
+ *x1++ = (y | (*x << n)) & ALL_ON;
+ y = *x++ >> k;
+ }
+ if ((*x1 = y) !=0)
+ x1++;
+ }
+ else
+ while(x < xe)
+ *x1++ = *x++;
+ }
+ if ((b->wds = x1 - b->x) == 0)
+ b->x[0] = 0;
+ }
+
+ int
+#ifdef KR_headers
+trailz(b) Bigint *b;
+#else
+trailz(Bigint *b)
+#endif
+{
+ ULong L, *x, *xe;
+ int n = 0;
+
+ x = b->x;
+ xe = x + b->wds;
+ for(n = 0; x < xe && !*x; x++)
+ n += ULbits;
+ if (x < xe) {
+ L = *x;
+ n += lo0bits(&L);
+ }
+ return n;
+ }
diff --git a/lib/libc/gdtoa/hd_init.c b/lib/libc/gdtoa/hd_init.c
new file mode 100644
index 00000000000..fa6e18dee8f
--- /dev/null
+++ b/lib/libc/gdtoa/hd_init.c
@@ -0,0 +1,55 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ unsigned char hexdig[256];
+
+ static void
+#ifdef KR_headers
+htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc;
+#else
+htinit(unsigned char *h, unsigned char *s, int inc)
+#endif
+{
+ int i, j;
+ for(i = 0; (j = s[i]) !=0; i++)
+ h[j] = i + inc;
+ }
+
+ void
+hexdig_init_D2A(Void)
+{
+#define USC (unsigned char *)
+ htinit(hexdig, USC "0123456789", 0x10);
+ htinit(hexdig, USC "abcdef", 0x10 + 10);
+ htinit(hexdig, USC "ABCDEF", 0x10 + 10);
+ }
diff --git a/lib/libc/gdtoa/hdtoa.c b/lib/libc/gdtoa/hdtoa.c
new file mode 100644
index 00000000000..f841538a300
--- /dev/null
+++ b/lib/libc/gdtoa/hdtoa.c
@@ -0,0 +1,328 @@
+/* $OpenBSD: hdtoa.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*-
+ * Copyright (c) 2004, 2005 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/types.h>
+#include <machine/ieee.h>
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+
+#include "gdtoaimp.h"
+
+/* Strings values used by dtoa() */
+#define INFSTR "Infinity"
+#define NANSTR "NaN"
+
+#define DBL_ADJ (DBL_MAX_EXP - 2 + ((DBL_MANT_DIG - 1) % 4))
+#define LDBL_ADJ (LDBL_MAX_EXP - 2 + ((LDBL_MANT_DIG - 1) % 4))
+
+/*
+ * Round up the given digit string. If the digit string is fff...f,
+ * this procedure sets it to 100...0 and returns 1 to indicate that
+ * the exponent needs to be bumped. Otherwise, 0 is returned.
+ */
+static int
+roundup(char *s0, int ndigits)
+{
+ char *s;
+
+ for (s = s0 + ndigits - 1; *s == 0xf; s--) {
+ if (s == s0) {
+ *s = 1;
+ return (1);
+ }
+ *s = 0;
+ }
+ ++*s;
+ return (0);
+}
+
+/*
+ * Round the given digit string to ndigits digits according to the
+ * current rounding mode. Note that this could produce a string whose
+ * value is not representable in the corresponding floating-point
+ * type. The exponent pointed to by decpt is adjusted if necessary.
+ */
+static void
+dorounding(char *s0, int ndigits, int sign, int *decpt)
+{
+ int adjust = 0; /* do we need to adjust the exponent? */
+
+ switch (FLT_ROUNDS) {
+ case 0: /* toward zero */
+ default: /* implementation-defined */
+ break;
+ case 1: /* to nearest, halfway rounds to even */
+ if ((s0[ndigits] > 8) ||
+ (s0[ndigits] == 8 && s0[ndigits + 1] & 1))
+ adjust = roundup(s0, ndigits);
+ break;
+ case 2: /* toward +inf */
+ if (sign == 0)
+ adjust = roundup(s0, ndigits);
+ break;
+ case 3: /* toward -inf */
+ if (sign != 0)
+ adjust = roundup(s0, ndigits);
+ break;
+ }
+
+ if (adjust)
+ *decpt += 4;
+}
+
+/*
+ * This procedure converts a double-precision number in IEEE format
+ * into a string of hexadecimal digits and an exponent of 2. Its
+ * behavior is bug-for-bug compatible with dtoa() in mode 2, with the
+ * following exceptions:
+ *
+ * - An ndigits < 0 causes it to use as many digits as necessary to
+ * represent the number exactly.
+ * - The additional xdigs argument should point to either the string
+ * "0123456789ABCDEF" or the string "0123456789abcdef", depending on
+ * which case is desired.
+ * - This routine does not repeat dtoa's mistake of setting decpt
+ * to 9999 in the case of an infinity or NaN. INT_MAX is used
+ * for this purpose instead.
+ *
+ * Note that the C99 standard does not specify what the leading digit
+ * should be for non-zero numbers. For instance, 0x1.3p3 is the same
+ * as 0x2.6p2 is the same as 0x4.cp3. This implementation chooses the
+ * first digit so that subsequent digits are aligned on nibble
+ * boundaries (before rounding).
+ *
+ * Inputs: d, xdigs, ndigits
+ * Outputs: decpt, sign, rve
+ */
+char *
+__hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign,
+ char **rve)
+{
+ static const int sigfigs = (DBL_MANT_DIG + 3) / 4;
+ struct ieee_double *p = (struct ieee_double *)&d;
+ char *s, *s0;
+ int bufsize;
+
+ *sign = p->dbl_sign;
+
+ switch (fpclassify(d)) {
+ case FP_NORMAL:
+ *decpt = p->dbl_exp - DBL_ADJ;
+ break;
+ case FP_ZERO:
+ *decpt = 1;
+ return (nrv_alloc("0", rve, 1));
+ case FP_SUBNORMAL:
+ d *= 0x1p514;
+ *decpt = p->dbl_exp - (514 + DBL_ADJ);
+ break;
+ case FP_INFINITE:
+ *decpt = INT_MAX;
+ return (nrv_alloc(INFSTR, rve, sizeof(INFSTR) - 1));
+ case FP_NAN:
+ *decpt = INT_MAX;
+ return (nrv_alloc(NANSTR, rve, sizeof(NANSTR) - 1));
+ default:
+ abort();
+ }
+
+ /* FP_NORMAL or FP_SUBNORMAL */
+
+ if (ndigits == 0) /* dtoa() compatibility */
+ ndigits = 1;
+
+ /*
+ * For simplicity, we generate all the digits even if the
+ * caller has requested fewer.
+ */
+ bufsize = (sigfigs > ndigits) ? sigfigs : ndigits;
+ s0 = rv_alloc(bufsize);
+
+ /*
+ * We work from right to left, first adding any requested zero
+ * padding, then the least significant portion of the
+ * mantissa, followed by the most significant. The buffer is
+ * filled with the byte values 0x0 through 0xf, which are
+ * converted to xdigs[0x0] through xdigs[0xf] after the
+ * rounding phase.
+ */
+ for (s = s0 + bufsize - 1; s > s0 + sigfigs - 1; s--)
+ *s = 0;
+ for (; s > s0 + sigfigs - (DBL_FRACLBITS / 4) - 1 && s > s0; s--) {
+ *s = p->dbl_fracl & 0xf;
+ p->dbl_fracl >>= 4;
+ }
+ for (; s > s0; s--) {
+ *s = p->dbl_frach & 0xf;
+ p->dbl_frach >>= 4;
+ }
+
+ /*
+ * At this point, we have snarfed all the bits in the
+ * mantissa, with the possible exception of the highest-order
+ * (partial) nibble, which is dealt with by the next
+ * statement. We also tack on the implicit normalization bit.
+ */
+ *s = p->dbl_frach | (1U << ((DBL_MANT_DIG - 1) % 4));
+
+ /* If ndigits < 0, we are expected to auto-size the precision. */
+ if (ndigits < 0) {
+ for (ndigits = sigfigs; s0[ndigits - 1] == 0; ndigits--)
+ ;
+ }
+
+ if (sigfigs > ndigits && s0[ndigits] != 0)
+ dorounding(s0, ndigits, p->dbl_sign, decpt);
+
+ s = s0 + ndigits;
+ if (rve != NULL)
+ *rve = s;
+ *s-- = '\0';
+ for (; s >= s0; s--)
+ *s = xdigs[(unsigned int)*s];
+
+ return (s0);
+}
+
+#if (LDBL_MANT_DIG > DBL_MANT_DIG)
+
+/*
+ * This is the long double version of __hdtoa().
+ */
+char *
+__hldtoa(long double e, const char *xdigs, int ndigits, int *decpt, int *sign,
+ char **rve)
+{
+ static const int sigfigs = (LDBL_MANT_DIG + 3) / 4;
+ struct ieee_ext *p = (struct ieee_ext *)&e;
+ char *s, *s0;
+ int bufsize;
+
+ *sign = p->ext_sign;
+
+ switch (fpclassify(e)) {
+ case FP_NORMAL:
+ *decpt = p->ext_exp - LDBL_ADJ;
+ break;
+ case FP_ZERO:
+ *decpt = 1;
+ return (nrv_alloc("0", rve, 1));
+ case FP_SUBNORMAL:
+ e *= 0x1p514L;
+ *decpt = p->ext_exp - (514 + LDBL_ADJ);
+ break;
+ case FP_INFINITE:
+ *decpt = INT_MAX;
+ return (nrv_alloc(INFSTR, rve, sizeof(INFSTR) - 1));
+ case FP_NAN:
+ *decpt = INT_MAX;
+ return (nrv_alloc(NANSTR, rve, sizeof(NANSTR) - 1));
+ default:
+ abort();
+ }
+
+ /* FP_NORMAL or FP_SUBNORMAL */
+
+ if (ndigits == 0) /* dtoa() compatibility */
+ ndigits = 1;
+
+ /*
+ * For simplicity, we generate all the digits even if the
+ * caller has requested fewer.
+ */
+ bufsize = (sigfigs > ndigits) ? sigfigs : ndigits;
+ s0 = rv_alloc(bufsize);
+
+ /*
+ * We work from right to left, first adding any requested zero
+ * padding, then the least significant portion of the
+ * mantissa, followed by the most significant. The buffer is
+ * filled with the byte values 0x0 through 0xf, which are
+ * converted to xdigs[0x0] through xdigs[0xf] after the
+ * rounding phase.
+ */
+ for (s = s0 + bufsize - 1; s > s0 + sigfigs - 1; s--)
+ *s = 0;
+ for (; s > s0 + sigfigs - (EXT_FRACLBITS / 4) - 1 && s > s0; s--) {
+ *s = p->ext_fracl & 0xf;
+ p->ext_fracl >>= 4;
+ }
+#ifdef EXT_FRACHMBITS
+ for (; s > s0; s--) {
+ *s = p->ext_frachm & 0xf;
+ p->ext_frachm >>= 4;
+ }
+#endif
+#ifdef EXT_FRACLMBITS
+ for (; s > s0; s--) {
+ *s = p->ext_fraclm & 0xf;
+ p->ext_fraclm >>= 4;
+ }
+#endif
+ for (; s > s0; s--) {
+ *s = p->ext_frach & 0xf;
+ p->ext_frach >>= 4;
+ }
+
+ /*
+ * At this point, we have snarfed all the bits in the
+ * mantissa, with the possible exception of the highest-order
+ * (partial) nibble, which is dealt with by the next
+ * statement. We also tack on the implicit normalization bit.
+ */
+ *s = p->ext_frach | (1U << ((LDBL_MANT_DIG - 1) % 4));
+
+ /* If ndigits < 0, we are expected to auto-size the precision. */
+ if (ndigits < 0) {
+ for (ndigits = sigfigs; s0[ndigits - 1] == 0; ndigits--)
+ ;
+ }
+
+ if (sigfigs > ndigits && s0[ndigits] != 0)
+ dorounding(s0, ndigits, p->ext_sign, decpt);
+
+ s = s0 + ndigits;
+ if (rve != NULL)
+ *rve = s;
+ *s-- = '\0';
+ for (; s >= s0; s--)
+ *s = xdigs[(unsigned int)*s];
+
+ return (s0);
+}
+
+#else /* (LDBL_MANT_DIG == DBL_MANT_DIG) */
+
+char *
+__hldtoa(long double e, const char *xdigs, int ndigits, int *decpt, int *sign,
+ char **rve)
+{
+ return (__hdtoa((double)e, xdigs, ndigits, decpt, sign, rve));
+}
+
+#endif /* (LDBL_MANT_DIG == DBL_MANT_DIG) */
diff --git a/lib/libc/gdtoa/hexnan.c b/lib/libc/gdtoa/hexnan.c
new file mode 100644
index 00000000000..e07e069ad69
--- /dev/null
+++ b/lib/libc/gdtoa/hexnan.c
@@ -0,0 +1,150 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ static void
+#ifdef KR_headers
+L_shift(x, x1, i) ULong *x; ULong *x1; int i;
+#else
+L_shift(ULong *x, ULong *x1, int i)
+#endif
+{
+ int j;
+
+ i = 8 - i;
+ i <<= 2;
+ j = ULbits - i;
+ do {
+ *x |= x[1] << j;
+ x[1] >>= i;
+ } while(++x < x1);
+ }
+
+ int
+#ifdef KR_headers
+hexnan(sp, fpi, x0)
+ CONST char **sp; FPI *fpi; ULong *x0;
+#else
+hexnan( CONST char **sp, FPI *fpi, ULong *x0)
+#endif
+{
+ ULong c, h, *x, *x1, *xe;
+ CONST char *s;
+ int havedig, hd0, i, nbits;
+
+ if (!hexdig['0'])
+ hexdig_init_D2A();
+ nbits = fpi->nbits;
+ x = x0 + (nbits >> kshift);
+ if (nbits & kmask)
+ x++;
+ *--x = 0;
+ x1 = xe = x;
+ havedig = hd0 = i = 0;
+ s = *sp;
+ /* allow optional initial 0x or 0X */
+ while((c = *(CONST unsigned char*)(s+1)) && c <= ' ')
+ ++s;
+ if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')
+ && *(CONST unsigned char*)(s+3) > ' ')
+ s += 2;
+ while(c = *(CONST unsigned char*)++s) {
+ if (!(h = hexdig[c])) {
+ if (c <= ' ') {
+ if (hd0 < havedig) {
+ if (x < x1 && i < 8)
+ L_shift(x, x1, i);
+ if (x <= x0) {
+ i = 8;
+ continue;
+ }
+ hd0 = havedig;
+ *--x = 0;
+ x1 = x;
+ i = 0;
+ }
+ while(*(CONST unsigned char*)(s+1) <= ' ')
+ ++s;
+ if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')
+ && *(CONST unsigned char*)(s+3) > ' ')
+ s += 2;
+ continue;
+ }
+ if (/*(*/ c == ')' && havedig) {
+ *sp = s + 1;
+ break;
+ }
+#ifndef GDTOA_NON_PEDANTIC_NANCHECK
+ do {
+ if (/*(*/ c == ')') {
+ *sp = s + 1;
+ break;
+ }
+ } while(c = *++s);
+#endif
+ return STRTOG_NaN;
+ }
+ havedig++;
+ if (++i > 8) {
+ if (x <= x0)
+ continue;
+ i = 1;
+ *--x = 0;
+ }
+ *x = (*x << 4) | h & 0xf;
+ }
+ if (!havedig)
+ return STRTOG_NaN;
+ if (x < x1 && i < 8)
+ L_shift(x, x1, i);
+ if (x > x0) {
+ x1 = x0;
+ do *x1++ = *x++;
+ while(x <= xe);
+ do *x1++ = 0;
+ while(x1 <= xe);
+ }
+ else {
+ /* truncate high-order word if necessary */
+ if ( (i = nbits & (ULbits-1)) !=0)
+ *xe &= ((ULong)0xffffffff) >> (ULbits - i);
+ }
+ for(x1 = xe;; --x1) {
+ if (*x1 != 0)
+ break;
+ if (x1 == x0) {
+ *x1 = 1;
+ break;
+ }
+ }
+ return STRTOG_NaNbits;
+ }
diff --git a/lib/libc/gdtoa/ldtoa.c b/lib/libc/gdtoa/ldtoa.c
new file mode 100644
index 00000000000..793d71cffb5
--- /dev/null
+++ b/lib/libc/gdtoa/ldtoa.c
@@ -0,0 +1,124 @@
+/* $OpenBSD: ldtoa.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*-
+ * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/types.h>
+#ifndef __vax__
+#include <machine/ieee.h>
+#endif /* !__vax__ */
+#include <float.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <math.h>
+#include <stdlib.h>
+#include "gdtoaimp.h"
+
+#if (LDBL_MANT_DIG > DBL_MANT_DIG)
+
+/*
+ * ldtoa() is a wrapper for gdtoa() that makes it smell like dtoa(),
+ * except that the floating point argument is passed by reference.
+ * When dtoa() is passed a NaN or infinity, it sets expt to 9999.
+ * However, a long double could have a valid exponent of 9999, so we
+ * use INT_MAX in ldtoa() instead.
+ */
+char *
+__ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign,
+ char **rve)
+{
+ FPI fpi = {
+ LDBL_MANT_DIG, /* nbits */
+ LDBL_MIN_EXP - LDBL_MANT_DIG, /* emin */
+ LDBL_MAX_EXP - LDBL_MANT_DIG, /* emax */
+ FLT_ROUNDS, /* rounding */
+#ifdef Sudden_Underflow /* unused, but correct anyway */
+ 1
+#else
+ 0
+#endif
+ };
+ int be, kind;
+ char *ret;
+ struct ieee_ext *p = (struct ieee_ext *)ld;
+ uint32_t bits[(LDBL_MANT_DIG + 31) / 32];
+ void *vbits = bits;
+
+ /*
+ * gdtoa doesn't know anything about the sign of the number, so
+ * if the number is negative, we need to swap rounding modes of
+ * 2 (upwards) and 3 (downwards).
+ */
+ *sign = p->ext_sign;
+ fpi.rounding ^= (fpi.rounding >> 1) & p->ext_sign;
+
+ be = p->ext_exp - (LDBL_MAX_EXP - 1) - (LDBL_MANT_DIG - 1);
+ EXT_TO_ARRAY32(p, bits);
+
+ switch (fpclassify(*ld)) {
+ case FP_NORMAL:
+ kind = STRTOG_Normal;
+#ifdef EXT_IMPLICIT_NBIT
+ bits[LDBL_MANT_DIG / 32] |= 1 << ((LDBL_MANT_DIG - 1) % 32);
+#endif /* EXT_IMPLICIT_NBIT */
+ break;
+ case FP_ZERO:
+ kind = STRTOG_Zero;
+ break;
+ case FP_SUBNORMAL:
+ kind = STRTOG_Denormal;
+ be++;
+ break;
+ case FP_INFINITE:
+ kind = STRTOG_Infinite;
+ break;
+ case FP_NAN:
+ kind = STRTOG_NaN;
+ break;
+ default:
+ abort();
+ }
+
+ ret = gdtoa(&fpi, be, vbits, &kind, mode, ndigits, decpt, rve);
+ if (*decpt == -32768)
+ *decpt = INT_MAX;
+ return ret;
+}
+
+#else /* (LDBL_MANT_DIG == DBL_MANT_DIG) */
+
+char *
+__ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign,
+ char **rve)
+{
+ char *ret;
+
+ ret = dtoa((double)*ld, mode, ndigits, decpt, sign, rve);
+ if (*decpt == 9999)
+ *decpt = INT_MAX;
+ return ret;
+}
+
+#endif /* (LDBL_MANT_DIG == DBL_MANT_DIG) */
diff --git a/lib/libc/gdtoa/locks.c b/lib/libc/gdtoa/locks.c
new file mode 100644
index 00000000000..75df2cb750d
--- /dev/null
+++ b/lib/libc/gdtoa/locks.c
@@ -0,0 +1,7 @@
+/* $OpenBSD: locks.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+
+/* Written by Martynas Venckus. Public Domain. */
+
+#include <stdio.h>
+
+void *__dtoa_locks[] = { NULL, NULL };
diff --git a/lib/libc/gdtoa/misc.c b/lib/libc/gdtoa/misc.c
new file mode 100644
index 00000000000..b3ce7c9b8a4
--- /dev/null
+++ b/lib/libc/gdtoa/misc.c
@@ -0,0 +1,865 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 1999 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ static Bigint *freelist[Kmax+1];
+#ifndef Omit_Private_Memory
+#ifndef PRIVATE_MEM
+#define PRIVATE_MEM 2304
+#endif
+#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
+static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
+#endif
+
+ Bigint *
+Balloc
+#ifdef KR_headers
+ (k) int k;
+#else
+ (int k)
+#endif
+{
+ int x;
+ Bigint *rv;
+#ifndef Omit_Private_Memory
+ unsigned int len;
+#endif
+
+ ACQUIRE_DTOA_LOCK(0);
+ if ( (rv = freelist[k]) !=0) {
+ freelist[k] = rv->next;
+ }
+ else {
+ x = 1 << k;
+#ifdef Omit_Private_Memory
+ rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
+#else
+ len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
+ /sizeof(double);
+ if (pmem_next - private_mem + len <= PRIVATE_mem) {
+ rv = (Bigint*)pmem_next;
+ pmem_next += len;
+ }
+ else
+ rv = (Bigint*)MALLOC(len*sizeof(double));
+#endif
+ rv->k = k;
+ rv->maxwds = x;
+ }
+ FREE_DTOA_LOCK(0);
+ rv->sign = rv->wds = 0;
+ return rv;
+ }
+
+ void
+Bfree
+#ifdef KR_headers
+ (v) Bigint *v;
+#else
+ (Bigint *v)
+#endif
+{
+ if (v) {
+ ACQUIRE_DTOA_LOCK(0);
+ v->next = freelist[v->k];
+ freelist[v->k] = v;
+ FREE_DTOA_LOCK(0);
+ }
+ }
+
+ int
+lo0bits
+#ifdef KR_headers
+ (y) ULong *y;
+#else
+ (ULong *y)
+#endif
+{
+ register int k;
+ register ULong x = *y;
+
+ if (x & 7) {
+ if (x & 1)
+ return 0;
+ if (x & 2) {
+ *y = x >> 1;
+ return 1;
+ }
+ *y = x >> 2;
+ return 2;
+ }
+ k = 0;
+ if (!(x & 0xffff)) {
+ k = 16;
+ x >>= 16;
+ }
+ if (!(x & 0xff)) {
+ k += 8;
+ x >>= 8;
+ }
+ if (!(x & 0xf)) {
+ k += 4;
+ x >>= 4;
+ }
+ if (!(x & 0x3)) {
+ k += 2;
+ x >>= 2;
+ }
+ if (!(x & 1)) {
+ k++;
+ x >>= 1;
+ if (!x)
+ return 32;
+ }
+ *y = x;
+ return k;
+ }
+
+ Bigint *
+multadd
+#ifdef KR_headers
+ (b, m, a) Bigint *b; int m, a;
+#else
+ (Bigint *b, int m, int a) /* multiply by m and add a */
+#endif
+{
+ int i, wds;
+#ifdef ULLong
+ ULong *x;
+ ULLong carry, y;
+#else
+ ULong carry, *x, y;
+#ifdef Pack_32
+ ULong xi, z;
+#endif
+#endif
+ Bigint *b1;
+
+ wds = b->wds;
+ x = b->x;
+ i = 0;
+ carry = a;
+ do {
+#ifdef ULLong
+ y = *x * (ULLong)m + carry;
+ carry = y >> 32;
+ *x++ = y & 0xffffffffUL;
+#else
+#ifdef Pack_32
+ xi = *x;
+ y = (xi & 0xffff) * m + carry;
+ z = (xi >> 16) * m + (y >> 16);
+ carry = z >> 16;
+ *x++ = (z << 16) + (y & 0xffff);
+#else
+ y = *x * m + carry;
+ carry = y >> 16;
+ *x++ = y & 0xffff;
+#endif
+#endif
+ }
+ while(++i < wds);
+ if (carry) {
+ if (wds >= b->maxwds) {
+ b1 = Balloc(b->k+1);
+ Bcopy(b1, b);
+ Bfree(b);
+ b = b1;
+ }
+ b->x[wds++] = carry;
+ b->wds = wds;
+ }
+ return b;
+ }
+
+ int
+hi0bits_D2A
+#ifdef KR_headers
+ (x) register ULong x;
+#else
+ (register ULong x)
+#endif
+{
+ register int k = 0;
+
+ if (!(x & 0xffff0000)) {
+ k = 16;
+ x <<= 16;
+ }
+ if (!(x & 0xff000000)) {
+ k += 8;
+ x <<= 8;
+ }
+ if (!(x & 0xf0000000)) {
+ k += 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0000000)) {
+ k += 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80000000)) {
+ k++;
+ if (!(x & 0x40000000))
+ return 32;
+ }
+ return k;
+ }
+
+ Bigint *
+i2b
+#ifdef KR_headers
+ (i) int i;
+#else
+ (int i)
+#endif
+{
+ Bigint *b;
+
+ b = Balloc(1);
+ b->x[0] = i;
+ b->wds = 1;
+ return b;
+ }
+
+ Bigint *
+mult
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ Bigint *c;
+ int k, wa, wb, wc;
+ ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+ ULong y;
+#ifdef ULLong
+ ULLong carry, z;
+#else
+ ULong carry, z;
+#ifdef Pack_32
+ ULong z2;
+#endif
+#endif
+
+ if (a->wds < b->wds) {
+ c = a;
+ a = b;
+ b = c;
+ }
+ k = a->k;
+ wa = a->wds;
+ wb = b->wds;
+ wc = wa + wb;
+ if (wc > a->maxwds)
+ k++;
+ c = Balloc(k);
+ for(x = c->x, xa = x + wc; x < xa; x++)
+ *x = 0;
+ xa = a->x;
+ xae = xa + wa;
+ xb = b->x;
+ xbe = xb + wb;
+ xc0 = c->x;
+#ifdef ULLong
+ for(; xb < xbe; xc0++) {
+ if ( (y = *xb++) !=0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = *x++ * (ULLong)y + *xc + carry;
+ carry = z >> 32;
+ *xc++ = z & 0xffffffffUL;
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ }
+#else
+#ifdef Pack_32
+ for(; xb < xbe; xb++, xc0++) {
+ if ( (y = *xb & 0xffff) !=0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+ carry = z >> 16;
+ z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+ carry = z2 >> 16;
+ Storeinc(xc, z2, z);
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ if ( (y = *xb >> 16) !=0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ z2 = *xc;
+ do {
+ z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+ carry = z >> 16;
+ Storeinc(xc, z, z2);
+ z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+ carry = z2 >> 16;
+ }
+ while(x < xae);
+ *xc = z2;
+ }
+ }
+#else
+ for(; xb < xbe; xc0++) {
+ if ( (y = *xb++) !=0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = *x++ * y + *xc + carry;
+ carry = z >> 16;
+ *xc++ = z & 0xffff;
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ }
+#endif
+#endif
+ for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+ c->wds = wc;
+ return c;
+ }
+
+ static Bigint *p5s;
+
+ Bigint *
+pow5mult
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint *b, int k)
+#endif
+{
+ Bigint *b1, *p5, *p51;
+ int i;
+ static int p05[3] = { 5, 25, 125 };
+
+ if ( (i = k & 3) !=0)
+ b = multadd(b, p05[i-1], 0);
+
+ if (!(k >>= 2))
+ return b;
+ if ((p5 = p5s) == 0) {
+ /* first time */
+#ifdef MULTIPLE_THREADS
+ ACQUIRE_DTOA_LOCK(1);
+ if (!(p5 = p5s)) {
+ p5 = p5s = i2b(625);
+ p5->next = 0;
+ }
+ FREE_DTOA_LOCK(1);
+#else
+ p5 = p5s = i2b(625);
+ p5->next = 0;
+#endif
+ }
+ for(;;) {
+ if (k & 1) {
+ b1 = mult(b, p5);
+ Bfree(b);
+ b = b1;
+ }
+ if (!(k >>= 1))
+ break;
+ if ((p51 = p5->next) == 0) {
+#ifdef MULTIPLE_THREADS
+ ACQUIRE_DTOA_LOCK(1);
+ if (!(p51 = p5->next)) {
+ p51 = p5->next = mult(p5,p5);
+ p51->next = 0;
+ }
+ FREE_DTOA_LOCK(1);
+#else
+ p51 = p5->next = mult(p5,p5);
+ p51->next = 0;
+#endif
+ }
+ p5 = p51;
+ }
+ return b;
+ }
+
+ Bigint *
+lshift
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint *b, int k)
+#endif
+{
+ int i, k1, n, n1;
+ Bigint *b1;
+ ULong *x, *x1, *xe, z;
+
+ n = k >> kshift;
+ k1 = b->k;
+ n1 = n + b->wds + 1;
+ for(i = b->maxwds; n1 > i; i <<= 1)
+ k1++;
+ b1 = Balloc(k1);
+ x1 = b1->x;
+ for(i = 0; i < n; i++)
+ *x1++ = 0;
+ x = b->x;
+ xe = x + b->wds;
+ if (k &= kmask) {
+#ifdef Pack_32
+ k1 = 32 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if ((*x1 = z) !=0)
+ ++n1;
+#else
+ k1 = 16 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k & 0xffff | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if (*x1 = z)
+ ++n1;
+#endif
+ }
+ else do
+ *x1++ = *x++;
+ while(x < xe);
+ b1->wds = n1 - 1;
+ Bfree(b);
+ return b1;
+ }
+
+ int
+cmp
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ ULong *xa, *xa0, *xb, *xb0;
+ int i, j;
+
+ i = a->wds;
+ j = b->wds;
+#ifdef DEBUG
+ if (i > 1 && !a->x[i-1])
+ Bug("cmp called with a->x[a->wds-1] == 0");
+ if (j > 1 && !b->x[j-1])
+ Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+ if (i -= j)
+ return i;
+ xa0 = a->x;
+ xa = xa0 + j;
+ xb0 = b->x;
+ xb = xb0 + j;
+ for(;;) {
+ if (*--xa != *--xb)
+ return *xa < *xb ? -1 : 1;
+ if (xa <= xa0)
+ break;
+ }
+ return 0;
+ }
+
+ Bigint *
+diff
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ Bigint *c;
+ int i, wa, wb;
+ ULong *xa, *xae, *xb, *xbe, *xc;
+#ifdef ULLong
+ ULLong borrow, y;
+#else
+ ULong borrow, y;
+#ifdef Pack_32
+ ULong z;
+#endif
+#endif
+
+ i = cmp(a,b);
+ if (!i) {
+ c = Balloc(0);
+ c->wds = 1;
+ c->x[0] = 0;
+ return c;
+ }
+ if (i < 0) {
+ c = a;
+ a = b;
+ b = c;
+ i = 1;
+ }
+ else
+ i = 0;
+ c = Balloc(a->k);
+ c->sign = i;
+ wa = a->wds;
+ xa = a->x;
+ xae = xa + wa;
+ wb = b->wds;
+ xb = b->x;
+ xbe = xb + wb;
+ xc = c->x;
+ borrow = 0;
+#ifdef ULLong
+ do {
+ y = (ULLong)*xa++ - *xb++ - borrow;
+ borrow = y >> 32 & 1UL;
+ *xc++ = y & 0xffffffffUL;
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = *xa++ - borrow;
+ borrow = y >> 32 & 1UL;
+ *xc++ = y & 0xffffffffUL;
+ }
+#else
+#ifdef Pack_32
+ do {
+ y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(xc, z, y);
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = (*xa & 0xffff) - borrow;
+ borrow = (y & 0x10000) >> 16;
+ z = (*xa++ >> 16) - borrow;
+ borrow = (z & 0x10000) >> 16;
+ Storeinc(xc, z, y);
+ }
+#else
+ do {
+ y = *xa++ - *xb++ - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *xc++ = y & 0xffff;
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = *xa++ - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *xc++ = y & 0xffff;
+ }
+#endif
+#endif
+ while(!*--xc)
+ wa--;
+ c->wds = wa;
+ return c;
+ }
+
+ double
+b2d
+#ifdef KR_headers
+ (a, e) Bigint *a; int *e;
+#else
+ (Bigint *a, int *e)
+#endif
+{
+ ULong *xa, *xa0, w, y, z;
+ int k;
+ double d;
+#ifdef VAX
+ ULong d0, d1;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+ xa0 = a->x;
+ xa = xa0 + a->wds;
+ y = *--xa;
+#ifdef DEBUG
+ if (!y) Bug("zero y in b2d");
+#endif
+ k = hi0bits(y);
+ *e = 32 - k;
+#ifdef Pack_32
+ if (k < Ebits) {
+ d0 = Exp_1 | y >> Ebits - k;
+ w = xa > xa0 ? *--xa : 0;
+ d1 = y << (32-Ebits) + k | w >> Ebits - k;
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ if (k -= Ebits) {
+ d0 = Exp_1 | y << k | z >> 32 - k;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = z << k | y >> 32 - k;
+ }
+ else {
+ d0 = Exp_1 | y;
+ d1 = z;
+ }
+#else
+ if (k < Ebits + 16) {
+ z = xa > xa0 ? *--xa : 0;
+ d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
+ w = xa > xa0 ? *--xa : 0;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ w = xa > xa0 ? *--xa : 0;
+ k -= Ebits + 16;
+ d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = w << k + 16 | y << k;
+#endif
+ ret_d:
+#ifdef VAX
+ word0(d) = d0 >> 16 | d0 << 16;
+ word1(d) = d1 >> 16 | d1 << 16;
+#endif
+ return dval(d);
+ }
+#undef d0
+#undef d1
+
+ Bigint *
+d2b
+#ifdef KR_headers
+ (d, e, bits) double d; int *e, *bits;
+#else
+ (double d, int *e, int *bits)
+#endif
+{
+ Bigint *b;
+#ifndef Sudden_Underflow
+ int i;
+#endif
+ int de, k;
+ ULong *x, y, z;
+#ifdef VAX
+ ULong d0, d1;
+ d0 = word0(d) >> 16 | word0(d) << 16;
+ d1 = word1(d) >> 16 | word1(d) << 16;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+#ifdef Pack_32
+ b = Balloc(1);
+#else
+ b = Balloc(2);
+#endif
+ x = b->x;
+
+ z = d0 & Frac_mask;
+ d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
+#ifdef Sudden_Underflow
+ de = (int)(d0 >> Exp_shift);
+#ifndef IBM
+ z |= Exp_msk11;
+#endif
+#else
+ if ( (de = (int)(d0 >> Exp_shift)) !=0)
+ z |= Exp_msk1;
+#endif
+#ifdef Pack_32
+ if ( (y = d1) !=0) {
+ if ( (k = lo0bits(&y)) !=0) {
+ x[0] = y | z << 32 - k;
+ z >>= k;
+ }
+ else
+ x[0] = y;
+#ifndef Sudden_Underflow
+ i =
+#endif
+ b->wds = (x[1] = z) !=0 ? 2 : 1;
+ }
+ else {
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ x[0] = z;
+#ifndef Sudden_Underflow
+ i =
+#endif
+ b->wds = 1;
+ k += 32;
+ }
+#else
+ if ( (y = d1) !=0) {
+ if ( (k = lo0bits(&y)) !=0)
+ if (k >= 16) {
+ x[0] = y | z << 32 - k & 0xffff;
+ x[1] = z >> k - 16 & 0xffff;
+ x[2] = z >> k;
+ i = 2;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16 | z << 16 - k & 0xffff;
+ x[2] = z >> k & 0xffff;
+ x[3] = z >> k+16;
+ i = 3;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16;
+ x[2] = z & 0xffff;
+ x[3] = z >> 16;
+ i = 3;
+ }
+ }
+ else {
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ if (k >= 16) {
+ x[0] = z;
+ i = 0;
+ }
+ else {
+ x[0] = z & 0xffff;
+ x[1] = z >> 16;
+ i = 1;
+ }
+ k += 32;
+ }
+ while(!x[i])
+ --i;
+ b->wds = i + 1;
+#endif
+#ifndef Sudden_Underflow
+ if (de) {
+#endif
+#ifdef IBM
+ *e = (de - Bias - (P-1) << 2) + k;
+ *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
+#else
+ *e = de - Bias - (P-1) + k;
+ *bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+ }
+ else {
+ *e = de - Bias - (P-1) + 1 + k;
+#ifdef Pack_32
+ *bits = 32*i - hi0bits(x[i-1]);
+#else
+ *bits = (i+2)*16 - hi0bits(x[i]);
+#endif
+ }
+#endif
+ return b;
+ }
+#undef d0
+#undef d1
+
+ CONST double
+#ifdef IEEE_Arith
+bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256
+ };
+#else
+#ifdef IBM
+bigtens[] = { 1e16, 1e32, 1e64 };
+CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#else
+bigtens[] = { 1e16, 1e32 };
+CONST double tinytens[] = { 1e-16, 1e-32 };
+#endif
+#endif
+
+ CONST double
+tens[] = {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22
+#ifdef VAX
+ , 1e23, 1e24
+#endif
+ };
+
+ char *
+#ifdef KR_headers
+strcp_D2A(a, b) char *a; char *b;
+#else
+strcp_D2A(char *a, CONST char *b)
+#endif
+{
+ while(*a = *b++)
+ a++;
+ return a;
+ }
+
+#ifdef NO_STRING_H
+
+ Char *
+#ifdef KR_headers
+memcpy_D2A(a, b, len) Char *a; Char *b; size_t len;
+#else
+memcpy_D2A(void *a1, void *b1, size_t len)
+#endif
+{
+ register char *a = (char*)a1, *ae = a + len;
+ register char *b = (char*)b1, *a0 = a;
+ while(a < ae)
+ *a++ = *b++;
+ return a0;
+ }
+
+#endif /* NO_STRING_H */
diff --git a/lib/libc/gdtoa/qnan.c b/lib/libc/gdtoa/qnan.c
new file mode 100644
index 00000000000..118e749216a
--- /dev/null
+++ b/lib/libc/gdtoa/qnan.c
@@ -0,0 +1,110 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 2005 by David M. Gay
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that the copyright notice and this permission notice and warranty
+disclaimer appear in supporting documentation, and that the name of
+the author or any of his current or former employers not be used in
+advertising or publicity pertaining to distribution of the software
+without specific, written prior permission.
+
+THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+NO EVENT SHALL THE AUTHOR OR ANY OF HIS CURRENT OR FORMER EMPLOYERS BE
+LIABLE FOR ANY SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+/* Program to compute quiet NaNs of various precisions (float, */
+/* double, and perhaps long double) on the current system, */
+/* provided the system uses binary IEEE (P754) arithmetic. */
+/* Note that one system's quiet NaN may be a signaling NaN on */
+/* another system. The IEEE arithmetic standards (P754, P854) */
+/* do not specify how to distinguish signaling NaNs from quiet */
+/* ones, and this detail varies across systems. The computed */
+/* NaN values are encoded in #defines for values for an */
+/* unsigned 32-bit integer type, called Ulong below, and */
+/* (for long double) perhaps as unsigned short values. Once */
+/* upon a time, there were PC compilers for Intel CPUs that */
+/* had sizeof(long double) = 10. Are such compilers still */
+/* distributed? */
+
+#include <stdio.h>
+#include "arith.h"
+
+#ifndef Long
+#define Long long
+#endif
+
+typedef unsigned Long Ulong;
+
+#undef HAVE_IEEE
+#ifdef IEEE_8087
+#define _0 1
+#define _1 0
+#define HAVE_IEEE
+#endif
+#ifdef IEEE_MC68k
+#define _0 0
+#define _1 1
+#define HAVE_IEEE
+#endif
+
+#define UL (unsigned long)
+
+ int
+main(void)
+{
+#ifdef HAVE_IEEE
+ typedef union {
+ float f;
+ double d;
+ Ulong L[4];
+#ifndef NO_LONG_LONG
+ unsigned short u[5];
+ long double D;
+#endif
+ } U;
+ U a, b, c;
+ int i;
+
+ a.L[0] = b.L[0] = 0x7f800000;
+ c.f = a.f - b.f;
+ printf("#define f_QNAN 0x%lx\n", UL c.L[0]);
+ a.L[_0] = b.L[_0] = 0x7ff00000;
+ a.L[_1] = b.L[_1] = 0;
+ c.d = a.d - b.d; /* quiet NaN */
+ printf("#define d_QNAN0 0x%lx\n", UL c.L[0]);
+ printf("#define d_QNAN1 0x%lx\n", UL c.L[1]);
+#ifdef NO_LONG_LONG
+ for(i = 0; i < 4; i++)
+ printf("#define ld_QNAN%d 0xffffffff\n", i);
+ for(i = 0; i < 5; i++)
+ printf("#define ldus_QNAN%d 0xffff\n", i);
+#else
+ b.D = c.D = a.d;
+ if (printf("") < 0)
+ c.D = 37; /* never executed; just defeat optimization */
+ a.L[2] = a.L[3] = 0;
+ a.D = b.D - c.D;
+ for(i = 0; i < 4; i++)
+ printf("#define ld_QNAN%d 0x%lx\n", i, UL a.L[i]);
+ for(i = 0; i < 5; i++)
+ printf("#define ldus_QNAN%d 0x%x\n", i, a.u[i]);
+#endif
+#endif /* HAVE_IEEE */
+ return 0;
+ }
diff --git a/lib/libc/gdtoa/smisc.c b/lib/libc/gdtoa/smisc.c
new file mode 100644
index 00000000000..163011e0aa2
--- /dev/null
+++ b/lib/libc/gdtoa/smisc.c
@@ -0,0 +1,191 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 1999 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ Bigint *
+s2b
+#ifdef KR_headers
+ (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
+#else
+ (CONST char *s, int nd0, int nd, ULong y9)
+#endif
+{
+ Bigint *b;
+ int i, k;
+ Long x, y;
+
+ x = (nd + 8) / 9;
+ for(k = 0, y = 1; x > y; y <<= 1, k++) ;
+#ifdef Pack_32
+ b = Balloc(k);
+ b->x[0] = y9;
+ b->wds = 1;
+#else
+ b = Balloc(k+1);
+ b->x[0] = y9 & 0xffff;
+ b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
+#endif
+
+ i = 9;
+ if (9 < nd0) {
+ s += 9;
+ do b = multadd(b, 10, *s++ - '0');
+ while(++i < nd0);
+ s++;
+ }
+ else
+ s += 10;
+ for(; i < nd; i++)
+ b = multadd(b, 10, *s++ - '0');
+ return b;
+ }
+
+ double
+ratio
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ double da, db;
+ int k, ka, kb;
+
+ dval(da) = b2d(a, &ka);
+ dval(db) = b2d(b, &kb);
+ k = ka - kb + ULbits*(a->wds - b->wds);
+#ifdef IBM
+ if (k > 0) {
+ word0(da) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ dval(da) *= 1 << k;
+ }
+ else {
+ k = -k;
+ word0(db) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ dval(db) *= 1 << k;
+ }
+#else
+ if (k > 0)
+ word0(da) += k*Exp_msk1;
+ else {
+ k = -k;
+ word0(db) += k*Exp_msk1;
+ }
+#endif
+ return dval(da) / dval(db);
+ }
+
+#ifdef INFNAN_CHECK
+
+ int
+match
+#ifdef KR_headers
+ (sp, t) char **sp, *t;
+#else
+ (CONST char **sp, char *t)
+#endif
+{
+ int c, d;
+ CONST char *s = *sp;
+
+ while( (d = *t++) !=0) {
+ if ((c = *++s) >= 'A' && c <= 'Z')
+ c += 'a' - 'A';
+ if (c != d)
+ return 0;
+ }
+ *sp = s + 1;
+ return 1;
+ }
+#endif /* INFNAN_CHECK */
+
+ void
+#ifdef KR_headers
+copybits(c, n, b) ULong *c; int n; Bigint *b;
+#else
+copybits(ULong *c, int n, Bigint *b)
+#endif
+{
+ ULong *ce, *x, *xe;
+#ifdef Pack_16
+ int nw, nw1;
+#endif
+
+ ce = c + ((n-1) >> kshift) + 1;
+ x = b->x;
+#ifdef Pack_32
+ xe = x + b->wds;
+ while(x < xe)
+ *c++ = *x++;
+#else
+ nw = b->wds;
+ nw1 = nw & 1;
+ for(xe = x + (nw - nw1); x < xe; x += 2)
+ Storeinc(c, x[1], x[0]);
+ if (nw1)
+ *c++ = *x;
+#endif
+ while(c < ce)
+ *c++ = 0;
+ }
+
+ ULong
+#ifdef KR_headers
+any_on(b, k) Bigint *b; int k;
+#else
+any_on(Bigint *b, int k)
+#endif
+{
+ int n, nwds;
+ ULong *x, *x0, x1, x2;
+
+ x = b->x;
+ nwds = b->wds;
+ n = k >> kshift;
+ if (n > nwds)
+ n = nwds;
+ else if (n < nwds && (k &= kmask)) {
+ x1 = x2 = x[n];
+ x1 >>= k;
+ x1 <<= k;
+ if (x1 != x2)
+ return 1;
+ }
+ x0 = x;
+ x += n;
+ while(x > x0)
+ if (*--x)
+ return 1;
+ return 0;
+ }
diff --git a/lib/libc/gdtoa/strtoIQ.c b/lib/libc/gdtoa/strtoIQ.c
new file mode 100644
index 00000000000..9ce5120e6b7
--- /dev/null
+++ b/lib/libc/gdtoa/strtoIQ.c
@@ -0,0 +1,63 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ int
+#ifdef KR_headers
+strtoIQ(s, sp, a, b) CONST char *s; char **sp; void *a; void *b;
+#else
+strtoIQ(CONST char *s, char **sp, void *a, void *b)
+#endif
+{
+ static FPI fpi = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI };
+ Long exp[2];
+ Bigint *B[2];
+ int k, rv[2];
+ ULong *L = (ULong *)a, *M = (ULong *)b;
+
+ B[0] = Balloc(2);
+ B[0]->wds = 4;
+ k = strtoIg(s, sp, &fpi, exp, B, rv);
+ ULtoQ(L, B[0]->x, exp[0], rv[0]);
+ Bfree(B[0]);
+ if (B[1]) {
+ ULtoQ(M, B[1]->x, exp[1], rv[1]);
+ Bfree(B[1]);
+ }
+ else {
+ M[0] = L[0];
+ M[1] = L[1];
+ M[2] = L[2];
+ M[3] = L[3];
+ }
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtoId.c b/lib/libc/gdtoa/strtoId.c
new file mode 100644
index 00000000000..1c97d382dea
--- /dev/null
+++ b/lib/libc/gdtoa/strtoId.c
@@ -0,0 +1,60 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ int
+#ifdef KR_headers
+strtoId(s, sp, f0, f1) CONST char *s; char **sp; double *f0, *f1;
+#else
+strtoId(CONST char *s, char **sp, double *f0, double *f1)
+#endif
+{
+ static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
+ Long exp[2];
+ Bigint *B[2];
+ int k, rv[2];
+
+ B[0] = Balloc(1);
+ B[0]->wds = 2;
+ k = strtoIg(s, sp, &fpi, exp, B, rv);
+ ULtod((ULong*)f0, B[0]->x, exp[0], rv[0]);
+ Bfree(B[0]);
+ if (B[1]) {
+ ULtod((ULong*)f1, B[1]->x, exp[1], rv[1]);
+ Bfree(B[1]);
+ }
+ else {
+ ((ULong*)f1)[0] = ((ULong*)f0)[0];
+ ((ULong*)f1)[1] = ((ULong*)f0)[1];
+ }
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtoIdd.c b/lib/libc/gdtoa/strtoIdd.c
new file mode 100644
index 00000000000..40b7936bc00
--- /dev/null
+++ b/lib/libc/gdtoa/strtoIdd.c
@@ -0,0 +1,66 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ int
+#ifdef KR_headers
+strtoIdd(s, sp, f0, f1) CONST char *s; char **sp; double *f0, *f1;
+#else
+strtoIdd(CONST char *s, char **sp, double *f0, double *f1)
+#endif
+{
+#ifdef Sudden_Underflow
+ static FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 };
+#else
+ static FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 };
+#endif
+ Long exp[2];
+ Bigint *B[2];
+ int k, rv[2];
+
+ B[0] = Balloc(2);
+ B[0]->wds = 4;
+ k = strtoIg(s, sp, &fpi, exp, B, rv);
+ ULtodd((ULong*)f0, B[0]->x, exp[0], rv[0]);
+ Bfree(B[0]);
+ if (B[1]) {
+ ULtodd((ULong*)f1, B[1]->x, exp[1], rv[1]);
+ Bfree(B[1]);
+ }
+ else {
+ ((ULong*)f1)[0] = ((ULong*)f0)[0];
+ ((ULong*)f1)[1] = ((ULong*)f0)[1];
+ ((ULong*)f1)[2] = ((ULong*)f0)[2];
+ ((ULong*)f1)[3] = ((ULong*)f0)[3];
+ }
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtoIf.c b/lib/libc/gdtoa/strtoIf.c
new file mode 100644
index 00000000000..65ecab2e0b8
--- /dev/null
+++ b/lib/libc/gdtoa/strtoIf.c
@@ -0,0 +1,58 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ int
+#ifdef KR_headers
+strtoIf(s, sp, f0, f1) CONST char *s; char **sp; float *f0, *f1;
+#else
+strtoIf(CONST char *s, char **sp, float *f0, float *f1)
+#endif
+{
+ static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI };
+ Long exp[2];
+ Bigint *B[2];
+ int k, rv[2];
+
+ B[0] = Balloc(0);
+ B[0]->wds = 1;
+ k = strtoIg(s, sp, &fpi, exp, B, rv);
+ ULtof((ULong*)f0, B[0]->x, exp[0], rv[0]);
+ Bfree(B[0]);
+ if (B[1]) {
+ ULtof((ULong*)f1, B[1]->x, exp[1], rv[1]);
+ Bfree(B[1]);
+ }
+ else
+ *(ULong*)f1 = *(ULong*)f0;
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtoIg.c b/lib/libc/gdtoa/strtoIg.c
new file mode 100644
index 00000000000..ec46a3ebb75
--- /dev/null
+++ b/lib/libc/gdtoa/strtoIg.c
@@ -0,0 +1,133 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ int
+#ifdef KR_headers
+strtoIg(s00, se, fpi, exp, B, rvp) CONST char *s00; char **se; FPI *fpi; Long *exp; Bigint **B; int *rvp;
+#else
+strtoIg(CONST char *s00, char **se, FPI *fpi, Long *exp, Bigint **B, int *rvp)
+#endif
+{
+ Bigint *b, *b1;
+ int i, nb, nw, nw1, rv, rv1, swap;
+ unsigned int nb1, nb11;
+ Long e1;
+
+ b = *B;
+ rv = strtodg(s00, se, fpi, exp, b->x);
+ if (!(rv & STRTOG_Inexact)) {
+ B[1] = 0;
+ return *rvp = rv;
+ }
+ e1 = exp[0];
+ rv1 = rv ^ STRTOG_Inexact;
+ b1 = Balloc(b->k);
+ Bcopy(b1, b);
+ nb = fpi->nbits;
+ nb1 = nb & 31;
+ nb11 = (nb1 - 1) & 31;
+ nw = b->wds;
+ nw1 = nw - 1;
+ if (rv & STRTOG_Inexlo) {
+ swap = 0;
+ b1 = increment(b1);
+ if (fpi->sudden_underflow
+ && (rv & STRTOG_Retmask) == STRTOG_Zero) {
+ b1->x[0] = 0;
+ b1->x[nw1] = 1L << nb11;
+ rv1 += STRTOG_Normal - STRTOG_Zero;
+ rv1 &= ~STRTOG_Underflow;
+ goto swapcheck;
+ }
+ if (b1->wds > nw
+ || nb1 && b1->x[nw1] & 1L << nb1) {
+ if (++e1 > fpi->emax)
+ rv1 = STRTOG_Infinite | STRTOG_Inexhi;
+ rshift(b1, 1);
+ }
+ else if ((rv & STRTOG_Retmask) == STRTOG_Denormal) {
+ if (b1->x[nw1] & 1L << nb11) {
+ rv1 += STRTOG_Normal - STRTOG_Denormal;
+ rv1 &= ~STRTOG_Underflow;
+ }
+ }
+ }
+ else {
+ swap = STRTOG_Neg;
+ if ((rv & STRTOG_Retmask) == STRTOG_Infinite) {
+ b1 = set_ones(b1, nb);
+ e1 = fpi->emax;
+ rv1 = STRTOG_Normal | STRTOG_Inexlo;
+ goto swapcheck;
+ }
+ decrement(b1);
+ if ((rv & STRTOG_Retmask) == STRTOG_Denormal) {
+ for(i = nw1; !b1->x[i]; --i)
+ if (!i) {
+ rv1 = STRTOG_Zero | STRTOG_Inexlo;
+ break;
+ }
+ goto swapcheck;
+ }
+ if (!(b1->x[nw1] & 1L << nb11)) {
+ if (e1 == fpi->emin) {
+ if (fpi->sudden_underflow)
+ rv1 += STRTOG_Zero - STRTOG_Normal;
+ else
+ rv1 += STRTOG_Denormal - STRTOG_Normal;
+ rv1 |= STRTOG_Underflow;
+ }
+ else {
+ b1 = lshift(b1, 1);
+ b1->x[0] |= 1;
+ --e1;
+ }
+ }
+ }
+ swapcheck:
+ if (swap ^ (rv & STRTOG_Neg)) {
+ rvp[0] = rv1;
+ rvp[1] = rv;
+ B[0] = b1;
+ B[1] = b;
+ exp[1] = exp[0];
+ exp[0] = e1;
+ }
+ else {
+ rvp[0] = rv;
+ rvp[1] = rv1;
+ B[1] = b1;
+ exp[1] = e1;
+ }
+ return rv;
+ }
diff --git a/lib/libc/gdtoa/strtoIx.c b/lib/libc/gdtoa/strtoIx.c
new file mode 100644
index 00000000000..783a631f066
--- /dev/null
+++ b/lib/libc/gdtoa/strtoIx.c
@@ -0,0 +1,64 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ int
+#ifdef KR_headers
+strtoIx(s, sp, a, b) CONST char *s; char **sp; void *a; void *b;
+#else
+strtoIx(CONST char *s, char **sp, void *a, void *b)
+#endif
+{
+ static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
+ Long exp[2];
+ Bigint *B[2];
+ int k, rv[2];
+ UShort *L = (UShort *)a, *M = (UShort *)b;
+
+ B[0] = Balloc(1);
+ B[0]->wds = 2;
+ k = strtoIg(s, sp, &fpi, exp, B, rv);
+ ULtox(L, B[0]->x, exp[0], rv[0]);
+ Bfree(B[0]);
+ if (B[1]) {
+ ULtox(M, B[1]->x, exp[1], rv[1]);
+ Bfree(B[1]);
+ }
+ else {
+ M[0] = L[0];
+ M[1] = L[1];
+ M[2] = L[2];
+ M[3] = L[3];
+ M[4] = L[4];
+ }
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtoIxL.c b/lib/libc/gdtoa/strtoIxL.c
new file mode 100644
index 00000000000..869bfd16fb8
--- /dev/null
+++ b/lib/libc/gdtoa/strtoIxL.c
@@ -0,0 +1,62 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ int
+#ifdef KR_headers
+strtoIxL(s, sp, a, b) CONST char *s; char **sp; void *a; void *b;
+#else
+strtoIxL(CONST char *s, char **sp, void *a, void *b)
+#endif
+{
+ static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
+ Long exp[2];
+ Bigint *B[2];
+ int k, rv[2];
+ ULong *L = (ULong *)a, *M = (ULong *)b;
+
+ B[0] = Balloc(1);
+ B[0]->wds = 2;
+ k = strtoIg(s, sp, &fpi, exp, B, rv);
+ ULtoxL(L, B[0]->x, exp[0], rv[0]);
+ Bfree(B[0]);
+ if (B[1]) {
+ ULtoxL(M, B[1]->x, exp[1], rv[1]);
+ Bfree(B[1]);
+ }
+ else {
+ M[0] = L[0];
+ M[1] = L[1];
+ M[2] = L[2];
+ }
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtod.c b/lib/libc/gdtoa/strtod.c
new file mode 100644
index 00000000000..66a3baa2bc3
--- /dev/null
+++ b/lib/libc/gdtoa/strtod.c
@@ -0,0 +1,982 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998-2001 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+#ifndef NO_FENV_H
+#include <fenv.h>
+#endif
+
+#ifdef USE_LOCALE
+#include "locale.h"
+#endif
+
+#ifdef IEEE_Arith
+#ifndef NO_IEEE_Scale
+#define Avoid_Underflow
+#undef tinytens
+/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
+/* flag unnecessarily. It leads to a song and dance at the end of strtod. */
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
+ 9007199254740992.e-256
+ };
+#endif
+#endif
+
+#ifdef Honor_FLT_ROUNDS
+#define Rounding rounding
+#undef Check_FLT_ROUNDS
+#define Check_FLT_ROUNDS
+#else
+#define Rounding Flt_Rounds
+#endif
+
+ double
+strtod
+#ifdef KR_headers
+ (s00, se) CONST char *s00; char **se;
+#else
+ (CONST char *s00, char **se)
+#endif
+{
+#ifdef Avoid_Underflow
+ int scale;
+#endif
+ int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign,
+ e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
+ CONST char *s, *s0, *s1;
+ double aadj, aadj1, adj, rv, rv0;
+ Long L;
+ ULong y, z;
+ Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
+#ifdef SET_INEXACT
+ int inexact, oldinexact;
+#endif
+#ifdef Honor_FLT_ROUNDS
+ int rounding;
+#endif
+
+ sign = nz0 = nz = decpt = 0;
+ dval(rv) = 0.;
+ for(s = s00;;s++) switch(*s) {
+ case '-':
+ sign = 1;
+ /* no break */
+ case '+':
+ if (*++s)
+ goto break2;
+ /* no break */
+ case 0:
+ goto ret0;
+ case '\t':
+ case '\n':
+ case '\v':
+ case '\f':
+ case '\r':
+ case ' ':
+ continue;
+ default:
+ goto break2;
+ }
+ break2:
+ if (*s == '0') {
+#ifndef NO_HEX_FP
+ {
+ static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
+ Long exp;
+ ULong bits[2];
+ switch(s[1]) {
+ case 'x':
+ case 'X':
+ {
+#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD)
+ FPI fpi1 = fpi;
+ switch(fegetround()) {
+ case FE_TOWARDZERO: fpi1.rounding = 0; break;
+ case FE_UPWARD: fpi1.rounding = 2; break;
+ case FE_DOWNWARD: fpi1.rounding = 3;
+ }
+#else
+#define fpi1 fpi
+#endif
+ switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ s = s00;
+ sign = 0;
+ case STRTOG_Zero:
+ break;
+ default:
+ if (bb) {
+ copybits(bits, fpi.nbits, bb);
+ Bfree(bb);
+ }
+ ULtod(((U*)&rv)->L, bits, exp, i);
+ }}
+ goto ret;
+ }
+ }
+#endif
+ nz0 = 1;
+ while(*++s == '0') ;
+ if (!*s)
+ goto ret;
+ }
+ s0 = s;
+ y = z = 0;
+ for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ if (nd < 9)
+ y = 10*y + c - '0';
+ else if (nd < 16)
+ z = 10*z + c - '0';
+ nd0 = nd;
+#ifdef USE_LOCALE
+ if (c == *localeconv()->decimal_point)
+#else
+ if (c == '.')
+#endif
+ {
+ decpt = 1;
+ c = *++s;
+ if (!nd) {
+ for(; c == '0'; c = *++s)
+ nz++;
+ if (c > '0' && c <= '9') {
+ s0 = s;
+ nf += nz;
+ nz = 0;
+ goto have_dig;
+ }
+ goto dig_done;
+ }
+ for(; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+ nz++;
+ if (c -= '0') {
+ nf += nz;
+ for(i = 1; i < nz; i++)
+ if (nd++ < 9)
+ y *= 10;
+ else if (nd <= DBL_DIG + 1)
+ z *= 10;
+ if (nd++ < 9)
+ y = 10*y + c;
+ else if (nd <= DBL_DIG + 1)
+ z = 10*z + c;
+ nz = 0;
+ }
+ }
+ }
+ dig_done:
+ e = 0;
+ if (c == 'e' || c == 'E') {
+ if (!nd && !nz && !nz0) {
+ goto ret0;
+ }
+ s00 = s;
+ esign = 0;
+ switch(c = *++s) {
+ case '-':
+ esign = 1;
+ case '+':
+ c = *++s;
+ }
+ if (c >= '0' && c <= '9') {
+ while(c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9') {
+ L = c - '0';
+ s1 = s;
+ while((c = *++s) >= '0' && c <= '9')
+ L = 10*L + c - '0';
+ if (s - s1 > 8 || L > 19999)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ e = 19999; /* safe for 16 bit ints */
+ else
+ e = (int)L;
+ if (esign)
+ e = -e;
+ }
+ else
+ e = 0;
+ }
+ else
+ s = s00;
+ }
+ if (!nd) {
+ if (!nz && !nz0) {
+#ifdef INFNAN_CHECK
+ /* Check for Nan and Infinity */
+ ULong bits[2];
+ static FPI fpinan = /* only 52 explicit bits */
+ { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI };
+ if (!decpt)
+ switch(c) {
+ case 'i':
+ case 'I':
+ if (match(&s,"nf")) {
+ --s;
+ if (!match(&s,"inity"))
+ ++s;
+ word0(rv) = 0x7ff00000;
+ word1(rv) = 0;
+ goto ret;
+ }
+ break;
+ case 'n':
+ case 'N':
+ if (match(&s, "an")) {
+#ifndef No_Hex_NaN
+ if (*s == '(' /*)*/
+ && hexnan(&s, &fpinan, bits)
+ == STRTOG_NaNbits) {
+ word0(rv) = 0x7ff00000 | bits[1];
+ word1(rv) = bits[0];
+ }
+ else {
+#endif
+ word0(rv) = NAN_WORD0;
+ word1(rv) = NAN_WORD1;
+#ifndef No_Hex_NaN
+ }
+#endif
+ goto ret;
+ }
+ }
+#endif /* INFNAN_CHECK */
+ ret0:
+ s = s00;
+ sign = 0;
+ }
+ goto ret;
+ }
+ e1 = e -= nf;
+
+ /* Now we have nd0 digits, starting at s0, followed by a
+ * decimal point, followed by nd-nd0 digits. The number we're
+ * after is the integer represented by those digits times
+ * 10**e */
+
+ if (!nd0)
+ nd0 = nd;
+ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+ dval(rv) = y;
+ if (k > 9) {
+#ifdef SET_INEXACT
+ if (k > DBL_DIG)
+ oldinexact = get_inexact();
+#endif
+ dval(rv) = tens[k - 9] * dval(rv) + z;
+ }
+ bd0 = 0;
+ if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+#ifndef Honor_FLT_ROUNDS
+ && Flt_Rounds == 1
+#endif
+#endif
+ ) {
+ if (!e)
+ goto ret;
+ if (e > 0) {
+ if (e <= Ten_pmax) {
+#ifdef VAX
+ goto vax_ovfl_check;
+#else
+#ifdef Honor_FLT_ROUNDS
+ /* round correctly FLT_ROUNDS = 2 or 3 */
+ if (sign) {
+ rv = -rv;
+ sign = 0;
+ }
+#endif
+ /* rv = */ rounded_product(dval(rv), tens[e]);
+ goto ret;
+#endif
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i) {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+#ifdef Honor_FLT_ROUNDS
+ /* round correctly FLT_ROUNDS = 2 or 3 */
+ if (sign) {
+ rv = -rv;
+ sign = 0;
+ }
+#endif
+ e -= i;
+ dval(rv) *= tens[i];
+#ifdef VAX
+ /* VAX exponent range is so narrow we must
+ * worry about overflow here...
+ */
+ vax_ovfl_check:
+ word0(rv) -= P*Exp_msk1;
+ /* rv = */ rounded_product(dval(rv), tens[e]);
+ if ((word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+ goto ovfl;
+ word0(rv) += P*Exp_msk1;
+#else
+ /* rv = */ rounded_product(dval(rv), tens[e]);
+#endif
+ goto ret;
+ }
+ }
+#ifndef Inaccurate_Divide
+ else if (e >= -Ten_pmax) {
+#ifdef Honor_FLT_ROUNDS
+ /* round correctly FLT_ROUNDS = 2 or 3 */
+ if (sign) {
+ rv = -rv;
+ sign = 0;
+ }
+#endif
+ /* rv = */ rounded_quotient(dval(rv), tens[-e]);
+ goto ret;
+ }
+#endif
+ }
+ e1 += nd - k;
+
+#ifdef IEEE_Arith
+#ifdef SET_INEXACT
+ inexact = 1;
+ if (k <= DBL_DIG)
+ oldinexact = get_inexact();
+#endif
+#ifdef Avoid_Underflow
+ scale = 0;
+#endif
+#ifdef Honor_FLT_ROUNDS
+ if ((rounding = Flt_Rounds) >= 2) {
+ if (sign)
+ rounding = rounding == 2 ? 0 : 2;
+ else
+ if (rounding != 2)
+ rounding = 0;
+ }
+#endif
+#endif /*IEEE_Arith*/
+
+ /* Get starting approximation = rv * 10**e1 */
+
+ if (e1 > 0) {
+ if ( (i = e1 & 15) !=0)
+ dval(rv) *= tens[i];
+ if (e1 &= ~15) {
+ if (e1 > DBL_MAX_10_EXP) {
+ ovfl:
+#ifndef NO_ERRNO
+ errno = ERANGE;
+#endif
+ /* Can't trust HUGE_VAL */
+#ifdef IEEE_Arith
+#ifdef Honor_FLT_ROUNDS
+ switch(rounding) {
+ case 0: /* toward 0 */
+ case 3: /* toward -infinity */
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ break;
+ default:
+ word0(rv) = Exp_mask;
+ word1(rv) = 0;
+ }
+#else /*Honor_FLT_ROUNDS*/
+ word0(rv) = Exp_mask;
+ word1(rv) = 0;
+#endif /*Honor_FLT_ROUNDS*/
+#ifdef SET_INEXACT
+ /* set overflow bit */
+ dval(rv0) = 1e300;
+ dval(rv0) *= dval(rv0);
+#endif
+#else /*IEEE_Arith*/
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+#endif /*IEEE_Arith*/
+ if (bd0)
+ goto retfree;
+ goto ret;
+ }
+ e1 >>= 4;
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ dval(rv) *= bigtens[j];
+ /* The last multiplication could overflow. */
+ word0(rv) -= P*Exp_msk1;
+ dval(rv) *= bigtens[j];
+ if ((z = word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+ goto ovfl;
+ if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+ /* set to largest number */
+ /* (Can't trust DBL_MAX) */
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ }
+ else
+ word0(rv) += P*Exp_msk1;
+ }
+ }
+ else if (e1 < 0) {
+ e1 = -e1;
+ if ( (i = e1 & 15) !=0)
+ dval(rv) /= tens[i];
+ if (e1 >>= 4) {
+ if (e1 >= 1 << n_bigtens)
+ goto undfl;
+#ifdef Avoid_Underflow
+ if (e1 & Scale_Bit)
+ scale = 2*P;
+ for(j = 0; e1 > 0; j++, e1 >>= 1)
+ if (e1 & 1)
+ dval(rv) *= tinytens[j];
+ if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask)
+ >> Exp_shift)) > 0) {
+ /* scaled rv is denormal; zap j low bits */
+ if (j >= 32) {
+ word1(rv) = 0;
+ if (j >= 53)
+ word0(rv) = (P+2)*Exp_msk1;
+ else
+ word0(rv) &= 0xffffffff << j-32;
+ }
+ else
+ word1(rv) &= 0xffffffff << j;
+ }
+#else
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ dval(rv) *= tinytens[j];
+ /* The last multiplication could underflow. */
+ dval(rv0) = dval(rv);
+ dval(rv) *= tinytens[j];
+ if (!dval(rv)) {
+ dval(rv) = 2.*dval(rv0);
+ dval(rv) *= tinytens[j];
+#endif
+ if (!dval(rv)) {
+ undfl:
+ dval(rv) = 0.;
+#ifndef NO_ERRNO
+ errno = ERANGE;
+#endif
+ if (bd0)
+ goto retfree;
+ goto ret;
+ }
+#ifndef Avoid_Underflow
+ word0(rv) = Tiny0;
+ word1(rv) = Tiny1;
+ /* The refinement below will clean
+ * this approximation up.
+ */
+ }
+#endif
+ }
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bd0 = s2b(s0, nd0, nd, y);
+
+ for(;;) {
+ bd = Balloc(bd0->k);
+ Bcopy(bd, bd0);
+ bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
+ bs = i2b(1);
+
+ if (e >= 0) {
+ bb2 = bb5 = 0;
+ bd2 = bd5 = e;
+ }
+ else {
+ bb2 = bb5 = -e;
+ bd2 = bd5 = 0;
+ }
+ if (bbe >= 0)
+ bb2 += bbe;
+ else
+ bd2 -= bbe;
+ bs2 = bb2;
+#ifdef Honor_FLT_ROUNDS
+ if (rounding != 1)
+ bs2++;
+#endif
+#ifdef Avoid_Underflow
+ j = bbe - scale;
+ i = j + bbbits - 1; /* logb(rv) */
+ if (i < Emin) /* denormal */
+ j += P - Emin;
+ else
+ j = P + 1 - bbbits;
+#else /*Avoid_Underflow*/
+#ifdef Sudden_Underflow
+#ifdef IBM
+ j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
+#else
+ j = P + 1 - bbbits;
+#endif
+#else /*Sudden_Underflow*/
+ j = bbe;
+ i = j + bbbits - 1; /* logb(rv) */
+ if (i < Emin) /* denormal */
+ j += P - Emin;
+ else
+ j = P + 1 - bbbits;
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+ bb2 += j;
+ bd2 += j;
+#ifdef Avoid_Underflow
+ bd2 += scale;
+#endif
+ i = bb2 < bd2 ? bb2 : bd2;
+ if (i > bs2)
+ i = bs2;
+ if (i > 0) {
+ bb2 -= i;
+ bd2 -= i;
+ bs2 -= i;
+ }
+ if (bb5 > 0) {
+ bs = pow5mult(bs, bb5);
+ bb1 = mult(bs, bb);
+ Bfree(bb);
+ bb = bb1;
+ }
+ if (bb2 > 0)
+ bb = lshift(bb, bb2);
+ if (bd5 > 0)
+ bd = pow5mult(bd, bd5);
+ if (bd2 > 0)
+ bd = lshift(bd, bd2);
+ if (bs2 > 0)
+ bs = lshift(bs, bs2);
+ delta = diff(bb, bd);
+ dsign = delta->sign;
+ delta->sign = 0;
+ i = cmp(delta, bs);
+#ifdef Honor_FLT_ROUNDS
+ if (rounding != 1) {
+ if (i < 0) {
+ /* Error is less than an ulp */
+ if (!delta->x[0] && delta->wds <= 1) {
+ /* exact */
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ break;
+ }
+ if (rounding) {
+ if (dsign) {
+ adj = 1.;
+ goto apply_adj;
+ }
+ }
+ else if (!dsign) {
+ adj = -1.;
+ if (!word1(rv)
+ && !(word0(rv) & Frac_mask)) {
+ y = word0(rv) & Exp_mask;
+#ifdef Avoid_Underflow
+ if (!scale || y > 2*P*Exp_msk1)
+#else
+ if (y)
+#endif
+ {
+ delta = lshift(delta,Log2P);
+ if (cmp(delta, bs) <= 0)
+ adj = -0.5;
+ }
+ }
+ apply_adj:
+#ifdef Avoid_Underflow
+ if (scale && (y = word0(rv) & Exp_mask)
+ <= 2*P*Exp_msk1)
+ word0(adj) += (2*P+1)*Exp_msk1 - y;
+#else
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <=
+ P*Exp_msk1) {
+ word0(rv) += P*Exp_msk1;
+ dval(rv) += adj*ulp(dval(rv));
+ word0(rv) -= P*Exp_msk1;
+ }
+ else
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+ dval(rv) += adj*ulp(dval(rv));
+ }
+ break;
+ }
+ adj = ratio(delta, bs);
+ if (adj < 1.)
+ adj = 1.;
+ if (adj <= 0x7ffffffe) {
+ /* adj = rounding ? ceil(adj) : floor(adj); */
+ y = adj;
+ if (y != adj) {
+ if (!((rounding>>1) ^ dsign))
+ y++;
+ adj = y;
+ }
+ }
+#ifdef Avoid_Underflow
+ if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
+ word0(adj) += (2*P+1)*Exp_msk1 - y;
+#else
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+ word0(rv) += P*Exp_msk1;
+ adj *= ulp(dval(rv));
+ if (dsign)
+ dval(rv) += adj;
+ else
+ dval(rv) -= adj;
+ word0(rv) -= P*Exp_msk1;
+ goto cont;
+ }
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+ adj *= ulp(dval(rv));
+ if (dsign)
+ dval(rv) += adj;
+ else
+ dval(rv) -= adj;
+ goto cont;
+ }
+#endif /*Honor_FLT_ROUNDS*/
+
+ if (i < 0) {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask
+#ifdef IEEE_Arith
+#ifdef Avoid_Underflow
+ || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1
+#else
+ || (word0(rv) & Exp_mask) <= Exp_msk1
+#endif
+#endif
+ ) {
+#ifdef SET_INEXACT
+ if (!delta->x[0] && delta->wds <= 1)
+ inexact = 0;
+#endif
+ break;
+ }
+ if (!delta->x[0] && delta->wds <= 1) {
+ /* exact result */
+#ifdef SET_INEXACT
+ inexact = 0;
+#endif
+ break;
+ }
+ delta = lshift(delta,Log2P);
+ if (cmp(delta, bs) > 0)
+ goto drop_down;
+ break;
+ }
+ if (i == 0) {
+ /* exactly half-way between */
+ if (dsign) {
+ if ((word0(rv) & Bndry_mask1) == Bndry_mask1
+ && word1(rv) == (
+#ifdef Avoid_Underflow
+ (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
+ ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
+#endif
+ 0xffffffff)) {
+ /*boundary case -- increment exponent*/
+ word0(rv) = (word0(rv) & Exp_mask)
+ + Exp_msk1
+#ifdef IBM
+ | Exp_msk1 >> 4
+#endif
+ ;
+ word1(rv) = 0;
+#ifdef Avoid_Underflow
+ dsign = 0;
+#endif
+ break;
+ }
+ }
+ else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
+ drop_down:
+ /* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow /*{{*/
+ L = word0(rv) & Exp_mask;
+#ifdef IBM
+ if (L < Exp_msk1)
+#else
+#ifdef Avoid_Underflow
+ if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
+#else
+ if (L <= Exp_msk1)
+#endif /*Avoid_Underflow*/
+#endif /*IBM*/
+ goto undfl;
+ L -= Exp_msk1;
+#else /*Sudden_Underflow}{*/
+#ifdef Avoid_Underflow
+ if (scale) {
+ L = word0(rv) & Exp_mask;
+ if (L <= (2*P+1)*Exp_msk1) {
+ if (L > (P+2)*Exp_msk1)
+ /* round even ==> */
+ /* accept rv */
+ break;
+ /* rv = smallest denormal */
+ goto undfl;
+ }
+ }
+#endif /*Avoid_Underflow*/
+ L = (word0(rv) & Exp_mask) - Exp_msk1;
+#endif /*Sudden_Underflow}*/
+ word0(rv) = L | Bndry_mask1;
+ word1(rv) = 0xffffffff;
+#ifdef IBM
+ goto cont;
+#else
+ break;
+#endif
+ }
+#ifndef ROUND_BIASED
+ if (!(word1(rv) & LSB))
+ break;
+#endif
+ if (dsign)
+ dval(rv) += ulp(dval(rv));
+#ifndef ROUND_BIASED
+ else {
+ dval(rv) -= ulp(dval(rv));
+#ifndef Sudden_Underflow
+ if (!dval(rv))
+ goto undfl;
+#endif
+ }
+#ifdef Avoid_Underflow
+ dsign = 1 - dsign;
+#endif
+#endif
+ break;
+ }
+ if ((aadj = ratio(delta, bs)) <= 2.) {
+ if (dsign)
+ aadj = aadj1 = 1.;
+ else if (word1(rv) || word0(rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+ if (word1(rv) == Tiny1 && !word0(rv))
+ goto undfl;
+#endif
+ aadj = 1.;
+ aadj1 = -1.;
+ }
+ else {
+ /* special case -- power of FLT_RADIX to be */
+ /* rounded down... */
+
+ if (aadj < 2./FLT_RADIX)
+ aadj = 1./FLT_RADIX;
+ else
+ aadj *= 0.5;
+ aadj1 = -aadj;
+ }
+ }
+ else {
+ aadj *= 0.5;
+ aadj1 = dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+ switch(Rounding) {
+ case 2: /* towards +infinity */
+ aadj1 -= 0.5;
+ break;
+ case 0: /* towards 0 */
+ case 3: /* towards -infinity */
+ aadj1 += 0.5;
+ }
+#else
+ if (Flt_Rounds == 0)
+ aadj1 += 0.5;
+#endif /*Check_FLT_ROUNDS*/
+ }
+ y = word0(rv) & Exp_mask;
+
+ /* Check for overflow */
+
+ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+ dval(rv0) = dval(rv);
+ word0(rv) -= P*Exp_msk1;
+ adj = aadj1 * ulp(dval(rv));
+ dval(rv) += adj;
+ if ((word0(rv) & Exp_mask) >=
+ Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+ if (word0(rv0) == Big0 && word1(rv0) == Big1)
+ goto ovfl;
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ goto cont;
+ }
+ else
+ word0(rv) += P*Exp_msk1;
+ }
+ else {
+#ifdef Avoid_Underflow
+ if (scale && y <= 2*P*Exp_msk1) {
+ if (aadj <= 0x7fffffff) {
+ if ((z = aadj) <= 0)
+ z = 1;
+ aadj = z;
+ aadj1 = dsign ? aadj : -aadj;
+ }
+ word0(aadj1) += (2*P+1)*Exp_msk1 - y;
+ }
+ adj = aadj1 * ulp(dval(rv));
+ dval(rv) += adj;
+#else
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+ dval(rv0) = dval(rv);
+ word0(rv) += P*Exp_msk1;
+ adj = aadj1 * ulp(dval(rv));
+ dval(rv) += adj;
+#ifdef IBM
+ if ((word0(rv) & Exp_mask) < P*Exp_msk1)
+#else
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
+#endif
+ {
+ if (word0(rv0) == Tiny0
+ && word1(rv0) == Tiny1)
+ goto undfl;
+ word0(rv) = Tiny0;
+ word1(rv) = Tiny1;
+ goto cont;
+ }
+ else
+ word0(rv) -= P*Exp_msk1;
+ }
+ else {
+ adj = aadj1 * ulp(dval(rv));
+ dval(rv) += adj;
+ }
+#else /*Sudden_Underflow*/
+ /* Compute adj so that the IEEE rounding rules will
+ * correctly round rv + adj in some half-way cases.
+ * If rv * ulp(rv) is denormalized (i.e.,
+ * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+ * trouble from bits lost to denormalization;
+ * example: 1.2e-307 .
+ */
+ if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
+ aadj1 = (double)(int)(aadj + 0.5);
+ if (!dsign)
+ aadj1 = -aadj1;
+ }
+ adj = aadj1 * ulp(dval(rv));
+ dval(rv) += adj;
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+ }
+ z = word0(rv) & Exp_mask;
+#ifndef SET_INEXACT
+#ifdef Avoid_Underflow
+ if (!scale)
+#endif
+ if (y == z) {
+ /* Can we stop now? */
+ L = (Long)aadj;
+ aadj -= L;
+ /* The tolerances below are conservative. */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
+ if (aadj < .4999999 || aadj > .5000001)
+ break;
+ }
+ else if (aadj < .4999999/FLT_RADIX)
+ break;
+ }
+#endif
+ cont:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(delta);
+ }
+#ifdef SET_INEXACT
+ if (inexact) {
+ if (!oldinexact) {
+ word0(rv0) = Exp_1 + (70 << Exp_shift);
+ word1(rv0) = 0;
+ dval(rv0) += 1.;
+ }
+ }
+ else if (!oldinexact)
+ clear_inexact();
+#endif
+#ifdef Avoid_Underflow
+ if (scale) {
+ word0(rv0) = Exp_1 - 2*P*Exp_msk1;
+ word1(rv0) = 0;
+ dval(rv) *= dval(rv0);
+#ifndef NO_ERRNO
+ /* try to avoid the bug of testing an 8087 register value */
+ if (word0(rv) == 0 && word1(rv) == 0)
+ errno = ERANGE;
+#endif
+ }
+#endif /* Avoid_Underflow */
+#ifdef SET_INEXACT
+ if (inexact && !(word0(rv) & Exp_mask)) {
+ /* set underflow bit */
+ dval(rv0) = 1e-300;
+ dval(rv0) *= dval(rv0);
+ }
+#endif
+ retfree:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
+ ret:
+ if (se)
+ *se = (char *)s;
+ return sign ? -dval(rv) : dval(rv);
+ }
+
diff --git a/lib/libc/gdtoa/strtodI.c b/lib/libc/gdtoa/strtodI.c
new file mode 100644
index 00000000000..98f889110e0
--- /dev/null
+++ b/lib/libc/gdtoa/strtodI.c
@@ -0,0 +1,167 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ static double
+#ifdef KR_headers
+ulpdown(d) double *d;
+#else
+ulpdown(double *d)
+#endif
+{
+ double u;
+ ULong *L = (ULong*)d;
+
+ u = ulp(*d);
+ if (!(L[_1] | L[_0] & 0xfffff)
+ && (L[_0] & 0x7ff00000) > 0x00100000)
+ u *= 0.5;
+ return u;
+ }
+
+ int
+#ifdef KR_headers
+strtodI(s, sp, dd) CONST char *s; char **sp; double *dd;
+#else
+strtodI(CONST char *s, char **sp, double *dd)
+#endif
+{
+ static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
+ ULong bits[2], sign;
+ Long exp;
+ int j, k;
+ typedef union {
+ double d[2];
+ ULong L[4];
+ } U;
+ U *u;
+
+ k = strtodg(s, sp, &fpi, &exp, bits);
+ u = (U*)dd;
+ sign = k & STRTOG_Neg ? 0x80000000L : 0;
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ u->d[0] = u->d[1] = 0.;
+ break;
+
+ case STRTOG_Zero:
+ u->d[0] = u->d[1] = 0.;
+#ifdef Sudden_Underflow
+ if (k & STRTOG_Inexact) {
+ if (sign)
+ u->L[_0] = 0x80100000L;
+ else
+ u->L[2+_0] = 0x100000L;
+ }
+ break;
+#else
+ goto contain;
+#endif
+
+ case STRTOG_Denormal:
+ u->L[_1] = bits[0];
+ u->L[_0] = bits[1];
+ goto contain;
+
+ case STRTOG_Normal:
+ u->L[_1] = bits[0];
+ u->L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
+ contain:
+ j = k & STRTOG_Inexact;
+ if (sign) {
+ u->L[_0] |= sign;
+ j = STRTOG_Inexact - j;
+ }
+ switch(j) {
+ case STRTOG_Inexlo:
+#ifdef Sudden_Underflow
+ if ((u->L[_0] & 0x7ff00000) < 0x3500000) {
+ u->L[2+_0] = u->L[_0] + 0x3500000;
+ u->L[2+_1] = u->L[_1];
+ u->d[1] += ulp(u->d[1]);
+ u->L[2+_0] -= 0x3500000;
+ if (!(u->L[2+_0] & 0x7ff00000)) {
+ u->L[2+_0] = sign;
+ u->L[2+_1] = 0;
+ }
+ }
+ else
+#endif
+ u->d[1] = u->d[0] + ulp(u->d[0]);
+ break;
+ case STRTOG_Inexhi:
+ u->d[1] = u->d[0];
+#ifdef Sudden_Underflow
+ if ((u->L[_0] & 0x7ff00000) < 0x3500000) {
+ u->L[_0] += 0x3500000;
+ u->d[0] -= ulpdown(u->d);
+ u->L[_0] -= 0x3500000;
+ if (!(u->L[_0] & 0x7ff00000)) {
+ u->L[_0] = sign;
+ u->L[_1] = 0;
+ }
+ }
+ else
+#endif
+ u->d[0] -= ulpdown(u->d);
+ break;
+ default:
+ u->d[1] = u->d[0];
+ }
+ break;
+
+ case STRTOG_Infinite:
+ u->L[_0] = u->L[2+_0] = sign | 0x7ff00000;
+ u->L[_1] = u->L[2+_1] = 0;
+ if (k & STRTOG_Inexact) {
+ if (sign) {
+ u->L[2+_0] = 0xffefffffL;
+ u->L[2+_1] = 0xffffffffL;
+ }
+ else {
+ u->L[_0] = 0x7fefffffL;
+ u->L[_1] = 0xffffffffL;
+ }
+ }
+ break;
+
+ case STRTOG_NaN:
+ u->L[0] = u->L[2] = d_QNAN0;
+ u->L[1] = u->L[3] = d_QNAN1;
+ break;
+
+ case STRTOG_NaNbits:
+ u->L[_0] = u->L[2+_0] = 0x7ff00000 | sign | bits[1];
+ u->L[_1] = u->L[2+_1] = bits[0];
+ }
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtodg.c b/lib/libc/gdtoa/strtodg.c
new file mode 100644
index 00000000000..0c008737813
--- /dev/null
+++ b/lib/libc/gdtoa/strtodg.c
@@ -0,0 +1,1010 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998-2001 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+#ifdef USE_LOCALE
+#include "locale.h"
+#endif
+
+ static CONST int
+fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21,
+ 24, 26, 28, 31, 33, 35, 38, 40, 42, 45,
+ 47, 49, 52
+#ifdef VAX
+ , 54, 56
+#endif
+ };
+
+ Bigint *
+#ifdef KR_headers
+increment(b) Bigint *b;
+#else
+increment(Bigint *b)
+#endif
+{
+ ULong *x, *xe;
+ Bigint *b1;
+#ifdef Pack_16
+ ULong carry = 1, y;
+#endif
+
+ x = b->x;
+ xe = x + b->wds;
+#ifdef Pack_32
+ do {
+ if (*x < (ULong)0xffffffffL) {
+ ++*x;
+ return b;
+ }
+ *x++ = 0;
+ } while(x < xe);
+#else
+ do {
+ y = *x + carry;
+ carry = y >> 16;
+ *x++ = y & 0xffff;
+ if (!carry)
+ return b;
+ } while(x < xe);
+ if (carry)
+#endif
+ {
+ if (b->wds >= b->maxwds) {
+ b1 = Balloc(b->k+1);
+ Bcopy(b1,b);
+ Bfree(b);
+ b = b1;
+ }
+ b->x[b->wds++] = 1;
+ }
+ return b;
+ }
+
+ int
+#ifdef KR_headers
+decrement(b) Bigint *b;
+#else
+decrement(Bigint *b)
+#endif
+{
+ ULong *x, *xe;
+#ifdef Pack_16
+ ULong borrow = 1, y;
+#endif
+
+ x = b->x;
+ xe = x + b->wds;
+#ifdef Pack_32
+ do {
+ if (*x) {
+ --*x;
+ break;
+ }
+ *x++ = 0xffffffffL;
+ }
+ while(x < xe);
+#else
+ do {
+ y = *x - borrow;
+ borrow = (y & 0x10000) >> 16;
+ *x++ = y & 0xffff;
+ } while(borrow && x < xe);
+#endif
+ return STRTOG_Inexlo;
+ }
+
+ static int
+#ifdef KR_headers
+all_on(b, n) Bigint *b; int n;
+#else
+all_on(Bigint *b, int n)
+#endif
+{
+ ULong *x, *xe;
+
+ x = b->x;
+ xe = x + (n >> kshift);
+ while(x < xe)
+ if ((*x++ & ALL_ON) != ALL_ON)
+ return 0;
+ if (n &= kmask)
+ return ((*x | (ALL_ON << n)) & ALL_ON) == ALL_ON;
+ return 1;
+ }
+
+ Bigint *
+#ifdef KR_headers
+set_ones(b, n) Bigint *b; int n;
+#else
+set_ones(Bigint *b, int n)
+#endif
+{
+ int k;
+ ULong *x, *xe;
+
+ k = (n + ((1 << kshift) - 1)) >> kshift;
+ if (b->k < k) {
+ Bfree(b);
+ b = Balloc(k);
+ }
+ k = n >> kshift;
+ if (n &= kmask)
+ k++;
+ b->wds = k;
+ x = b->x;
+ xe = x + k;
+ while(x < xe)
+ *x++ = ALL_ON;
+ if (n)
+ x[-1] >>= ULbits - n;
+ return b;
+ }
+
+ static int
+rvOK
+#ifdef KR_headers
+ (d, fpi, exp, bits, exact, rd, irv)
+ double d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv;
+#else
+ (double d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv)
+#endif
+{
+ Bigint *b;
+ ULong carry, inex, lostbits;
+ int bdif, e, j, k, k1, nb, rv;
+
+ carry = rv = 0;
+ b = d2b(d, &e, &bdif);
+ bdif -= nb = fpi->nbits;
+ e += bdif;
+ if (bdif <= 0) {
+ if (exact)
+ goto trunc;
+ goto ret;
+ }
+ if (P == nb) {
+ if (
+#ifndef IMPRECISE_INEXACT
+ exact &&
+#endif
+ fpi->rounding ==
+#ifdef RND_PRODQUOT
+ FPI_Round_near
+#else
+ Flt_Rounds
+#endif
+ ) goto trunc;
+ goto ret;
+ }
+ switch(rd) {
+ case 1:
+ goto trunc;
+ case 2:
+ break;
+ default: /* round near */
+ k = bdif - 1;
+ if (k < 0)
+ goto trunc;
+ if (!k) {
+ if (!exact)
+ goto ret;
+ if (b->x[0] & 2)
+ break;
+ goto trunc;
+ }
+ if (b->x[k>>kshift] & ((ULong)1 << (k & kmask)))
+ break;
+ goto trunc;
+ }
+ /* "break" cases: round up 1 bit, then truncate; bdif > 0 */
+ carry = 1;
+ trunc:
+ inex = lostbits = 0;
+ if (bdif > 0) {
+ if ( (lostbits = any_on(b, bdif)) !=0)
+ inex = STRTOG_Inexlo;
+ rshift(b, bdif);
+ if (carry) {
+ inex = STRTOG_Inexhi;
+ b = increment(b);
+ if ( (j = nb & kmask) !=0)
+ j = ULbits - j;
+ if (hi0bits(b->x[b->wds - 1]) != j) {
+ if (!lostbits)
+ lostbits = b->x[0] & 1;
+ rshift(b, 1);
+ e++;
+ }
+ }
+ }
+ else if (bdif < 0)
+ b = lshift(b, -bdif);
+ if (e < fpi->emin) {
+ k = fpi->emin - e;
+ e = fpi->emin;
+ if (k > nb || fpi->sudden_underflow) {
+ b->wds = inex = 0;
+ *irv = STRTOG_Underflow | STRTOG_Inexlo;
+ }
+ else {
+ k1 = k - 1;
+ if (k1 > 0 && !lostbits)
+ lostbits = any_on(b, k1);
+ if (!lostbits && !exact)
+ goto ret;
+ lostbits |=
+ carry = b->x[k1>>kshift] & (1 << (k1 & kmask));
+ rshift(b, k);
+ *irv = STRTOG_Denormal;
+ if (carry) {
+ b = increment(b);
+ inex = STRTOG_Inexhi | STRTOG_Underflow;
+ }
+ else if (lostbits)
+ inex = STRTOG_Inexlo | STRTOG_Underflow;
+ }
+ }
+ else if (e > fpi->emax) {
+ e = fpi->emax + 1;
+ *irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
+#ifndef NO_ERRNO
+ errno = ERANGE;
+#endif
+ b->wds = inex = 0;
+ }
+ *exp = e;
+ copybits(bits, nb, b);
+ *irv |= inex;
+ rv = 1;
+ ret:
+ Bfree(b);
+ return rv;
+ }
+
+ static int
+#ifdef KR_headers
+mantbits(d) double d;
+#else
+mantbits(double d)
+#endif
+{
+ ULong L;
+#ifdef VAX
+ L = word1(d) << 16 | word1(d) >> 16;
+ if (L)
+#else
+ if ( (L = word1(d)) !=0)
+#endif
+ return P - lo0bits(&L);
+#ifdef VAX
+ L = word0(d) << 16 | word0(d) >> 16 | Exp_msk11;
+#else
+ L = word0(d) | Exp_msk1;
+#endif
+ return P - 32 - lo0bits(&L);
+ }
+
+ int
+strtodg
+#ifdef KR_headers
+ (s00, se, fpi, exp, bits)
+ CONST char *s00; char **se; FPI *fpi; Long *exp; ULong *bits;
+#else
+ (CONST char *s00, char **se, FPI *fpi, Long *exp, ULong *bits)
+#endif
+{
+ int abe, abits, asub;
+ int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, denorm;
+ int dsign, e, e1, e2, emin, esign, finished, i, inex, irv;
+ int j, k, nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign;
+ int sudden_underflow;
+ CONST char *s, *s0, *s1;
+ double adj, adj0, rv, tol;
+ Long L;
+ ULong y, z;
+ Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0;
+
+ irv = STRTOG_Zero;
+ denorm = sign = nz0 = nz = 0;
+ dval(rv) = 0.;
+ rvb = 0;
+ nbits = fpi->nbits;
+ for(s = s00;;s++) switch(*s) {
+ case '-':
+ sign = 1;
+ /* no break */
+ case '+':
+ if (*++s)
+ goto break2;
+ /* no break */
+ case 0:
+ sign = 0;
+ irv = STRTOG_NoNumber;
+ s = s00;
+ goto ret;
+ case '\t':
+ case '\n':
+ case '\v':
+ case '\f':
+ case '\r':
+ case ' ':
+ continue;
+ default:
+ goto break2;
+ }
+ break2:
+ if (*s == '0') {
+#ifndef NO_HEX_FP
+ switch(s[1]) {
+ case 'x':
+ case 'X':
+ irv = gethex(&s, fpi, exp, &rvb, sign);
+ if (irv == STRTOG_NoNumber) {
+ s = s00;
+ sign = 0;
+ }
+ goto ret;
+ }
+#endif
+ nz0 = 1;
+ while(*++s == '0') ;
+ if (!*s)
+ goto ret;
+ }
+ sudden_underflow = fpi->sudden_underflow;
+ s0 = s;
+ y = z = 0;
+ for(decpt = nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ if (nd < 9)
+ y = 10*y + c - '0';
+ else if (nd < 16)
+ z = 10*z + c - '0';
+ nd0 = nd;
+#ifdef USE_LOCALE
+ if (c == *localeconv()->decimal_point)
+#else
+ if (c == '.')
+#endif
+ {
+ decpt = 1;
+ c = *++s;
+ if (!nd) {
+ for(; c == '0'; c = *++s)
+ nz++;
+ if (c > '0' && c <= '9') {
+ s0 = s;
+ nf += nz;
+ nz = 0;
+ goto have_dig;
+ }
+ goto dig_done;
+ }
+ for(; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+ nz++;
+ if (c -= '0') {
+ nf += nz;
+ for(i = 1; i < nz; i++)
+ if (nd++ < 9)
+ y *= 10;
+ else if (nd <= DBL_DIG + 1)
+ z *= 10;
+ if (nd++ < 9)
+ y = 10*y + c;
+ else if (nd <= DBL_DIG + 1)
+ z = 10*z + c;
+ nz = 0;
+ }
+ }
+ }
+ dig_done:
+ e = 0;
+ if (c == 'e' || c == 'E') {
+ if (!nd && !nz && !nz0) {
+ irv = STRTOG_NoNumber;
+ s = s00;
+ goto ret;
+ }
+ s00 = s;
+ esign = 0;
+ switch(c = *++s) {
+ case '-':
+ esign = 1;
+ case '+':
+ c = *++s;
+ }
+ if (c >= '0' && c <= '9') {
+ while(c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9') {
+ L = c - '0';
+ s1 = s;
+ while((c = *++s) >= '0' && c <= '9')
+ L = 10*L + c - '0';
+ if (s - s1 > 8 || L > 19999)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ e = 19999; /* safe for 16 bit ints */
+ else
+ e = (int)L;
+ if (esign)
+ e = -e;
+ }
+ else
+ e = 0;
+ }
+ else
+ s = s00;
+ }
+ if (!nd) {
+ if (!nz && !nz0) {
+#ifdef INFNAN_CHECK
+ /* Check for Nan and Infinity */
+ if (!decpt)
+ switch(c) {
+ case 'i':
+ case 'I':
+ if (match(&s,"nf")) {
+ --s;
+ if (!match(&s,"inity"))
+ ++s;
+ irv = STRTOG_Infinite;
+ goto infnanexp;
+ }
+ break;
+ case 'n':
+ case 'N':
+ if (match(&s, "an")) {
+ irv = STRTOG_NaN;
+ *exp = fpi->emax + 1;
+#ifndef No_Hex_NaN
+ if (*s == '(') /*)*/
+ irv = hexnan(&s, fpi, bits);
+#endif
+ goto infnanexp;
+ }
+ }
+#endif /* INFNAN_CHECK */
+ irv = STRTOG_NoNumber;
+ s = s00;
+ }
+ goto ret;
+ }
+
+ irv = STRTOG_Normal;
+ e1 = e -= nf;
+ rd = 0;
+ switch(fpi->rounding & 3) {
+ case FPI_Round_up:
+ rd = 2 - sign;
+ break;
+ case FPI_Round_zero:
+ rd = 1;
+ break;
+ case FPI_Round_down:
+ rd = 1 + sign;
+ }
+
+ /* Now we have nd0 digits, starting at s0, followed by a
+ * decimal point, followed by nd-nd0 digits. The number we're
+ * after is the integer represented by those digits times
+ * 10**e */
+
+ if (!nd0)
+ nd0 = nd;
+ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+ dval(rv) = y;
+ if (k > 9)
+ dval(rv) = tens[k - 9] * dval(rv) + z;
+ bd0 = 0;
+ if (nbits <= P && nd <= DBL_DIG) {
+ if (!e) {
+ if (rvOK(dval(rv), fpi, exp, bits, 1, rd, &irv))
+ goto ret;
+ }
+ else if (e > 0) {
+ if (e <= Ten_pmax) {
+#ifdef VAX
+ goto vax_ovfl_check;
+#else
+ i = fivesbits[e] + mantbits(dval(rv)) <= P;
+ /* rv = */ rounded_product(dval(rv), tens[e]);
+ if (rvOK(dval(rv), fpi, exp, bits, i, rd, &irv))
+ goto ret;
+ e1 -= e;
+ goto rv_notOK;
+#endif
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i) {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+ e2 = e - i;
+ e1 -= i;
+ dval(rv) *= tens[i];
+#ifdef VAX
+ /* VAX exponent range is so narrow we must
+ * worry about overflow here...
+ */
+ vax_ovfl_check:
+ dval(adj) = dval(rv);
+ word0(adj) -= P*Exp_msk1;
+ /* adj = */ rounded_product(dval(adj), tens[e2]);
+ if ((word0(adj) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+ goto rv_notOK;
+ word0(adj) += P*Exp_msk1;
+ dval(rv) = dval(adj);
+#else
+ /* rv = */ rounded_product(dval(rv), tens[e2]);
+#endif
+ if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv))
+ goto ret;
+ e1 -= e2;
+ }
+ }
+#ifndef Inaccurate_Divide
+ else if (e >= -Ten_pmax) {
+ /* rv = */ rounded_quotient(dval(rv), tens[-e]);
+ if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv))
+ goto ret;
+ e1 -= e;
+ }
+#endif
+ }
+ rv_notOK:
+ e1 += nd - k;
+
+ /* Get starting approximation = rv * 10**e1 */
+
+ e2 = 0;
+ if (e1 > 0) {
+ if ( (i = e1 & 15) !=0)
+ dval(rv) *= tens[i];
+ if (e1 &= ~15) {
+ e1 >>= 4;
+ while(e1 >= (1 << n_bigtens-1)) {
+ e2 += ((word0(rv) & Exp_mask)
+ >> Exp_shift1) - Bias;
+ word0(rv) &= ~Exp_mask;
+ word0(rv) |= Bias << Exp_shift1;
+ dval(rv) *= bigtens[n_bigtens-1];
+ e1 -= 1 << n_bigtens-1;
+ }
+ e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias;
+ word0(rv) &= ~Exp_mask;
+ word0(rv) |= Bias << Exp_shift1;
+ for(j = 0; e1 > 0; j++, e1 >>= 1)
+ if (e1 & 1)
+ dval(rv) *= bigtens[j];
+ }
+ }
+ else if (e1 < 0) {
+ e1 = -e1;
+ if ( (i = e1 & 15) !=0)
+ dval(rv) /= tens[i];
+ if (e1 &= ~15) {
+ e1 >>= 4;
+ while(e1 >= (1 << n_bigtens-1)) {
+ e2 += ((word0(rv) & Exp_mask)
+ >> Exp_shift1) - Bias;
+ word0(rv) &= ~Exp_mask;
+ word0(rv) |= Bias << Exp_shift1;
+ dval(rv) *= tinytens[n_bigtens-1];
+ e1 -= 1 << n_bigtens-1;
+ }
+ e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias;
+ word0(rv) &= ~Exp_mask;
+ word0(rv) |= Bias << Exp_shift1;
+ for(j = 0; e1 > 0; j++, e1 >>= 1)
+ if (e1 & 1)
+ dval(rv) *= tinytens[j];
+ }
+ }
+#ifdef IBM
+ /* e2 is a correction to the (base 2) exponent of the return
+ * value, reflecting adjustments above to avoid overflow in the
+ * native arithmetic. For native IBM (base 16) arithmetic, we
+ * must multiply e2 by 4 to change from base 16 to 2.
+ */
+ e2 <<= 2;
+#endif
+ rvb = d2b(dval(rv), &rve, &rvbits); /* rv = rvb * 2^rve */
+ rve += e2;
+ if ((j = rvbits - nbits) > 0) {
+ rshift(rvb, j);
+ rvbits = nbits;
+ rve += j;
+ }
+ bb0 = 0; /* trailing zero bits in rvb */
+ e2 = rve + rvbits - nbits;
+ if (e2 > fpi->emax + 1)
+ goto huge;
+ rve1 = rve + rvbits - nbits;
+ if (e2 < (emin = fpi->emin)) {
+ denorm = 1;
+ j = rve - emin;
+ if (j > 0) {
+ rvb = lshift(rvb, j);
+ rvbits += j;
+ }
+ else if (j < 0) {
+ rvbits += j;
+ if (rvbits <= 0) {
+ if (rvbits < -1) {
+ ufl:
+ rvb->wds = 0;
+ rvb->x[0] = 0;
+ *exp = emin;
+ irv = STRTOG_Underflow | STRTOG_Inexlo;
+ goto ret;
+ }
+ rvb->x[0] = rvb->wds = rvbits = 1;
+ }
+ else
+ rshift(rvb, -j);
+ }
+ rve = rve1 = emin;
+ if (sudden_underflow && e2 + 1 < emin)
+ goto ufl;
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bd0 = s2b(s0, nd0, nd, y);
+
+ for(;;) {
+ bd = Balloc(bd0->k);
+ Bcopy(bd, bd0);
+ bb = Balloc(rvb->k);
+ Bcopy(bb, rvb);
+ bbbits = rvbits - bb0;
+ bbe = rve + bb0;
+ bs = i2b(1);
+
+ if (e >= 0) {
+ bb2 = bb5 = 0;
+ bd2 = bd5 = e;
+ }
+ else {
+ bb2 = bb5 = -e;
+ bd2 = bd5 = 0;
+ }
+ if (bbe >= 0)
+ bb2 += bbe;
+ else
+ bd2 -= bbe;
+ bs2 = bb2;
+ j = nbits + 1 - bbbits;
+ i = bbe + bbbits - nbits;
+ if (i < emin) /* denormal */
+ j += i - emin;
+ bb2 += j;
+ bd2 += j;
+ i = bb2 < bd2 ? bb2 : bd2;
+ if (i > bs2)
+ i = bs2;
+ if (i > 0) {
+ bb2 -= i;
+ bd2 -= i;
+ bs2 -= i;
+ }
+ if (bb5 > 0) {
+ bs = pow5mult(bs, bb5);
+ bb1 = mult(bs, bb);
+ Bfree(bb);
+ bb = bb1;
+ }
+ bb2 -= bb0;
+ if (bb2 > 0)
+ bb = lshift(bb, bb2);
+ else if (bb2 < 0)
+ rshift(bb, -bb2);
+ if (bd5 > 0)
+ bd = pow5mult(bd, bd5);
+ if (bd2 > 0)
+ bd = lshift(bd, bd2);
+ if (bs2 > 0)
+ bs = lshift(bs, bs2);
+ asub = 1;
+ inex = STRTOG_Inexhi;
+ delta = diff(bb, bd);
+ if (delta->wds <= 1 && !delta->x[0])
+ break;
+ dsign = delta->sign;
+ delta->sign = finished = 0;
+ L = 0;
+ i = cmp(delta, bs);
+ if (rd && i <= 0) {
+ irv = STRTOG_Normal;
+ if ( (finished = dsign ^ (rd&1)) !=0) {
+ if (dsign != 0) {
+ irv |= STRTOG_Inexhi;
+ goto adj1;
+ }
+ irv |= STRTOG_Inexlo;
+ if (rve1 == emin)
+ goto adj1;
+ for(i = 0, j = nbits; j >= ULbits;
+ i++, j -= ULbits) {
+ if (rvb->x[i] & ALL_ON)
+ goto adj1;
+ }
+ if (j > 1 && lo0bits(rvb->x + i) < j - 1)
+ goto adj1;
+ rve = rve1 - 1;
+ rvb = set_ones(rvb, rvbits = nbits);
+ break;
+ }
+ irv |= dsign ? STRTOG_Inexlo : STRTOG_Inexhi;
+ break;
+ }
+ if (i < 0) {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ irv = dsign
+ ? STRTOG_Normal | STRTOG_Inexlo
+ : STRTOG_Normal | STRTOG_Inexhi;
+ if (dsign || bbbits > 1 || denorm || rve1 == emin)
+ break;
+ delta = lshift(delta,1);
+ if (cmp(delta, bs) > 0) {
+ irv = STRTOG_Normal | STRTOG_Inexlo;
+ goto drop_down;
+ }
+ break;
+ }
+ if (i == 0) {
+ /* exactly half-way between */
+ if (dsign) {
+ if (denorm && all_on(rvb, rvbits)) {
+ /*boundary case -- increment exponent*/
+ rvb->wds = 1;
+ rvb->x[0] = 1;
+ rve = emin + nbits - (rvbits = 1);
+ irv = STRTOG_Normal | STRTOG_Inexhi;
+ denorm = 0;
+ break;
+ }
+ irv = STRTOG_Normal | STRTOG_Inexlo;
+ }
+ else if (bbbits == 1) {
+ irv = STRTOG_Normal;
+ drop_down:
+ /* boundary case -- decrement exponent */
+ if (rve1 == emin) {
+ irv = STRTOG_Normal | STRTOG_Inexhi;
+ if (rvb->wds == 1 && rvb->x[0] == 1)
+ sudden_underflow = 1;
+ break;
+ }
+ rve -= nbits;
+ rvb = set_ones(rvb, rvbits = nbits);
+ break;
+ }
+ else
+ irv = STRTOG_Normal | STRTOG_Inexhi;
+ if (bbbits < nbits && !denorm || !(rvb->x[0] & 1))
+ break;
+ if (dsign) {
+ rvb = increment(rvb);
+ j = kmask & (ULbits - (rvbits & kmask));
+ if (hi0bits(rvb->x[rvb->wds - 1]) != j)
+ rvbits++;
+ irv = STRTOG_Normal | STRTOG_Inexhi;
+ }
+ else {
+ if (bbbits == 1)
+ goto undfl;
+ decrement(rvb);
+ irv = STRTOG_Normal | STRTOG_Inexlo;
+ }
+ break;
+ }
+ if ((dval(adj) = ratio(delta, bs)) <= 2.) {
+ adj1:
+ inex = STRTOG_Inexlo;
+ if (dsign) {
+ asub = 0;
+ inex = STRTOG_Inexhi;
+ }
+ else if (denorm && bbbits <= 1) {
+ undfl:
+ rvb->wds = 0;
+ rve = emin;
+ irv = STRTOG_Underflow | STRTOG_Inexlo;
+ break;
+ }
+ adj0 = dval(adj) = 1.;
+ }
+ else {
+ adj0 = dval(adj) *= 0.5;
+ if (dsign) {
+ asub = 0;
+ inex = STRTOG_Inexlo;
+ }
+ if (dval(adj) < 2147483647.) {
+ L = adj0;
+ adj0 -= L;
+ switch(rd) {
+ case 0:
+ if (adj0 >= .5)
+ goto inc_L;
+ break;
+ case 1:
+ if (asub && adj0 > 0.)
+ goto inc_L;
+ break;
+ case 2:
+ if (!asub && adj0 > 0.) {
+ inc_L:
+ L++;
+ inex = STRTOG_Inexact - inex;
+ }
+ }
+ dval(adj) = L;
+ }
+ }
+ y = rve + rvbits;
+
+ /* adj *= ulp(dval(rv)); */
+ /* if (asub) rv -= adj; else rv += adj; */
+
+ if (!denorm && rvbits < nbits) {
+ rvb = lshift(rvb, j = nbits - rvbits);
+ rve -= j;
+ rvbits = nbits;
+ }
+ ab = d2b(dval(adj), &abe, &abits);
+ if (abe < 0)
+ rshift(ab, -abe);
+ else if (abe > 0)
+ ab = lshift(ab, abe);
+ rvb0 = rvb;
+ if (asub) {
+ /* rv -= adj; */
+ j = hi0bits(rvb->x[rvb->wds-1]);
+ rvb = diff(rvb, ab);
+ k = rvb0->wds - 1;
+ if (denorm)
+ /* do nothing */;
+ else if (rvb->wds <= k
+ || hi0bits( rvb->x[k]) >
+ hi0bits(rvb0->x[k])) {
+ /* unlikely; can only have lost 1 high bit */
+ if (rve1 == emin) {
+ --rvbits;
+ denorm = 1;
+ }
+ else {
+ rvb = lshift(rvb, 1);
+ --rve;
+ --rve1;
+ L = finished = 0;
+ }
+ }
+ }
+ else {
+ rvb = sum(rvb, ab);
+ k = rvb->wds - 1;
+ if (k >= rvb0->wds
+ || hi0bits(rvb->x[k]) < hi0bits(rvb0->x[k])) {
+ if (denorm) {
+ if (++rvbits == nbits)
+ denorm = 0;
+ }
+ else {
+ rshift(rvb, 1);
+ rve++;
+ rve1++;
+ L = 0;
+ }
+ }
+ }
+ Bfree(ab);
+ Bfree(rvb0);
+ if (finished)
+ break;
+
+ z = rve + rvbits;
+ if (y == z && L) {
+ /* Can we stop now? */
+ tol = dval(adj) * 5e-16; /* > max rel error */
+ dval(adj) = adj0 - .5;
+ if (dval(adj) < -tol) {
+ if (adj0 > tol) {
+ irv |= inex;
+ break;
+ }
+ }
+ else if (dval(adj) > tol && adj0 < 1. - tol) {
+ irv |= inex;
+ break;
+ }
+ }
+ bb0 = denorm ? 0 : trailz(rvb);
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(delta);
+ }
+ if (!denorm && (j = nbits - rvbits)) {
+ if (j > 0)
+ rvb = lshift(rvb, j);
+ else
+ rshift(rvb, -j);
+ rve -= j;
+ }
+ *exp = rve;
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
+ if (rve > fpi->emax) {
+ huge:
+ rvb->wds = 0;
+ irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
+#ifndef NO_ERRNO
+ errno = ERANGE;
+#endif
+ infnanexp:
+ *exp = fpi->emax + 1;
+ }
+ ret:
+ if (denorm) {
+ if (sudden_underflow) {
+ rvb->wds = 0;
+ irv = STRTOG_Underflow | STRTOG_Inexlo;
+ }
+ else {
+ irv = (irv & ~STRTOG_Retmask) |
+ (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero);
+ if (irv & STRTOG_Inexact)
+ irv |= STRTOG_Underflow;
+ }
+ }
+ if (se)
+ *se = (char *)s;
+ if (sign)
+ irv |= STRTOG_Neg;
+ if (rvb) {
+ copybits(bits, nbits, rvb);
+ Bfree(rvb);
+ }
+ return irv;
+ }
diff --git a/lib/libc/gdtoa/strtodnrp.c b/lib/libc/gdtoa/strtodnrp.c
new file mode 100644
index 00000000000..19a769f0b43
--- /dev/null
+++ b/lib/libc/gdtoa/strtodnrp.c
@@ -0,0 +1,87 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 2004 by David M. Gay.
+All Rights Reserved
+Based on material in the rest of /netlib/fp/gdota.tar.gz,
+which is copyright (C) 1998, 2000 by Lucent Technologies.
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* This is a variant of strtod that works on Intel ia32 systems */
+/* with the default extended-precision arithmetic -- it does not */
+/* require setting the precision control to 53 bits. */
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ double
+#ifdef KR_headers
+strtod(s, sp) CONST char *s; char **sp;
+#else
+strtod(CONST char *s, char **sp)
+#endif
+{
+ static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
+ ULong bits[2];
+ Long exp;
+ int k;
+ union { ULong L[2]; double d; } u;
+
+ k = strtodg(s, sp, &fpi, &exp, bits);
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ u.L[0] = u.L[1] = 0;
+ break;
+
+ case STRTOG_Normal:
+ u.L[_1] = bits[0];
+ u.L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
+ break;
+
+ case STRTOG_Denormal:
+ u.L[_1] = bits[0];
+ u.L[_0] = bits[1];
+ break;
+
+ case STRTOG_Infinite:
+ u.L[_0] = 0x7ff00000;
+ u.L[_1] = 0;
+ break;
+
+ case STRTOG_NaN:
+ u.L[0] = d_QNAN0;
+ u.L[1] = d_QNAN1;
+ break;
+
+ case STRTOG_NaNbits:
+ u.L[_0] = 0x7ff00000 | bits[1];
+ u.L[_1] = bits[0];
+ }
+ if (k & STRTOG_Neg)
+ u.L[_0] |= 0x80000000L;
+ return u.d;
+ }
diff --git a/lib/libc/gdtoa/strtof.c b/lib/libc/gdtoa/strtof.c
new file mode 100644
index 00000000000..21bc6c15bfe
--- /dev/null
+++ b/lib/libc/gdtoa/strtof.c
@@ -0,0 +1,73 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ float
+#ifdef KR_headers
+strtof(s, sp) CONST char *s; char **sp;
+#else
+strtof(CONST char *s, char **sp)
+#endif
+{
+ static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI };
+ ULong bits[1];
+ Long exp;
+ int k;
+ union { ULong L[1]; float f; } u;
+
+ k = strtodg(s, sp, &fpi, &exp, bits);
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ u.L[0] = 0;
+ break;
+
+ case STRTOG_Normal:
+ case STRTOG_NaNbits:
+ u.L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23;
+ break;
+
+ case STRTOG_Denormal:
+ u.L[0] = bits[0];
+ break;
+
+ case STRTOG_Infinite:
+ u.L[0] = 0x7f800000;
+ break;
+
+ case STRTOG_NaN:
+ u.L[0] = f_QNAN;
+ }
+ if (k & STRTOG_Neg)
+ u.L[0] |= 0x80000000L;
+ return u.f;
+ }
diff --git a/lib/libc/gdtoa/strtold.c b/lib/libc/gdtoa/strtold.c
new file mode 100644
index 00000000000..0de6d88c008
--- /dev/null
+++ b/lib/libc/gdtoa/strtold.c
@@ -0,0 +1,40 @@
+/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */
+/*-
+ * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * Machine-dependent glue to integrate David Gay's gdtoa
+ * package into libc for architectures where a long double
+ * is the same as a double, such as the Alpha.
+ */
+
+#include "gdtoaimp.h"
+
+long double
+strtold(const char * __restrict s, char ** __restrict sp)
+{
+ return strtod(s, sp);
+}
diff --git a/lib/libc/gdtoa/strtopQ.c b/lib/libc/gdtoa/strtopQ.c
new file mode 100644
index 00000000000..dd5dab826c9
--- /dev/null
+++ b/lib/libc/gdtoa/strtopQ.c
@@ -0,0 +1,101 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+#undef _0
+#undef _1
+
+/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
+
+#ifdef IEEE_MC68k
+#define _0 0
+#define _1 1
+#define _2 2
+#define _3 3
+#endif
+#ifdef IEEE_8087
+#define _0 3
+#define _1 2
+#define _2 1
+#define _3 0
+#endif
+
+ int
+#ifdef KR_headers
+strtopQ(s, sp, V) CONST char *s; char **sp; void *V;
+#else
+strtopQ(CONST char *s, char **sp, void *V)
+#endif
+{
+ static FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, SI };
+ ULong bits[4];
+ Long exp;
+ int k;
+ ULong *L = (ULong*)V;
+
+ k = strtodg(s, sp, &fpi, &exp, bits);
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ L[0] = L[1] = L[2] = L[3] = 0;
+ break;
+
+ case STRTOG_Normal:
+ case STRTOG_NaNbits:
+ L[_3] = bits[0];
+ L[_2] = bits[1];
+ L[_1] = bits[2];
+ L[_0] = (bits[3] & ~0x10000) | ((exp + 0x3fff + 112) << 16);
+ break;
+
+ case STRTOG_Denormal:
+ L[_3] = bits[0];
+ L[_2] = bits[1];
+ L[_1] = bits[2];
+ L[_0] = bits[3];
+ break;
+
+ case STRTOG_Infinite:
+ L[_0] = 0x7fff0000;
+ L[_1] = L[_2] = L[_3] = 0;
+ break;
+
+ case STRTOG_NaN:
+ L[0] = ld_QNAN0;
+ L[1] = ld_QNAN1;
+ L[2] = ld_QNAN2;
+ L[3] = ld_QNAN3;
+ }
+ if (k & STRTOG_Neg)
+ L[_0] |= 0x80000000L;
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtopd.c b/lib/libc/gdtoa/strtopd.c
new file mode 100644
index 00000000000..42c57fcc1fc
--- /dev/null
+++ b/lib/libc/gdtoa/strtopd.c
@@ -0,0 +1,49 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ int
+#ifdef KR_headers
+strtopd(s, sp, d) char *s; char **sp; double *d;
+#else
+strtopd(CONST char *s, char **sp, double *d)
+#endif
+{
+ static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
+ ULong bits[2];
+ Long exp;
+ int k;
+
+ k = strtodg(s, sp, &fpi0, &exp, bits);
+ ULtod((ULong*)d, bits, exp, k);
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtopdd.c b/lib/libc/gdtoa/strtopdd.c
new file mode 100644
index 00000000000..9b788eecc9a
--- /dev/null
+++ b/lib/libc/gdtoa/strtopdd.c
@@ -0,0 +1,178 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ int
+#ifdef KR_headers
+strtopdd(s, sp, dd) CONST char *s; char **sp; double *dd;
+#else
+strtopdd(CONST char *s, char **sp, double *dd)
+#endif
+{
+#ifdef Sudden_Underflow
+ static FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 };
+#else
+ static FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 };
+#endif
+ ULong bits[4];
+ Long exp;
+ int i, j, rv;
+ typedef union {
+ double d[2];
+ ULong L[4];
+ } U;
+ U *u;
+
+ rv = strtodg(s, sp, &fpi, &exp, bits);
+ u = (U*)dd;
+ switch(rv & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ u->d[0] = u->d[1] = 0.;
+ break;
+
+ case STRTOG_Normal:
+ u->L[_1] = (bits[1] >> 21 | bits[2] << 11) & 0xffffffffL;
+ u->L[_0] = bits[2] >> 21 | bits[3] << 11 & 0xfffff
+ | exp + 0x3ff + 105 << 20;
+ exp += 0x3ff + 52;
+ if (bits[1] &= 0x1fffff) {
+ i = hi0bits(bits[1]) - 11;
+ if (i >= exp) {
+ i = exp - 1;
+ exp = 0;
+ }
+ else
+ exp -= i;
+ if (i > 0) {
+ bits[1] = bits[1] << i | bits[0] >> 32-i;
+ bits[0] = bits[0] << i & 0xffffffffL;
+ }
+ }
+ else if (bits[0]) {
+ i = hi0bits(bits[0]) + 21;
+ if (i >= exp) {
+ i = exp - 1;
+ exp = 0;
+ }
+ else
+ exp -= i;
+ if (i < 32) {
+ bits[1] = bits[0] >> 32 - i;
+ bits[0] = bits[0] << i & 0xffffffffL;
+ }
+ else {
+ bits[1] = bits[0] << i - 32;
+ bits[0] = 0;
+ }
+ }
+ else {
+ u->L[2] = u->L[3] = 0;
+ break;
+ }
+ u->L[2+_1] = bits[0];
+ u->L[2+_0] = bits[1] & 0xfffff | exp << 20;
+ break;
+
+ case STRTOG_Denormal:
+ if (bits[3])
+ goto nearly_normal;
+ if (bits[2])
+ goto partly_normal;
+ if (bits[1] & 0xffe00000)
+ goto hardly_normal;
+ /* completely denormal */
+ u->L[2] = u->L[3] = 0;
+ u->L[_1] = bits[0];
+ u->L[_0] = bits[1];
+ break;
+
+ nearly_normal:
+ i = hi0bits(bits[3]) - 11; /* i >= 12 */
+ j = 32 - i;
+ u->L[_0] = (bits[3] << i | bits[2] >> j) & 0xfffff
+ | 65 - i << 20;
+ u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL;
+ u->L[2+_0] = bits[1] & (1L << j) - 1;
+ u->L[2+_1] = bits[0];
+ break;
+
+ partly_normal:
+ i = hi0bits(bits[2]) - 11;
+ if (i < 0) {
+ j = -i;
+ i += 32;
+ u->L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20;
+ u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL;
+ u->L[2+_0] = bits[1] & (1L << j) - 1;
+ u->L[2+_1] = bits[0];
+ break;
+ }
+ if (i == 0) {
+ u->L[_0] = bits[2] & 0xfffff | 33 << 20;
+ u->L[_1] = bits[1];
+ u->L[2+_0] = 0;
+ u->L[2+_1] = bits[0];
+ break;
+ }
+ j = 32 - i;
+ u->L[_0] = (bits[2] << i | bits[1] >> j) & 0xfffff
+ | j + 1 << 20;
+ u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL;
+ u->L[2+_0] = 0;
+ u->L[2+_1] = bits[0] & (1L << j) - 1;
+ break;
+
+ hardly_normal:
+ j = 11 - hi0bits(bits[1]);
+ i = 32 - j;
+ u->L[_0] = bits[1] >> j & 0xfffff | j + 1 << 20;
+ u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL;
+ u->L[2+_0] = 0;
+ u->L[2+_1] = bits[0] & (1L << j) - 1;
+ break;
+
+ case STRTOG_Infinite:
+ u->L[_0] = u->L[2+_0] = 0x7ff00000;
+ u->L[_1] = u->L[2+_1] = 0;
+ break;
+
+ case STRTOG_NaN:
+ u->L[0] = u->L[2] = d_QNAN0;
+ u->L[1] = u->L[3] = d_QNAN1;
+ }
+ if (rv & STRTOG_Neg) {
+ u->L[ _0] |= 0x80000000L;
+ u->L[2+_0] |= 0x80000000L;
+ }
+ return rv;
+ }
diff --git a/lib/libc/gdtoa/strtopf.c b/lib/libc/gdtoa/strtopf.c
new file mode 100644
index 00000000000..cc7c970cba4
--- /dev/null
+++ b/lib/libc/gdtoa/strtopf.c
@@ -0,0 +1,73 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ int
+#ifdef KR_headers
+strtopf(s, sp, f) CONST char *s; char **sp; float *f;
+#else
+strtopf(CONST char *s, char **sp, float *f)
+#endif
+{
+ static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI };
+ ULong bits[1], *L;
+ Long exp;
+ int k;
+
+ k = strtodg(s, sp, &fpi, &exp, bits);
+ L = (ULong*)f;
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ L[0] = 0;
+ break;
+
+ case STRTOG_Normal:
+ case STRTOG_NaNbits:
+ L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23;
+ break;
+
+ case STRTOG_Denormal:
+ L[0] = bits[0];
+ break;
+
+ case STRTOG_Infinite:
+ L[0] = 0x7f800000;
+ break;
+
+ case STRTOG_NaN:
+ L[0] = f_QNAN;
+ }
+ if (k & STRTOG_Neg)
+ L[0] |= 0x80000000L;
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtopx.c b/lib/libc/gdtoa/strtopx.c
new file mode 100644
index 00000000000..4dcb06ae73c
--- /dev/null
+++ b/lib/libc/gdtoa/strtopx.c
@@ -0,0 +1,103 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+#undef _0
+#undef _1
+
+/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
+
+#ifdef IEEE_MC68k
+#define _0 0
+#define _1 1
+#define _2 2
+#define _3 3
+#define _4 4
+#endif
+#ifdef IEEE_8087
+#define _0 4
+#define _1 3
+#define _2 2
+#define _3 1
+#define _4 0
+#endif
+
+ int
+#ifdef KR_headers
+strtopx(s, sp, V) CONST char *s; char **sp; void *V;
+#else
+strtopx(CONST char *s, char **sp, void *V)
+#endif
+{
+ static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
+ ULong bits[2];
+ Long exp;
+ int k;
+ UShort *L = (UShort*)V;
+
+ k = strtodg(s, sp, &fpi, &exp, bits);
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ L[0] = L[1] = L[2] = L[3] = L[4] = 0;
+ break;
+
+ case STRTOG_Denormal:
+ L[_0] = 0;
+ goto normal_bits;
+
+ case STRTOG_Normal:
+ case STRTOG_NaNbits:
+ L[_0] = exp + 0x3fff + 63;
+ normal_bits:
+ L[_4] = (UShort)bits[0];
+ L[_3] = (UShort)(bits[0] >> 16);
+ L[_2] = (UShort)bits[1];
+ L[_1] = (UShort)(bits[1] >> 16);
+ break;
+
+ case STRTOG_Infinite:
+ L[_0] = 0x7fff;
+ L[_1] = L[_2] = L[_3] = L[_4] = 0;
+ break;
+
+ case STRTOG_NaN:
+ L[0] = ldus_QNAN0;
+ L[1] = ldus_QNAN1;
+ L[2] = ldus_QNAN2;
+ L[3] = ldus_QNAN3;
+ L[4] = ldus_QNAN4;
+ }
+ if (k & STRTOG_Neg)
+ L[_0] |= 0x8000;
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtopxL.c b/lib/libc/gdtoa/strtopxL.c
new file mode 100644
index 00000000000..68c83d2bdae
--- /dev/null
+++ b/lib/libc/gdtoa/strtopxL.c
@@ -0,0 +1,91 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+#undef _0
+#undef _1
+
+/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
+
+#ifdef IEEE_MC68k
+#define _0 0
+#define _1 1
+#define _2 2
+#endif
+#ifdef IEEE_8087
+#define _0 2
+#define _1 1
+#define _2 0
+#endif
+
+ int
+#ifdef KR_headers
+strtopxL(s, sp, V) CONST char *s; char **sp; void *V;
+#else
+strtopxL(CONST char *s, char **sp, void *V)
+#endif
+{
+ static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
+ ULong bits[2];
+ Long exp;
+ int k;
+ ULong *L = (ULong*)V;
+
+ k = strtodg(s, sp, &fpi, &exp, bits);
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ L[0] = L[1] = L[2] = 0;
+ break;
+
+ case STRTOG_Normal:
+ case STRTOG_Denormal:
+ case STRTOG_NaNbits:
+ L[_2] = bits[0];
+ L[_1] = bits[1];
+ L[_0] = (exp + 0x3fff + 63) << 16;
+ break;
+
+ case STRTOG_Infinite:
+ L[_0] = 0x7fff << 16;
+ L[_1] = L[_2] = 0;
+ break;
+
+ case STRTOG_NaN:
+ L[0] = ld_QNAN0;
+ L[1] = ld_QNAN1;
+ L[2] = ld_QNAN2;
+ }
+ if (k & STRTOG_Neg)
+ L[_0] |= 0x80000000L;
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtorQ.c b/lib/libc/gdtoa/strtorQ.c
new file mode 100644
index 00000000000..a9a07da04ea
--- /dev/null
+++ b/lib/libc/gdtoa/strtorQ.c
@@ -0,0 +1,117 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+#undef _0
+#undef _1
+
+/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
+
+#ifdef IEEE_MC68k
+#define _0 0
+#define _1 1
+#define _2 2
+#define _3 3
+#endif
+#ifdef IEEE_8087
+#define _0 3
+#define _1 2
+#define _2 1
+#define _3 0
+#endif
+
+ void
+#ifdef KR_headers
+ULtoQ(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
+#else
+ULtoQ(ULong *L, ULong *bits, Long exp, int k)
+#endif
+{
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ L[0] = L[1] = L[2] = L[3] = 0;
+ break;
+
+ case STRTOG_Normal:
+ case STRTOG_NaNbits:
+ L[_3] = bits[0];
+ L[_2] = bits[1];
+ L[_1] = bits[2];
+ L[_0] = (bits[3] & ~0x10000) | ((exp + 0x3fff + 112) << 16);
+ break;
+
+ case STRTOG_Denormal:
+ L[_3] = bits[0];
+ L[_2] = bits[1];
+ L[_1] = bits[2];
+ L[_0] = bits[3];
+ break;
+
+ case STRTOG_Infinite:
+ L[_0] = 0x7fff0000;
+ L[_1] = L[_2] = L[_3] = 0;
+ break;
+
+ case STRTOG_NaN:
+ L[0] = ld_QNAN0;
+ L[1] = ld_QNAN1;
+ L[2] = ld_QNAN2;
+ L[3] = ld_QNAN3;
+ }
+ if (k & STRTOG_Neg)
+ L[_0] |= 0x80000000L;
+ }
+
+ int
+#ifdef KR_headers
+strtorQ(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L;
+#else
+strtorQ(CONST char *s, char **sp, int rounding, void *L)
+#endif
+{
+ static FPI fpi0 = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI };
+ FPI *fpi, fpi1;
+ ULong bits[4];
+ Long exp;
+ int k;
+
+ fpi = &fpi0;
+ if (rounding != FPI_Round_near) {
+ fpi1 = fpi0;
+ fpi1.rounding = rounding;
+ fpi = &fpi1;
+ }
+ k = strtodg(s, sp, fpi, &exp, bits);
+ ULtoQ((ULong*)L, bits, exp, k);
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtord.c b/lib/libc/gdtoa/strtord.c
new file mode 100644
index 00000000000..709af4c713f
--- /dev/null
+++ b/lib/libc/gdtoa/strtord.c
@@ -0,0 +1,93 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ void
+#ifdef KR_headers
+ULtod(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
+#else
+ULtod(ULong *L, ULong *bits, Long exp, int k)
+#endif
+{
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ L[0] = L[1] = 0;
+ break;
+
+ case STRTOG_Denormal:
+ L[_1] = bits[0];
+ L[_0] = bits[1];
+ break;
+
+ case STRTOG_Normal:
+ case STRTOG_NaNbits:
+ L[_1] = bits[0];
+ L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
+ break;
+
+ case STRTOG_Infinite:
+ L[_0] = 0x7ff00000;
+ L[_1] = 0;
+ break;
+
+ case STRTOG_NaN:
+ L[0] = d_QNAN0;
+ L[1] = d_QNAN1;
+ }
+ if (k & STRTOG_Neg)
+ L[_0] |= 0x80000000L;
+ }
+
+ int
+#ifdef KR_headers
+strtord(s, sp, rounding, d) CONST char *s; char **sp; int rounding; double *d;
+#else
+strtord(CONST char *s, char **sp, int rounding, double *d)
+#endif
+{
+ static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
+ FPI *fpi, fpi1;
+ ULong bits[2];
+ Long exp;
+ int k;
+
+ fpi = &fpi0;
+ if (rounding != FPI_Round_near) {
+ fpi1 = fpi0;
+ fpi1.rounding = rounding;
+ fpi = &fpi1;
+ }
+ k = strtodg(s, sp, fpi, &exp, bits);
+ ULtod((ULong*)d, bits, exp, k);
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtordd.c b/lib/libc/gdtoa/strtordd.c
new file mode 100644
index 00000000000..9c2b46e65e3
--- /dev/null
+++ b/lib/libc/gdtoa/strtordd.c
@@ -0,0 +1,199 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ void
+#ifdef KR_headers
+ULtodd(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
+#else
+ULtodd(ULong *L, ULong *bits, Long exp, int k)
+#endif
+{
+ int i, j;
+
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ L[0] = L[1] = L[2] = L[3] = 0;
+ break;
+
+ case STRTOG_Normal:
+ L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL;
+ L[_0] = bits[2] >> 21 | bits[3] << 11 & 0xfffff
+ | exp + 0x3ff + 105 << 20;
+ exp += 0x3ff + 52;
+ if (bits[1] &= 0x1fffff) {
+ i = hi0bits(bits[1]) - 11;
+ if (i >= exp) {
+ i = exp - 1;
+ exp = 0;
+ }
+ else
+ exp -= i;
+ if (i > 0) {
+ bits[1] = bits[1] << i | bits[0] >> 32-i;
+ bits[0] = bits[0] << i & (ULong)0xffffffffL;
+ }
+ }
+ else if (bits[0]) {
+ i = hi0bits(bits[0]) + 21;
+ if (i >= exp) {
+ i = exp - 1;
+ exp = 0;
+ }
+ else
+ exp -= i;
+ if (i < 32) {
+ bits[1] = bits[0] >> 32 - i;
+ bits[0] = bits[0] << i & (ULong)0xffffffffL;
+ }
+ else {
+ bits[1] = bits[0] << i - 32;
+ bits[0] = 0;
+ }
+ }
+ else {
+ L[2] = L[3] = 0;
+ break;
+ }
+ L[2+_1] = bits[0];
+ L[2+_0] = bits[1] & 0xfffff | exp << 20;
+ break;
+
+ case STRTOG_Denormal:
+ if (bits[3])
+ goto nearly_normal;
+ if (bits[2])
+ goto partly_normal;
+ if (bits[1] & 0xffe00000)
+ goto hardly_normal;
+ /* completely denormal */
+ L[2] = L[3] = 0;
+ L[_1] = bits[0];
+ L[_0] = bits[1];
+ break;
+
+ nearly_normal:
+ i = hi0bits(bits[3]) - 11; /* i >= 12 */
+ j = 32 - i;
+ L[_0] = (bits[3] << i | bits[2] >> j) & 0xfffff
+ | 65 - i << 20;
+ L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL;
+ L[2+_0] = bits[1] & ((ULong)1L << j) - 1;
+ L[2+_1] = bits[0];
+ break;
+
+ partly_normal:
+ i = hi0bits(bits[2]) - 11;
+ if (i < 0) {
+ j = -i;
+ i += 32;
+ L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20;
+ L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL;
+ L[2+_0] = bits[1] & ((ULong)1L << j) - 1;
+ L[2+_1] = bits[0];
+ break;
+ }
+ if (i == 0) {
+ L[_0] = bits[2] & 0xfffff | 33 << 20;
+ L[_1] = bits[1];
+ L[2+_0] = 0;
+ L[2+_1] = bits[0];
+ break;
+ }
+ j = 32 - i;
+ L[_0] = (bits[2] << i | bits[1] >> j) & 0xfffff
+ | j + 1 << 20;
+ L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL;
+ L[2+_0] = 0;
+ L[2+_1] = bits[0] & (1L << j) - 1;
+ break;
+
+ hardly_normal:
+ j = 11 - hi0bits(bits[1]);
+ i = 32 - j;
+ L[_0] = bits[1] >> j & 0xfffff | j + 1 << 20;
+ L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL;
+ L[2+_0] = 0;
+ L[2+_1] = bits[0] & ((ULong)1L << j) - 1;
+ break;
+
+ case STRTOG_Infinite:
+ L[_0] = L[2+_0] = 0x7ff00000;
+ L[_1] = L[2+_1] = 0;
+ break;
+
+ case STRTOG_NaN:
+ L[0] = L[2] = d_QNAN0;
+ L[1] = L[3] = d_QNAN1;
+ break;
+
+ case STRTOG_NaNbits:
+ L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL;
+ L[_0] = bits[2] >> 21 | bits[3] << 11
+ | (ULong)0x7ff00000L;
+ L[2+_1] = bits[0];
+ L[2+_0] = bits[1] | (ULong)0x7ff00000L;
+ }
+ if (k & STRTOG_Neg) {
+ L[_0] |= 0x80000000L;
+ L[2+_0] |= 0x80000000L;
+ }
+ }
+
+ int
+#ifdef KR_headers
+strtordd(s, sp, rounding, dd) CONST char *s; char **sp; int rounding; double *dd;
+#else
+strtordd(CONST char *s, char **sp, int rounding, double *dd)
+#endif
+{
+#ifdef Sudden_Underflow
+ static FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 };
+#else
+ static FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 };
+#endif
+ FPI *fpi, fpi1;
+ ULong bits[4];
+ Long exp;
+ int k;
+
+ fpi = &fpi0;
+ if (rounding != FPI_Round_near) {
+ fpi1 = fpi0;
+ fpi1.rounding = rounding;
+ fpi = &fpi1;
+ }
+ k = strtodg(s, sp, fpi, &exp, bits);
+ ULtodd((ULong*)dd, bits, exp, k);
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtorf.c b/lib/libc/gdtoa/strtorf.c
new file mode 100644
index 00000000000..46b0ba2e424
--- /dev/null
+++ b/lib/libc/gdtoa/strtorf.c
@@ -0,0 +1,89 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ void
+#ifdef KR_headers
+ULtof(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
+#else
+ULtof(ULong *L, ULong *bits, Long exp, int k)
+#endif
+{
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ *L = 0;
+ break;
+
+ case STRTOG_Normal:
+ case STRTOG_NaNbits:
+ L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23;
+ break;
+
+ case STRTOG_Denormal:
+ L[0] = bits[0];
+ break;
+
+ case STRTOG_Infinite:
+ L[0] = 0x7f800000;
+ break;
+
+ case STRTOG_NaN:
+ L[0] = f_QNAN;
+ }
+ if (k & STRTOG_Neg)
+ L[0] |= 0x80000000L;
+ }
+
+ int
+#ifdef KR_headers
+strtorf(s, sp, rounding, f) CONST char *s; char **sp; int rounding; float *f;
+#else
+strtorf(CONST char *s, char **sp, int rounding, float *f)
+#endif
+{
+ static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI };
+ FPI *fpi, fpi1;
+ ULong bits[1];
+ Long exp;
+ int k;
+
+ fpi = &fpi0;
+ if (rounding != FPI_Round_near) {
+ fpi1 = fpi0;
+ fpi1.rounding = rounding;
+ fpi = &fpi1;
+ }
+ k = strtodg(s, sp, fpi, &exp, bits);
+ ULtof((ULong*)f, bits, exp, k);
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtorx.c b/lib/libc/gdtoa/strtorx.c
new file mode 100644
index 00000000000..23f721aa293
--- /dev/null
+++ b/lib/libc/gdtoa/strtorx.c
@@ -0,0 +1,119 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+#undef _0
+#undef _1
+
+/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
+
+#ifdef IEEE_MC68k
+#define _0 0
+#define _1 1
+#define _2 2
+#define _3 3
+#define _4 4
+#endif
+#ifdef IEEE_8087
+#define _0 4
+#define _1 3
+#define _2 2
+#define _3 1
+#define _4 0
+#endif
+
+ void
+#ifdef KR_headers
+ULtox(L, bits, exp, k) UShort *L; ULong *bits; Long exp; int k;
+#else
+ULtox(UShort *L, ULong *bits, Long exp, int k)
+#endif
+{
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ L[0] = L[1] = L[2] = L[3] = L[4] = 0;
+ break;
+
+ case STRTOG_Denormal:
+ L[_0] = 0;
+ goto normal_bits;
+
+ case STRTOG_Normal:
+ case STRTOG_NaNbits:
+ L[_0] = exp + 0x3fff + 63;
+ normal_bits:
+ L[_4] = (UShort)bits[0];
+ L[_3] = (UShort)(bits[0] >> 16);
+ L[_2] = (UShort)bits[1];
+ L[_1] = (UShort)(bits[1] >> 16);
+ break;
+
+ case STRTOG_Infinite:
+ L[_0] = 0x7fff;
+ L[_1] = L[_2] = L[_3] = L[_4] = 0;
+ break;
+
+ case STRTOG_NaN:
+ L[0] = ldus_QNAN0;
+ L[1] = ldus_QNAN1;
+ L[2] = ldus_QNAN2;
+ L[3] = ldus_QNAN3;
+ L[4] = ldus_QNAN4;
+ }
+ if (k & STRTOG_Neg)
+ L[_0] |= 0x8000;
+ }
+
+ int
+#ifdef KR_headers
+strtorx(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L;
+#else
+strtorx(CONST char *s, char **sp, int rounding, void *L)
+#endif
+{
+ static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
+ FPI *fpi, fpi1;
+ ULong bits[2];
+ Long exp;
+ int k;
+
+ fpi = &fpi0;
+ if (rounding != FPI_Round_near) {
+ fpi1 = fpi0;
+ fpi1.rounding = rounding;
+ fpi = &fpi1;
+ }
+ k = strtodg(s, sp, fpi, &exp, bits);
+ ULtox((UShort*)L, bits, exp, k);
+ return k;
+ }
diff --git a/lib/libc/gdtoa/strtorxL.c b/lib/libc/gdtoa/strtorxL.c
new file mode 100644
index 00000000000..ff62a61302a
--- /dev/null
+++ b/lib/libc/gdtoa/strtorxL.c
@@ -0,0 +1,107 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 2000 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+#undef _0
+#undef _1
+
+/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
+
+#ifdef IEEE_MC68k
+#define _0 0
+#define _1 1
+#define _2 2
+#endif
+#ifdef IEEE_8087
+#define _0 2
+#define _1 1
+#define _2 0
+#endif
+
+ void
+#ifdef KR_headers
+ULtoxL(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
+#else
+ULtoxL(ULong *L, ULong *bits, Long exp, int k)
+#endif
+{
+ switch(k & STRTOG_Retmask) {
+ case STRTOG_NoNumber:
+ case STRTOG_Zero:
+ L[0] = L[1] = L[2] = 0;
+ break;
+
+ case STRTOG_Normal:
+ case STRTOG_Denormal:
+ case STRTOG_NaNbits:
+ L[_0] = (exp + 0x3fff + 63) << 16;
+ L[_1] = bits[1];
+ L[_2] = bits[0];
+ break;
+
+ case STRTOG_Infinite:
+ L[_0] = 0x7fff << 16;
+ L[_1] = L[_2] = 0;
+ break;
+
+ case STRTOG_NaN:
+ L[0] = ld_QNAN0;
+ L[1] = ld_QNAN1;
+ L[2] = ld_QNAN2;
+ }
+ if (k & STRTOG_Neg)
+ L[_0] |= 0x80000000L;
+ }
+
+ int
+#ifdef KR_headers
+strtorxL(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L;
+#else
+strtorxL(CONST char *s, char **sp, int rounding, void *L)
+#endif
+{
+ static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
+ FPI *fpi, fpi1;
+ ULong bits[2];
+ Long exp;
+ int k;
+
+ fpi = &fpi0;
+ if (rounding != FPI_Round_near) {
+ fpi1 = fpi0;
+ fpi1.rounding = rounding;
+ fpi = &fpi1;
+ }
+ k = strtodg(s, sp, fpi, &exp, bits);
+ ULtoxL((ULong*)L, bits, exp, k);
+ return k;
+ }
diff --git a/lib/libc/gdtoa/sum.c b/lib/libc/gdtoa/sum.c
new file mode 100644
index 00000000000..dc0c88bcfab
--- /dev/null
+++ b/lib/libc/gdtoa/sum.c
@@ -0,0 +1,98 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ Bigint *
+#ifdef KR_headers
+sum(a, b) Bigint *a; Bigint *b;
+#else
+sum(Bigint *a, Bigint *b)
+#endif
+{
+ Bigint *c;
+ ULong carry, *xc, *xa, *xb, *xe, y;
+#ifdef Pack_32
+ ULong z;
+#endif
+
+ if (a->wds < b->wds) {
+ c = b; b = a; a = c;
+ }
+ c = Balloc(a->k);
+ c->wds = a->wds;
+ carry = 0;
+ xa = a->x;
+ xb = b->x;
+ xc = c->x;
+ xe = xc + b->wds;
+#ifdef Pack_32
+ do {
+ y = (*xa & 0xffff) + (*xb & 0xffff) + carry;
+ carry = (y & 0x10000) >> 16;
+ z = (*xa++ >> 16) + (*xb++ >> 16) + carry;
+ carry = (z & 0x10000) >> 16;
+ Storeinc(xc, z, y);
+ }
+ while(xc < xe);
+ xe += a->wds - b->wds;
+ while(xc < xe) {
+ y = (*xa & 0xffff) + carry;
+ carry = (y & 0x10000) >> 16;
+ z = (*xa++ >> 16) + carry;
+ carry = (z & 0x10000) >> 16;
+ Storeinc(xc, z, y);
+ }
+#else
+ do {
+ y = *xa++ + *xb++ + carry;
+ carry = (y & 0x10000) >> 16;
+ *xc++ = y & 0xffff;
+ }
+ while(xc < xe);
+ xe += a->wds - b->wds;
+ while(xc < xe) {
+ y = *xa++ + carry;
+ carry = (y & 0x10000) >> 16;
+ *xc++ = y & 0xffff;
+ }
+#endif
+ if (carry) {
+ if (c->wds == c->maxwds) {
+ b = Balloc(c->k + 1);
+ Bcopy(b, c);
+ Bfree(c);
+ c = b;
+ }
+ c->x[c->wds++] = 1;
+ }
+ return c;
+ }
diff --git a/lib/libc/gdtoa/ulp.c b/lib/libc/gdtoa/ulp.c
new file mode 100644
index 00000000000..7810a5c8e64
--- /dev/null
+++ b/lib/libc/gdtoa/ulp.c
@@ -0,0 +1,70 @@
+/****************************************************************
+
+The author of this software is David M. Gay.
+
+Copyright (C) 1998, 1999 by Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, 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.
+
+****************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to "."). */
+
+#include "gdtoaimp.h"
+
+ double
+ulp
+#ifdef KR_headers
+ (x) double x;
+#else
+ (double x)
+#endif
+{
+ Long L;
+ double a;
+
+ L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Sudden_Underflow
+ if (L > 0) {
+#endif
+#ifdef IBM
+ L |= Exp_msk1 >> 4;
+#endif
+ word0(a) = L;
+ word1(a) = 0;
+#ifndef Sudden_Underflow
+ }
+ else {
+ L = -L >> Exp_shift;
+ if (L < Exp_shift) {
+ word0(a) = 0x80000 >> L;
+ word1(a) = 0;
+ }
+ else {
+ word0(a) = 0;
+ L -= Exp_shift;
+ word1(a) = L >= 31 ? 1 : 1 << 31 - L;
+ }
+ }
+#endif
+ return a;
+ }
diff --git a/lib/libc/gen/fpclassify.c b/lib/libc/gen/fpclassify.c
index f126935961f..10a0904637b 100644
--- a/lib/libc/gen/fpclassify.c
+++ b/lib/libc/gen/fpclassify.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fpclassify.c,v 1.1 2008/07/24 09:31:07 martynas Exp $ */
+/* $OpenBSD: fpclassify.c,v 1.2 2008/09/07 20:36:08 martynas Exp $ */
/*
* Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
*
@@ -62,29 +62,3 @@ __fpclassifyf(float f)
return FP_NORMAL;
}
-
-#if 0 /* XXX */
-int
-__fpclassifyl(long double e)
-{
- struct ieee_ext *p = (struct ieee_ext *)&e;
-
- if (p->ext_exp == 0) {
- if (p->ext_frach == 0 && p->ext_fracl == 0)
- return FP_ZERO;
- else
- return FP_SUBNORMAL;
- }
-
- p->ext_frach &= ~0x80000000; /* clear sign bit */
-
- if (p->ext_exp == EXT_EXP_INFNAN) {
- if (p->ext_frach == 0 && p->ext_fracl == 0)
- return FP_INFINITE;
- else
- return FP_NAN;
- }
-
- return FP_NORMAL;
-}
-#endif /* XXX */
diff --git a/lib/libc/gen/isfinite.c b/lib/libc/gen/isfinite.c
index 0af06c60696..0e0e8844492 100644
--- a/lib/libc/gen/isfinite.c
+++ b/lib/libc/gen/isfinite.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isfinite.c,v 1.1 2008/07/24 09:31:07 martynas Exp $ */
+/* $OpenBSD: isfinite.c,v 1.2 2008/09/07 20:36:08 martynas Exp $ */
/*
* Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
*
@@ -33,13 +33,3 @@ __isfinitef(float f)
return (p->sng_exp != SNG_EXP_INFNAN);
}
-
-#if 0 /* XXX */
-int
-__isfinitel(long double e)
-{
- struct ieee_ext *p = (struct ieee_ext *)&e;
-
- return (p->ext_exp != EXT_EXP_INFNAN);
-}
-#endif /* XXX */
diff --git a/lib/libc/gen/isinf.c b/lib/libc/gen/isinf.c
index f8dae2a5402..9af1ca9657b 100644
--- a/lib/libc/gen/isinf.c
+++ b/lib/libc/gen/isinf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isinf.c,v 1.1 2008/07/24 09:31:07 martynas Exp $ */
+/* $OpenBSD: isinf.c,v 1.2 2008/09/07 20:36:08 martynas Exp $ */
/*
* Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
*
@@ -34,16 +34,3 @@ isinff(float f)
return (p->sng_exp == SNG_EXP_INFNAN && p->sng_frac == 0);
}
-
-#if 0 /* XXX */
-int
-__isinfl(long double e)
-{
- struct ieee_ext *p = (struct ieee_ext *)&e;
-
- p->ext_frach &= ~0x80000000; /* clear sign bit */
-
- return (p->ext_exp == EXT_EXP_INFNAN &&
- p->ext_frach == 0 && p->ext_fracl == 0);
-}
-#endif /* XXX */
diff --git a/lib/libc/gen/isnan.c b/lib/libc/gen/isnan.c
index 29566c812b7..116360369ed 100644
--- a/lib/libc/gen/isnan.c
+++ b/lib/libc/gen/isnan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isnan.c,v 1.1 2008/07/24 09:31:07 martynas Exp $ */
+/* $OpenBSD: isnan.c,v 1.2 2008/09/07 20:36:08 martynas Exp $ */
/*
* Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
*
@@ -34,16 +34,3 @@ isnanf(float f)
return (p->sng_exp == SNG_EXP_INFNAN && p->sng_frac != 0);
}
-
-#if 0 /* XXX */
-int
-__isnanl(long double e)
-{
- struct ieee_ext *p = (struct ieee_ext *)&e;
-
- p->ext_frach &= ~0x80000000; /* clear sign bit */
-
- return (p->ext_exp == EXT_EXP_INFNAN &&
- (p->ext_frach != 0 || p->ext_fracl != 0));
-}
-#endif /* XXX */
diff --git a/lib/libc/gen/isnormal.c b/lib/libc/gen/isnormal.c
index e35bddc2c35..8879218e7fe 100644
--- a/lib/libc/gen/isnormal.c
+++ b/lib/libc/gen/isnormal.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isnormal.c,v 1.1 2008/07/24 09:31:07 martynas Exp $ */
+/* $OpenBSD: isnormal.c,v 1.2 2008/09/07 20:36:08 martynas Exp $ */
/*
* Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
*
@@ -33,13 +33,3 @@ __isnormalf(float f)
return (p->sng_exp != 0 && p->sng_exp != SNG_EXP_INFNAN);
}
-
-#if 0 /* XXX */
-int
-__isnormall(long double e)
-{
- struct ieee_ext *p = (struct ieee_ext *)&e;
-
- return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN);
-}
-#endif /* XXX */
diff --git a/lib/libc/stdio/floatio.h b/lib/libc/stdio/floatio.h
index 20f9801e466..97690308442 100644
--- a/lib/libc/stdio/floatio.h
+++ b/lib/libc/stdio/floatio.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: floatio.h,v 1.3 2003/06/02 20:18:37 millert Exp $ */
+/* $OpenBSD: floatio.h,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*-
* Copyright (c) 1990, 1993
@@ -40,3 +40,19 @@
#define MAXEXP 308
/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
#define MAXFRACT 39
+
+/*
+ * MAXEXPDIG is the maximum number of decimal digits needed to store a
+ * floating point exponent in the largest supported format. It should
+ * be ceil(log10(LDBL_MAX_10_EXP)) or, if hexadecimal floating point
+ * conversions are supported, ceil(log10(LDBL_MAX_EXP)). But since it
+ * is presently never greater than 5 in practice, we fudge it.
+ */
+#define MAXEXPDIG 6
+#if LDBL_MAX_EXP > 999999
+#error "floating point buffers too small"
+#endif
+
+char *__hdtoa(double, const char *, int, int *, int *, char **);
+char *__hldtoa(long double, const char *, int, int *, int *, char **);
+char *__ldtoa(long double *, int, int, int *, int *, char **);
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index 9e651cab145..59af7eb7a22 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfprintf.c,v 1.51 2008/08/27 00:40:38 martynas Exp $ */
+/* $OpenBSD: vfprintf.c,v 1.52 2008/09/07 20:36:08 martynas Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -140,22 +140,27 @@ __sbprintf(FILE *fp, const char *fmt, va_list ap)
#ifdef FLOATING_POINT
+#include <float.h>
#include <locale.h>
#include <math.h>
#include "floatio.h"
-#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
#define DEFPREC 6
extern char *__dtoa(double, int, int, int *, int *, char **);
extern void __freedtoa(char *);
-static char *cvt(double, int, int, int *, int *, int, int *);
static int exponent(char *, int, int);
-
-#else /* no FLOATING_POINT */
-#define BUF 40
#endif /* FLOATING_POINT */
+/*
+ * The size of the buffer we use as scratch space for integer
+ * conversions, among other things. Technically, we would need the
+ * most space for base 10 conversions with thousands' grouping
+ * characters between each pair of digits. 100 bytes is a
+ * conservative overestimate even for a 128-bit uintmax_t.
+ */
+#define BUF 100
+
#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
@@ -170,7 +175,6 @@ static int exponent(char *, int, int);
* Flags used during conversion.
*/
#define ALT 0x0001 /* alternate form */
-#define HEXPREFIX 0x0002 /* add 0x or 0X prefix */
#define LADJUST 0x0004 /* left adjustment */
#define LONGDBL 0x0008 /* long double; unimplemented */
#define LONGINT 0x0010 /* long integer */
@@ -194,32 +198,52 @@ vfprintf(FILE *fp, const char *fmt0, __va_list ap)
int flags; /* flags as above */
int ret; /* return value accumulator */
int width; /* width from format (%8d), or 0 */
- int prec; /* precision from format (%.3d), or -1 */
+ int prec; /* precision from format; <0 for N/A */
char sign; /* sign prefix (' ', '+', '-', or \0) */
wchar_t wc;
mbstate_t ps;
#ifdef FLOATING_POINT
+ /*
+ * We can decompose the printed representation of floating
+ * point numbers into several parts, some of which may be empty:
+ *
+ * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
+ * A B ---C--- D E F
+ *
+ * A: 'sign' holds this value if present; '\0' otherwise
+ * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
+ * C: cp points to the string MMMNNN. Leading and trailing
+ * zeros are not in the string and must be added.
+ * D: expchar holds this character; '\0' if no exponent, e.g. %f
+ * F: at least two digits for decimal, at least one digit for hex
+ */
char *decimal_point = localeconv()->decimal_point;
- int softsign; /* temporary negative sign for floats */
- double _double; /* double precision arguments %[eEfFgG] */
+ int signflag; /* true if float is negative */
+ union { /* floating point arguments %[aAeEfFgG] */
+ double dbl;
+ long double ldbl;
+ } fparg;
int expt; /* integer value of exponent */
+ char expchar; /* exponent character: [eEpP\0] */
+ char *dtoaend; /* pointer to end of converted digits */
int expsize; /* character count for expstr */
- int ndig; /* actual number of digits returned by cvt */
- char expstr[7]; /* buffer for exponent string */
+ int lead; /* sig figs before decimal or group sep */
+ int ndig; /* actual number of digits returned by dtoa */
+ char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */
char *dtoaresult = NULL;
#endif
uintmax_t _umax; /* integer arguments %[diouxX] */
- enum { OCT, DEC, HEX } base;/* base for %[diouxX] conversion */
+ enum { OCT, DEC, HEX } base; /* base for %[diouxX] conversion */
int dprec; /* a copy of prec if %[diouxX], 0 otherwise */
int realsz; /* field size expanded by dprec */
int size; /* size of converted field or string */
- char *xdigs; /* digits for %[xX] conversion */
+ const char *xdigs; /* digits for %[xX] conversion */
#define NIOV 8
struct __suio uio; /* output information: summary */
struct __siov iov[NIOV];/* ... and individual io vectors */
- char buf[BUF]; /* space for %c, %[diouxX], %[eEfFgG] */
- char ox[2]; /* space for 0x hex-prefix */
+ char buf[BUF]; /* buffer with space for digits of uintmax_t */
+ char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */
union arg *argtable; /* args, built due to positional arg */
union arg statargtable[STATIC_ARG_TBL_SIZE];
size_t argtablesiz;
@@ -237,6 +261,9 @@ vfprintf(FILE *fp, const char *fmt0, __va_list ap)
static char zeroes[PADSIZE] =
{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
+ static const char xdigs_lower[16] = "0123456789abcdef";
+ static const char xdigs_upper[16] = "0123456789ABCDEF";
+
/*
* BEWARE, these `goto error' on error, and PAD uses `n'.
*/
@@ -260,6 +287,14 @@ vfprintf(FILE *fp, const char *fmt0, __va_list ap)
PRINT(with, n); \
} \
} while (0)
+#define PRINTANDPAD(p, ep, len, with) do { \
+ n2 = (ep) - (p); \
+ if (n2 > (len)) \
+ n2 = (len); \
+ if (n2 > 0) \
+ PRINT((p), n2); \
+ PAD((len) - (n2 > 0 ? n2 : 0), (with)); \
+} while(0)
#define FLUSH() do { \
if (uio.uio_resid && __sprint(fp, &uio)) \
goto error; \
@@ -386,6 +421,7 @@ vfprintf(FILE *fp, const char *fmt0, __va_list ap)
width = 0;
prec = -1;
sign = '\0';
+ ox[1] = '\0';
rflag: ch = *fmt++;
reswitch: switch (ch) {
@@ -520,82 +556,122 @@ reswitch: switch (ch) {
base = DEC;
goto number;
#ifdef FLOATING_POINT
+ case 'a':
+ case 'A':
+ if (ch == 'a') {
+ ox[1] = 'x';
+ xdigs = xdigs_lower;
+ expchar = 'p';
+ } else {
+ ox[1] = 'X';
+ xdigs = xdigs_upper;
+ expchar = 'P';
+ }
+ if (prec >= 0)
+ prec++;
+ if (dtoaresult)
+ __freedtoa(dtoaresult);
+ if (flags & LONGDBL) {
+ fparg.ldbl = GETARG(long double);
+ dtoaresult = cp =
+ __hldtoa(fparg.ldbl, xdigs, prec,
+ &expt, &signflag, &dtoaend);
+ } else {
+ fparg.dbl = GETARG(double);
+ dtoaresult = cp =
+ __hdtoa(fparg.dbl, xdigs, prec,
+ &expt, &signflag, &dtoaend);
+ }
+ if (prec < 0)
+ prec = dtoaend - cp;
+ if (expt == INT_MAX)
+ ox[1] = '\0';
+ goto fp_common;
case 'e':
case 'E':
+ expchar = ch;
+ if (prec < 0) /* account for digit before decpt */
+ prec = DEFPREC + 1;
+ else
+ prec++;
+ goto fp_begin;
case 'f':
case 'F':
+ expchar = '\0';
+ goto fp_begin;
case 'g':
case 'G':
- if (prec == -1) {
+ expchar = ch - ('g' - 'e');
+ if (prec == 0)
+ prec = 1;
+fp_begin:
+ if (prec < 0)
prec = DEFPREC;
- } else if ((ch == 'g' || ch == 'G') && prec == 0) {
- prec = 1;
- }
-
+ if (dtoaresult)
+ __freedtoa(dtoaresult);
if (flags & LONGDBL) {
- _double = (double) GETARG(long double);
+ fparg.ldbl = GETARG(long double);
+ dtoaresult = cp =
+ __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
+ &expt, &signflag, &dtoaend);
} else {
- _double = GETARG(double);
- }
-
- /* do this before tricky precision changes */
- if (isinf(_double)) {
- if (_double < 0)
- sign = '-';
- if (ch == 'E' || ch == 'F' || ch == 'G')
- cp = "INF";
- else
- cp = "inf";
- size = 3;
- flags &= ~ZEROPAD;
- break;
- }
- if (isnan(_double)) {
- if (ch == 'E' || ch == 'F' || ch == 'G')
- cp = "NAN";
- else
- cp = "nan";
- size = 3;
+ fparg.dbl = GETARG(double);
+ dtoaresult = cp =
+ __dtoa(fparg.dbl, expchar ? 2 : 3, prec,
+ &expt, &signflag, &dtoaend);
+ if (expt == 9999)
+ expt = INT_MAX;
+ }
+fp_common:
+ if (signflag)
+ sign = '-';
+ if (expt == INT_MAX) { /* inf or nan */
+ if (*cp == 'N') {
+ cp = (ch >= 'a') ? "nan" : "NAN";
+ sign = '\0';
+ } else
+ cp = (ch >= 'a') ? "inf" : "INF";
+ size = 3;
flags &= ~ZEROPAD;
- break;
- }
-
+ break;
+ }
flags |= FPT;
- if (dtoaresult)
- __freedtoa(dtoaresult);
- dtoaresult = cp = cvt(_double, prec, flags, &softsign,
- &expt, ch, &ndig);
- if (ch == 'g' || ch == 'G') {
- if (expt <= -4 || expt > prec)
- ch = (ch == 'g') ? 'e' : 'E';
- else
- ch = 'g';
- }
- if (ch == 'e' || ch == 'E') { /* 'e' or 'E' fmt */
- --expt;
- expsize = exponent(expstr, expt, ch);
- size = expsize + ndig;
- if (ndig > 1 || flags & ALT)
- ++size;
- } else if (ch == 'f' || ch == 'F') {
- /* 'f' or 'F' fmt */
- if (expt > 0) {
- size = expt;
- if (prec || flags & ALT)
- size += prec + 1;
- } else { /* "0.X" */
- size = prec + 2;
+ ndig = dtoaend - cp;
+ if (ch == 'g' || ch == 'G') {
+ if (expt > -4 && expt <= prec) {
+ /* Make %[gG] smell like %[fF] */
+ expchar = '\0';
+ if (flags & ALT)
+ prec -= expt;
+ else
+ prec = ndig - expt;
+ if (prec < 0)
+ prec = 0;
+ } else {
+ /*
+ * Make %[gG] smell like %[eE], but
+ * trim trailing zeroes if no # flag.
+ */
+ if (!(flags & ALT))
+ prec = ndig;
}
- } else if (expt >= ndig) { /* fixed g fmt */
- size = expt;
- if (flags & ALT)
- ++size;
+ }
+ if (expchar) {
+ expsize = exponent(expstr, expt - 1, expchar);
+ size = expsize + prec;
+ if (prec > 1 || flags & ALT)
+ ++size;
} else {
- size = ndig + (expt > 0 ? 1 : 2 - expt);
+ /* space for digits before decimal point */
+ if (expt > 0)
+ size = expt;
+ else /* "0" */
+ size = 1;
+ /* space for decimal pt and following digits */
+ if (prec || flags & ALT)
+ size += prec + 1;
+ lead = expt;
}
-
- if (softsign)
- sign = '-';
break;
#endif /* FLOATING_POINT */
case 'n':
@@ -634,9 +710,8 @@ reswitch: switch (ch) {
/* NOSTRICT */
_umax = (u_long)GETARG(void *);
base = HEX;
- xdigs = "0123456789abcdef";
- flags |= HEXPREFIX;
- ch = 'x';
+ xdigs = xdigs_lower;
+ ox[1] = 'x';
goto nosign;
case 's':
if ((cp = GETARG(char *)) == NULL)
@@ -667,15 +742,15 @@ reswitch: switch (ch) {
base = DEC;
goto nosign;
case 'X':
- xdigs = "0123456789ABCDEF";
+ xdigs = xdigs_upper;
goto hex;
case 'x':
- xdigs = "0123456789abcdef";
+ xdigs = xdigs_lower;
hex: _umax = UARG();
base = HEX;
/* leading 0x/X only if non-zero */
if (flags & ALT && _umax != 0)
- flags |= HEXPREFIX;
+ ox[1] = ch;
/* unsigned conversions */
nosign: sign = '\0';
@@ -733,6 +808,8 @@ number: if ((dprec = prec) >= 0)
}
}
size = buf + BUF - cp;
+ if (size > BUF) /* should never happen */
+ abort();
skipsize:
break;
default: /* "%?" prints ?, unless ? is NUL */
@@ -763,7 +840,7 @@ number: if ((dprec = prec) >= 0)
realsz = dprec > size ? dprec : size;
if (sign)
realsz++;
- else if (flags & HEXPREFIX)
+ if (ox[1])
realsz+= 2;
/* right-adjusting blank padding */
@@ -771,11 +848,10 @@ number: if ((dprec = prec) >= 0)
PAD(width - realsz, blanks);
/* prefix */
- if (sign) {
+ if (sign)
PRINT(&sign, 1);
- } else if (flags & HEXPREFIX) {
+ if (ox[1]) { /* ox[1] is either x, X, or \0 */
ox[0] = '0';
- ox[1] = ch;
PRINT(ox, 2);
}
@@ -791,41 +867,28 @@ number: if ((dprec = prec) >= 0)
if ((flags & FPT) == 0) {
PRINT(cp, size);
} else { /* glue together f_p fragments */
- if (ch >= 'f' || ch == 'F') { /* 'f', 'g' or 'F' */
- if (_double == 0) {
- /* kludge for __dtoa irregularity */
- PRINT("0", 1);
- if (expt < ndig || (flags & ALT) != 0) {
+ if (!expchar) { /* %[fF] or sufficiently short %[gG] */
+ if (expt <= 0) {
+ PRINT(zeroes, 1);
+ if (prec || flags & ALT)
PRINT(decimal_point, 1);
- PAD(ndig - 1, zeroes);
- }
- } else if (expt <= 0) {
- PRINT("0", 1);
- PRINT(decimal_point, 1);
PAD(-expt, zeroes);
- PRINT(cp, ndig);
- } else if (expt >= ndig) {
- PRINT(cp, ndig);
- PAD(expt - ndig, zeroes);
- if (flags & ALT)
+ /* already handled initial 0's */
+ prec += expt;
+ } else {
+ PRINTANDPAD(cp, dtoaend, lead, zeroes);
+ cp += lead;
+ if (prec || flags & ALT)
PRINT(".", 1);
- } else {
- PRINT(cp, expt);
- cp += expt;
- PRINT(".", 1);
- PRINT(cp, ndig-expt);
}
- } else { /* 'e' or 'E' */
- if (ndig > 1 || flags & ALT) {
- ox[0] = *cp++;
- ox[1] = '.';
- PRINT(ox, 2);
- if (_double) {
- PRINT(cp, ndig-1);
- } else {/* 0.[0..] */
- /* __dtoa irregularity */
- PAD(ndig - 1, zeroes);
- }
+ PRINTANDPAD(cp, dtoaend, prec, zeroes);
+ } else { /* %[eE] or sufficiently long %[gG] */
+ if (prec > 1 || flags & ALT) {
+ buf[0] = *cp++;
+ buf[1] = '.';
+ PRINT(buf, 2);
+ PRINT(cp, ndig-1);
+ PAD(prec - ndig, zeroes);
} else { /* XeYYY */
PRINT(cp, 1);
}
@@ -1076,6 +1139,8 @@ reswitch: switch (ch) {
ADDSARG();
break;
#ifdef FLOATING_POINT
+ case 'a':
+ case 'A':
case 'e':
case 'E':
case 'f':
@@ -1266,49 +1331,11 @@ __grow_type_table(unsigned char **typetable, int *tablesize)
#ifdef FLOATING_POINT
-
-static char *
-cvt(double value, int ndigits, int flags, int *sign, int *decpt, int ch,
- int *length)
-{
- int mode;
- char *digits, *bp, *rve;
-
- if (ch == 'f' || ch == 'F') {
- mode = 3; /* ndigits after the decimal point */
- } else {
- /* To obtain ndigits after the decimal point for the 'e'
- * and 'E' formats, round to ndigits + 1 significant
- * figures.
- */
- if (ch == 'e' || ch == 'E') {
- ndigits++;
- }
- mode = 2; /* ndigits significant digits */
- }
-
- digits = __dtoa(value, mode, ndigits, decpt, sign, &rve);
- if ((ch != 'g' && ch != 'G') || flags & ALT) {/* Print trailing zeros */
- bp = digits + ndigits;
- if (ch == 'f' || ch == 'F') {
- if (*digits == '0' && value)
- *decpt = -ndigits + 1;
- bp += *decpt;
- }
- if (value == 0) /* kludge for __dtoa irregularity */
- rve = bp;
- while (rve < bp)
- *rve++ = '0';
- }
- *length = rve - digits;
- return (digits);
-}
-
static int
exponent(char *p0, int exp, int fmtch)
{
char *p, *t;
- char expbuf[MAXEXP];
+ char expbuf[MAXEXPDIG];
p = p0;
*p++ = fmtch;
@@ -1317,16 +1344,23 @@ exponent(char *p0, int exp, int fmtch)
*p++ = '-';
} else
*p++ = '+';
- t = expbuf + MAXEXP;
+ t = expbuf + MAXEXPDIG;
if (exp > 9) {
do {
*--t = to_char(exp % 10);
} while ((exp /= 10) > 9);
*--t = to_char(exp);
- for (; t < expbuf + MAXEXP; *p++ = *t++)
+ for (; t < expbuf + MAXEXPDIG; *p++ = *t++)
/* nothing */;
} else {
- *p++ = '0';
+ /*
+ * Exponents for decimal floating point conversions
+ * (%[eEgG]) must be at least two characters long,
+ * whereas exponents for hexadecimal conversions can
+ * be only one character long.
+ */
+ if (fmtch == 'e' || fmtch == 'E')
+ *p++ = '0';
*p++ = to_char(exp);
}
return (p - p0);
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
index 09db4ce7935..ab8bd39f07b 100644
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.39 2008/08/22 17:14:56 otto Exp $
+# $OpenBSD: Makefile.inc,v 1.40 2008/09/07 20:36:08 martynas Exp $
# stdlib sources
.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/stdlib
@@ -7,7 +7,7 @@ SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \
cfree.c exit.c ecvt.c gcvt.c getenv.c getopt_long.c \
getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c l64a.c llabs.c \
lldiv.c lsearch.c malloc.c merge.c putenv.c qsort.c radixsort.c rand.c \
- random.c realpath.c setenv.c strtoimax.c strtod.c strtof.c strtol.c \
+ random.c realpath.c setenv.c strtoimax.c strtol.c \
strtoll.c strtonum.c strtoul.c strtoull.c strtoumax.c system.c \
tfind.c tsearch.c _rand48.c drand48.c erand48.c jrand48.c lcong48.c \
lrand48.c mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c _Exit.c
diff --git a/lib/libc/stdlib/strtod.c b/lib/libc/stdlib/strtod.c
deleted file mode 100644
index 4dc3d65a267..00000000000
--- a/lib/libc/stdlib/strtod.c
+++ /dev/null
@@ -1,2459 +0,0 @@
-/* $OpenBSD: strtod.c,v 1.30 2006/10/30 18:30:52 deraadt Exp $ */
-/****************************************************************
- *
- * The author of this software is David M. Gay.
- *
- * Copyright (c) 1991 by AT&T.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose without fee is hereby granted, provided that this entire notice
- * is included in all copies of any software which is or includes a copy
- * or modification of this software and in all copies of the supporting
- * documentation for such software.
- *
- * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
- * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
- * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
- *
- ***************************************************************/
-
-/* Please send bug reports to
- David M. Gay
- AT&T Bell Laboratories, Room 2C-463
- 600 Mountain Avenue
- Murray Hill, NJ 07974-2070
- U.S.A.
- dmg@research.att.com or research!dmg
- */
-
-/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
- *
- * This strtod returns a nearest machine number to the input decimal
- * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
- * broken by the IEEE round-even rule. Otherwise ties are broken by
- * biased rounding (add half and chop).
- *
- * Inspired loosely by William D. Clinger's paper "How to Read Floating
- * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
- *
- * Modifications:
- *
- * 1. We only require IEEE, IBM, or VAX double-precision
- * arithmetic (not IEEE double-extended).
- * 2. We get by with floating-point arithmetic in a case that
- * Clinger missed -- when we're computing d * 10^n
- * for a small integer d and the integer n is not too
- * much larger than 22 (the maximum integer k for which
- * we can represent 10^k exactly), we may be able to
- * compute (d*10^k) * 10^(e-k) with just one roundoff.
- * 3. Rather than a bit-at-a-time adjustment of the binary
- * result in the hard case, we use floating-point
- * arithmetic to determine the adjustment to within
- * one bit; only in really hard cases do we need to
- * compute a second residual.
- * 4. Because of 3., we don't need a large table of powers of 10
- * for ten-to-e (just some small tables, e.g. of 10^k
- * for 0 <= k <= 22).
- */
-
-/*
- * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least
- * significant byte has the lowest address.
- * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most
- * significant byte has the lowest address.
- * #define Long int on machines with 32-bit ints and 64-bit longs.
- * #define Sudden_Underflow for IEEE-format machines without gradual
- * underflow (i.e., that flush to zero on underflow).
- * #define IBM for IBM mainframe-style floating-point arithmetic.
- * #define VAX for VAX-style floating-point arithmetic.
- * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
- * #define No_leftright to omit left-right logic in fast floating-point
- * computation of dtoa.
- * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
- * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
- * that use extended-precision instructions to compute rounded
- * products and quotients) with IBM.
- * #define ROUND_BIASED for IEEE-format with biased rounding.
- * #define Inaccurate_Divide for IEEE-format with correctly rounded
- * products but inaccurate quotients, e.g., for Intel i860.
- * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision
- * integer arithmetic. Whether this speeds things up or slows things
- * down depends on the machine and the number being converted.
- * #define Bad_float_h if your system lacks a float.h or if it does not
- * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
- * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
- * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
- * if memory is available and otherwise does something you deem
- * appropriate. If MALLOC is undefined, malloc will be invoked
- * directly -- and assumed always to succeed.
- */
-
-#include <sys/types.h>
-#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
- defined(__mips__) || defined(__mips64__) || defined(__ns32k__) || \
- defined(__alpha__) || defined(__powerpc__) || defined(__m88k__) || \
- defined(__hppa__) || defined(__amd64__) || defined(__sh__) || \
- defined(__sparc64__) || \
- (defined(__arm__) && defined(__VFP_FP__))
-
-#if BYTE_ORDER == BIG_ENDIAN
-#define IEEE_BIG_ENDIAN
-#else
-#define IEEE_LITTLE_ENDIAN
-#endif
-#endif
-
-#if defined(__arm__) && !defined(__VFP_FP__)
-/*
- * Although the CPU is little endian the FP has different
- * byte and word endianness. The byte order is still little endian
- * but the word order is big endian.
- */
-#define IEEE_BIG_ENDIAN
-#endif
-
-#ifdef __vax__
-#define VAX
-#endif
-
-#define Long int32_t
-#define ULong u_int32_t
-
-#ifdef DEBUG
-#include "stdio.h"
-#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
-#endif
-
-#include "thread_private.h"
-
-_THREAD_PRIVATE_KEY(dtoa);
-_THREAD_PRIVATE_KEY(pow5mult);
-
-#ifdef __cplusplus
-#include "malloc.h"
-#include "memory.h"
-#else
-#include "stdlib.h"
-#include "string.h"
-#include "locale.h"
-#endif
-
-#ifdef MALLOC
-extern void *MALLOC(size_t);
-#else
-#define MALLOC malloc
-#endif
-
-#include "ctype.h"
-#include "errno.h"
-
-#ifdef Bad_float_h
-#ifdef IEEE_BIG_ENDIAN
-#define IEEE_ARITHMETIC
-#endif
-#ifdef IEEE_LITTLE_ENDIAN
-#define IEEE_ARITHMETIC
-#endif
-
-#ifdef IEEE_ARITHMETIC
-#define DBL_DIG 15
-#define DBL_MAX_10_EXP 308
-#define DBL_MAX_EXP 1024
-#define FLT_RADIX 2
-#define FLT_ROUNDS 1
-#define DBL_MAX 1.7976931348623157e+308
-#endif
-
-#ifdef IBM
-#define DBL_DIG 16
-#define DBL_MAX_10_EXP 75
-#define DBL_MAX_EXP 63
-#define FLT_RADIX 16
-#define FLT_ROUNDS 0
-#define DBL_MAX 7.2370055773322621e+75
-#endif
-
-#ifdef VAX
-#define DBL_DIG 16
-#define DBL_MAX_10_EXP 38
-#define DBL_MAX_EXP 127
-#define FLT_RADIX 2
-#define FLT_ROUNDS 1
-#define DBL_MAX 1.7014118346046923e+38
-#endif
-
-#ifndef LONG_MAX
-#define LONG_MAX 2147483647
-#endif
-#else
-#include "float.h"
-#endif
-#ifndef __MATH_H__
-#include "math.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef CONST
-#define CONST const
-#endif
-
-#ifdef Unsigned_Shifts
-#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
-#else
-#define Sign_Extend(a,b) /*no-op*/
-#endif
-
-#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \
- defined(IBM) != 1
-#error Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or IBM should be defined.
-#endif
-
-typedef union {
- double d;
- ULong ul[2];
-} _double;
-#define value(x) ((x).d)
-#ifdef IEEE_LITTLE_ENDIAN
-#define word0(x) ((x).ul[1])
-#define word1(x) ((x).ul[0])
-#else
-#define word0(x) ((x).ul[0])
-#define word1(x) ((x).ul[1])
-#endif
-
-/* The following definition of Storeinc is appropriate for MIPS processors.
- * An alternative that might be better on some machines is
- * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
- */
-#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__)
-#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
-((unsigned short *)a)[0] = (unsigned short)c, a++)
-#else
-#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
-((unsigned short *)a)[1] = (unsigned short)c, a++)
-#endif
-
-/* #define P DBL_MANT_DIG */
-/* Ten_pmax = floor(P*log(2)/log(5)) */
-/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
-/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
-/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
-
-#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN)
-#define Exp_shift 20
-#define Exp_shift1 20
-#define Exp_msk1 0x100000
-#define Exp_msk11 0x100000
-#define Exp_mask 0x7ff00000
-#define P 53
-#define Bias 1023
-#define IEEE_Arith
-#define Emin (-1022)
-#define Exp_1 0x3ff00000
-#define Exp_11 0x3ff00000
-#define Ebits 11
-#define Frac_mask 0xfffff
-#define Frac_mask1 0xfffff
-#define Ten_pmax 22
-#define Bletch 0x10
-#define Bndry_mask 0xfffff
-#define Bndry_mask1 0xfffff
-#define LSB 1
-#define Sign_bit 0x80000000
-#define Log2P 1
-#define Tiny0 0
-#define Tiny1 1
-#define Quick_max 14
-#define Int_max 14
-#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
-#else
-#undef Sudden_Underflow
-#define Sudden_Underflow
-#ifdef IBM
-#define Exp_shift 24
-#define Exp_shift1 24
-#define Exp_msk1 0x1000000
-#define Exp_msk11 0x1000000
-#define Exp_mask 0x7f000000
-#define P 14
-#define Bias 65
-#define Exp_1 0x41000000
-#define Exp_11 0x41000000
-#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
-#define Frac_mask 0xffffff
-#define Frac_mask1 0xffffff
-#define Bletch 4
-#define Ten_pmax 22
-#define Bndry_mask 0xefffff
-#define Bndry_mask1 0xffffff
-#define LSB 1
-#define Sign_bit 0x80000000
-#define Log2P 4
-#define Tiny0 0x100000
-#define Tiny1 0
-#define Quick_max 14
-#define Int_max 15
-#else /* VAX */
-#define Exp_shift 23
-#define Exp_shift1 7
-#define Exp_msk1 0x80
-#define Exp_msk11 0x800000
-#define Exp_mask 0x7f80
-#define P 56
-#define Bias 129
-#define Exp_1 0x40800000
-#define Exp_11 0x4080
-#define Ebits 8
-#define Frac_mask 0x7fffff
-#define Frac_mask1 0xffff007f
-#define Ten_pmax 24
-#define Bletch 2
-#define Bndry_mask 0xffff007f
-#define Bndry_mask1 0xffff007f
-#define LSB 0x10000
-#define Sign_bit 0x8000
-#define Log2P 1
-#define Tiny0 0x80
-#define Tiny1 0
-#define Quick_max 15
-#define Int_max 15
-#endif
-#endif
-
-#ifndef IEEE_Arith
-#define ROUND_BIASED
-#endif
-
-#ifdef RND_PRODQUOT
-#define rounded_product(a,b) a = rnd_prod(a, b)
-#define rounded_quotient(a,b) a = rnd_quot(a, b)
-extern double rnd_prod(double, double), rnd_quot(double, double);
-#else
-#define rounded_product(a,b) a *= b
-#define rounded_quotient(a,b) a /= b
-#endif
-
-#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
-#define Big1 0xffffffff
-
-#ifndef Just_16
-/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
- * This makes some inner loops simpler and sometimes saves work
- * during multiplications, but it often seems to make things slightly
- * slower. Hence the default is now to store 32 bits per Long.
- */
-#ifndef Pack_32
-#define Pack_32
-#endif
-#endif
-
-#define Kmax 15
-
-#ifdef __cplusplus
-extern "C" double strtod(const char *s00, char **se);
-extern "C" char *__dtoa(double d, int mode, int ndigits,
- int *decpt, int *sign, char **rve);
-#endif
-
- struct
-Bigint {
- struct Bigint *next;
- int k, maxwds, sign, wds;
- ULong x[1];
- };
-
- typedef struct Bigint Bigint;
-
- static Bigint *freelist[Kmax+1];
-
-#define PRIVATE_MEM 2304
-#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
- static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
-
- static Bigint *
-Balloc(int k)
-{
- int x;
- unsigned int len;
- Bigint *rv;
-
- _THREAD_PRIVATE_MUTEX_LOCK(dtoa);
- if ((rv = freelist[k])) {
- freelist[k] = rv->next;
- }
- else {
- x = 1 << k;
- len = (sizeof(Bigint) + (x-1)*sizeof(Long) + sizeof(double) - 1)
- /sizeof(double);
- if (pmem_next - private_mem + len <= PRIVATE_mem) {
- rv = (Bigint *)pmem_next;
- pmem_next += len;
- }
- else
- rv = (Bigint *)MALLOC(len *sizeof(double));
- rv->k = k;
- rv->maxwds = x;
- }
- _THREAD_PRIVATE_MUTEX_UNLOCK(dtoa);
- rv->sign = rv->wds = 0;
- return rv;
- }
-
- static void
-Bfree(Bigint *v)
-{
- if (v) {
- _THREAD_PRIVATE_MUTEX_LOCK(dtoa);
- v->next = freelist[v->k];
- freelist[v->k] = v;
- _THREAD_PRIVATE_MUTEX_UNLOCK(dtoa);
- }
- }
-
-#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
-y->wds*sizeof(Long) + 2*sizeof(int))
-
-/* return value is only used as a simple string, so mis-aligned parts
- * inside the Bigint are not at risk on strict align architectures
- */
- static char *
-rv_alloc(int i)
-{
- int j, k, *r;
-
- j = sizeof(ULong);
- for(k = 0;
- sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
- j <<= 1)
- k++;
- r = (int*)Balloc(k);
- *r = k;
- return (char *)(r+1);
- }
-
- static char *
-nrv_alloc(char *s, char **rve, int n)
-{
- char *rv, *t;
-
- t = rv = rv_alloc(n);
- while((*t = *s++) !=0)
- t++;
- if (rve)
- *rve = t;
- return rv;
- }
-
- void
-__freedtoa(char *s)
-{
- Bigint *b = (Bigint *)((int *)s - 1);
- b->maxwds = 1 << (b->k = *(int*)b);
- Bfree(b);
- }
-
- static Bigint *
-multadd(Bigint *b, int m, int a) /* multiply by m and add a */
-{
- int i, wds;
- ULong *x, y;
-#ifdef Pack_32
- ULong xi, z;
-#endif
- Bigint *b1;
-
- wds = b->wds;
- x = b->x;
- i = 0;
- do {
-#ifdef Pack_32
- xi = *x;
- y = (xi & 0xffff) * m + a;
- z = (xi >> 16) * m + (y >> 16);
- a = (int)(z >> 16);
- *x++ = (z << 16) + (y & 0xffff);
-#else
- y = *x * m + a;
- a = (int)(y >> 16);
- *x++ = y & 0xffff;
-#endif
- }
- while(++i < wds);
- if (a) {
- if (wds >= b->maxwds) {
- b1 = Balloc(b->k+1);
- Bcopy(b1, b);
- Bfree(b);
- b = b1;
- }
- b->x[wds++] = a;
- b->wds = wds;
- }
- return b;
- }
-
- static Bigint *
-s2b(CONST char *s, int nd0, int nd, ULong y9)
-{
- Bigint *b;
- int i, k;
- Long x, y;
-
- x = (nd + 8) / 9;
- for(k = 0, y = 1; x > y; y <<= 1, k++) ;
-#ifdef Pack_32
- b = Balloc(k);
- b->x[0] = y9;
- b->wds = 1;
-#else
- b = Balloc(k+1);
- b->x[0] = y9 & 0xffff;
- b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
-#endif
-
- i = 9;
- if (9 < nd0) {
- s += 9;
- do b = multadd(b, 10, *s++ - '0');
- while(++i < nd0);
- s++;
- }
- else
- s += 10;
- for(; i < nd; i++)
- b = multadd(b, 10, *s++ - '0');
- return b;
- }
-
- static int
-hi0bits(ULong x)
-{
- int k = 0;
-
- if (!(x & 0xffff0000)) {
- k = 16;
- x <<= 16;
- }
- if (!(x & 0xff000000)) {
- k += 8;
- x <<= 8;
- }
- if (!(x & 0xf0000000)) {
- k += 4;
- x <<= 4;
- }
- if (!(x & 0xc0000000)) {
- k += 2;
- x <<= 2;
- }
- if (!(x & 0x80000000)) {
- k++;
- if (!(x & 0x40000000))
- return 32;
- }
- return k;
- }
-
- static int
-lo0bits(ULong *y)
-{
- int k;
- ULong x = *y;
-
- if (x & 7) {
- if (x & 1)
- return 0;
- if (x & 2) {
- *y = x >> 1;
- return 1;
- }
- *y = x >> 2;
- return 2;
- }
- k = 0;
- if (!(x & 0xffff)) {
- k = 16;
- x >>= 16;
- }
- if (!(x & 0xff)) {
- k += 8;
- x >>= 8;
- }
- if (!(x & 0xf)) {
- k += 4;
- x >>= 4;
- }
- if (!(x & 0x3)) {
- k += 2;
- x >>= 2;
- }
- if (!(x & 1)) {
- k++;
- x >>= 1;
- if (!(x & 1))
- return 32;
- }
- *y = x;
- return k;
- }
-
- static Bigint *
-i2b(int i)
-{
- Bigint *b;
-
- b = Balloc(1);
- b->x[0] = i;
- b->wds = 1;
- return b;
- }
-
- static Bigint *
-mult(Bigint *a, Bigint *b)
-{
- Bigint *c;
- int k, wa, wb, wc;
- ULong carry, y, z;
- ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
-#ifdef Pack_32
- ULong z2;
-#endif
-
- if (a->wds < b->wds) {
- c = a;
- a = b;
- b = c;
- }
- k = a->k;
- wa = a->wds;
- wb = b->wds;
- wc = wa + wb;
- if (wc > a->maxwds)
- k++;
- c = Balloc(k);
- for(x = c->x, xa = x + wc; x < xa; x++)
- *x = 0;
- xa = a->x;
- xae = xa + wa;
- xb = b->x;
- xbe = xb + wb;
- xc0 = c->x;
-#ifdef Pack_32
- for(; xb < xbe; xb++, xc0++) {
- if ((y = *xb & 0xffff)) {
- x = xa;
- xc = xc0;
- carry = 0;
- do {
- z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
- carry = z >> 16;
- z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
- carry = z2 >> 16;
- Storeinc(xc, z2, z);
- }
- while(x < xae);
- *xc = carry;
- }
- if ((y = *xb >> 16)) {
- x = xa;
- xc = xc0;
- carry = 0;
- z2 = *xc;
- do {
- z = (*x & 0xffff) * y + (*xc >> 16) + carry;
- carry = z >> 16;
- Storeinc(xc, z, z2);
- z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
- carry = z2 >> 16;
- }
- while(x < xae);
- *xc = z2;
- }
- }
-#else
- for(; xb < xbe; xc0++) {
- if (y = *xb++) {
- x = xa;
- xc = xc0;
- carry = 0;
- do {
- z = *x++ * y + *xc + carry;
- carry = z >> 16;
- *xc++ = z & 0xffff;
- }
- while(x < xae);
- *xc = carry;
- }
- }
-#endif
- for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
- c->wds = wc;
- return c;
- }
-
- static Bigint *p5s;
-
- static Bigint *
-pow5mult(Bigint *b, int k)
-{
- Bigint *b1, *p5, *p51;
- int i;
- static int p05[3] = { 5, 25, 125 };
-
- if ((i = k & 3))
- b = multadd(b, p05[i-1], 0);
-
- if (!(k >>= 2))
- return b;
- if (!(p5 = p5s)) {
- /* first time */
- _THREAD_PRIVATE_MUTEX_LOCK(pow5mult);
- p5 = p5s = i2b(625);
- p5->next = 0;
- _THREAD_PRIVATE_MUTEX_UNLOCK(pow5mult);
- }
- for(;;) {
- if (k & 1) {
- b1 = mult(b, p5);
- Bfree(b);
- b = b1;
- }
- if (!(k >>= 1))
- break;
- if (!(p51 = p5->next)) {
- _THREAD_PRIVATE_MUTEX_LOCK(pow5mult);
- if (!(p51 = p5->next)) {
- p51 = p5->next = mult(p5,p5);
- p51->next = 0;
- }
- _THREAD_PRIVATE_MUTEX_UNLOCK(pow5mult);
- }
- p5 = p51;
- }
- return b;
- }
-
- static Bigint *
-lshift(Bigint *b, int k)
-{
- int i, k1, n, n1;
- Bigint *b1;
- ULong *x, *x1, *xe, z;
-
-#ifdef Pack_32
- n = k >> 5;
-#else
- n = k >> 4;
-#endif
- k1 = b->k;
- n1 = n + b->wds + 1;
- for(i = b->maxwds; n1 > i; i <<= 1)
- k1++;
- b1 = Balloc(k1);
- x1 = b1->x;
- for(i = 0; i < n; i++)
- *x1++ = 0;
- x = b->x;
- xe = x + b->wds;
-#ifdef Pack_32
- if (k &= 0x1f) {
- k1 = 32 - k;
- z = 0;
- do {
- *x1++ = *x << k | z;
- z = *x++ >> k1;
- }
- while(x < xe);
- if ((*x1 = z))
- ++n1;
- }
-#else
- if (k &= 0xf) {
- k1 = 16 - k;
- z = 0;
- do {
- *x1++ = *x << k & 0xffff | z;
- z = *x++ >> k1;
- }
- while(x < xe);
- if (*x1 = z)
- ++n1;
- }
-#endif
- else do
- *x1++ = *x++;
- while(x < xe);
- b1->wds = n1 - 1;
- Bfree(b);
- return b1;
- }
-
- static int
-cmp(Bigint *a, Bigint *b)
-{
- ULong *xa, *xa0, *xb, *xb0;
- int i, j;
-
- i = a->wds;
- j = b->wds;
-#ifdef DEBUG
- if (i > 1 && !a->x[i-1])
- Bug("cmp called with a->x[a->wds-1] == 0");
- if (j > 1 && !b->x[j-1])
- Bug("cmp called with b->x[b->wds-1] == 0");
-#endif
- if (i -= j)
- return i;
- xa0 = a->x;
- xa = xa0 + j;
- xb0 = b->x;
- xb = xb0 + j;
- for(;;) {
- if (*--xa != *--xb)
- return *xa < *xb ? -1 : 1;
- if (xa <= xa0)
- break;
- }
- return 0;
- }
-
- static Bigint *
-diff(Bigint *a, Bigint *b)
-{
- Bigint *c;
- int i, wa, wb;
- Long borrow, y; /* We need signed shifts here. */
- ULong *xa, *xae, *xb, *xbe, *xc;
-#ifdef Pack_32
- Long z;
-#endif
-
- i = cmp(a,b);
- if (!i) {
- c = Balloc(0);
- c->wds = 1;
- c->x[0] = 0;
- return c;
- }
- if (i < 0) {
- c = a;
- a = b;
- b = c;
- i = 1;
- }
- else
- i = 0;
- c = Balloc(a->k);
- c->sign = i;
- wa = a->wds;
- xa = a->x;
- xae = xa + wa;
- wb = b->wds;
- xb = b->x;
- xbe = xb + wb;
- xc = c->x;
- borrow = 0;
-#ifdef Pack_32
- do {
- y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
- borrow = z >> 16;
- Sign_Extend(borrow, z);
- Storeinc(xc, z, y);
- }
- while(xb < xbe);
- while(xa < xae) {
- y = (*xa & 0xffff) + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- z = (*xa++ >> 16) + borrow;
- borrow = z >> 16;
- Sign_Extend(borrow, z);
- Storeinc(xc, z, y);
- }
-#else
- do {
- y = *xa++ - *xb++ + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- *xc++ = y & 0xffff;
- }
- while(xb < xbe);
- while(xa < xae) {
- y = *xa++ + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- *xc++ = y & 0xffff;
- }
-#endif
- while(!*--xc)
- wa--;
- c->wds = wa;
- return c;
- }
-
- static double
-ulp(double _x)
-{
- _double x;
- Long L;
- _double a;
-
- value(x) = _x;
- L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
-#ifndef Sudden_Underflow
- if (L > 0) {
-#endif
-#ifdef IBM
- L |= Exp_msk1 >> 4;
-#endif
- word0(a) = L;
- word1(a) = 0;
-#ifndef Sudden_Underflow
- }
- else {
- L = -L >> Exp_shift;
- if (L < Exp_shift) {
- word0(a) = 0x80000 >> L;
- word1(a) = 0;
- }
- else {
- word0(a) = 0;
- L -= Exp_shift;
- word1(a) = L >= 31 ? 1 : 1 << 31 - L;
- }
- }
-#endif
- return value(a);
- }
-
- static double
-b2d(Bigint *a, int *e)
-{
- ULong *xa, *xa0, w, y, z;
- int k;
- _double d;
-#ifdef VAX
- ULong d0, d1;
-#else
-#define d0 word0(d)
-#define d1 word1(d)
-#endif
-
- xa0 = a->x;
- xa = xa0 + a->wds;
- y = *--xa;
-#ifdef DEBUG
- if (!y) Bug("zero y in b2d");
-#endif
- k = hi0bits(y);
- *e = 32 - k;
-#ifdef Pack_32
- if (k < Ebits) {
- d0 = Exp_1 | y >> Ebits - k;
- w = xa > xa0 ? *--xa : 0;
- d1 = y << (32-Ebits) + k | w >> Ebits - k;
- goto ret_d;
- }
- z = xa > xa0 ? *--xa : 0;
- if (k -= Ebits) {
- d0 = Exp_1 | y << k | z >> 32 - k;
- y = xa > xa0 ? *--xa : 0;
- d1 = z << k | y >> 32 - k;
- }
- else {
- d0 = Exp_1 | y;
- d1 = z;
- }
-#else
- if (k < Ebits + 16) {
- z = xa > xa0 ? *--xa : 0;
- d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
- w = xa > xa0 ? *--xa : 0;
- y = xa > xa0 ? *--xa : 0;
- d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
- goto ret_d;
- }
- z = xa > xa0 ? *--xa : 0;
- w = xa > xa0 ? *--xa : 0;
- k -= Ebits + 16;
- d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
- y = xa > xa0 ? *--xa : 0;
- d1 = w << k + 16 | y << k;
-#endif
- ret_d:
-#ifdef VAX
- word0(d) = d0 >> 16 | d0 << 16;
- word1(d) = d1 >> 16 | d1 << 16;
-#else
-#undef d0
-#undef d1
-#endif
- return value(d);
- }
-
- static Bigint *
-d2b(double _d, int *e, int *bits)
-{
- Bigint *b;
- int de, i, k;
- ULong *x, y, z;
- _double d;
-#ifdef VAX
- ULong d0, d1;
-#endif
-
- value(d) = _d;
-#ifdef VAX
- d0 = word0(d) >> 16 | word0(d) << 16;
- d1 = word1(d) >> 16 | word1(d) << 16;
-#else
-#define d0 word0(d)
-#define d1 word1(d)
-#endif
-
-#ifdef Pack_32
- b = Balloc(1);
-#else
- b = Balloc(2);
-#endif
- x = b->x;
-
- z = d0 & Frac_mask;
- d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
-#ifdef Sudden_Underflow
- de = (int)(d0 >> Exp_shift);
-#ifndef IBM
- z |= Exp_msk11;
-#endif
-#else
- if (de = (int)(d0 >> Exp_shift))
- z |= Exp_msk1;
-#endif
-#ifdef Pack_32
- if (y = d1) {
- if (k = lo0bits(&y)) {
- x[0] = y | z << 32 - k;
- z >>= k;
- }
- else
- x[0] = y;
- i = b->wds = (x[1] = z) ? 2 : 1;
- }
- else {
-#ifdef DEBUG
- if (!z)
- Bug("Zero passed to d2b");
-#endif
- k = lo0bits(&z);
- x[0] = z;
- i = b->wds = 1;
- k += 32;
- }
-#else
- if (y = d1) {
- if (k = lo0bits(&y))
- if (k >= 16) {
- x[0] = y | z << 32 - k & 0xffff;
- x[1] = z >> k - 16 & 0xffff;
- x[2] = z >> k;
- i = 2;
- }
- else {
- x[0] = y & 0xffff;
- x[1] = y >> 16 | z << 16 - k & 0xffff;
- x[2] = z >> k & 0xffff;
- x[3] = z >> k+16;
- i = 3;
- }
- else {
- x[0] = y & 0xffff;
- x[1] = y >> 16;
- x[2] = z & 0xffff;
- x[3] = z >> 16;
- i = 3;
- }
- }
- else {
-#ifdef DEBUG
- if (!z)
- Bug("Zero passed to d2b");
-#endif
- k = lo0bits(&z);
- if (k >= 16) {
- x[0] = z;
- i = 0;
- }
- else {
- x[0] = z & 0xffff;
- x[1] = z >> 16;
- i = 1;
- }
- k += 32;
- }
- while(!x[i])
- --i;
- b->wds = i + 1;
-#endif
-#ifndef Sudden_Underflow
- if (de) {
-#endif
-#ifdef IBM
- *e = (de - Bias - (P-1) << 2) + k;
- *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
-#else
- *e = de - Bias - (P-1) + k;
- *bits = P - k;
-#endif
-#ifndef Sudden_Underflow
- }
- else {
- *e = de - Bias - (P-1) + 1 + k;
-#ifdef Pack_32
- *bits = 32*i - hi0bits(x[i-1]);
-#else
- *bits = (i+2)*16 - hi0bits(x[i]);
-#endif
- }
-#endif
- return b;
- }
-#undef d0
-#undef d1
-
- static double
-ratio(Bigint *a, Bigint *b)
-{
- _double da, db;
- int k, ka, kb;
-
- value(da) = b2d(a, &ka);
- value(db) = b2d(b, &kb);
-#ifdef Pack_32
- k = ka - kb + 32*(a->wds - b->wds);
-#else
- k = ka - kb + 16*(a->wds - b->wds);
-#endif
-#ifdef IBM
- if (k > 0) {
- word0(da) += (k >> 2)*Exp_msk1;
- if (k &= 3)
- da *= 1 << k;
- }
- else {
- k = -k;
- word0(db) += (k >> 2)*Exp_msk1;
- if (k &= 3)
- db *= 1 << k;
- }
-#else
- if (k > 0)
- word0(da) += k*Exp_msk1;
- else {
- k = -k;
- word0(db) += k*Exp_msk1;
- }
-#endif
- return value(da) / value(db);
- }
-
-static CONST double
-tens[] = {
- 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
- 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
- 1e20, 1e21, 1e22
-#ifdef VAX
- , 1e23, 1e24
-#endif
- };
-
-#ifdef IEEE_Arith
-static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
-static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
-#define n_bigtens 5
-#else
-#ifdef IBM
-static CONST double bigtens[] = { 1e16, 1e32, 1e64 };
-static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
-#define n_bigtens 3
-#else
-static CONST double bigtens[] = { 1e16, 1e32 };
-static CONST double tinytens[] = { 1e-16, 1e-32 };
-#define n_bigtens 2
-#endif
-#endif
-
- double
-strtod(CONST char *s00, char **se)
-{
- int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
- e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
- CONST char *s, *s0, *s1;
- double aadj, aadj1, adj;
- /*
- * volatile forces mem update for FPUs where reg size != sizeof double,
- * which should trigger ERANGE in the case of underflow.
- */
- volatile _double rv;
- _double rv0;
- Long L;
- ULong y, z;
- Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
-
- CONST char decimal_point = localeconv()->decimal_point[0];
-
- sign = nz0 = nz = 0;
- value(rv) = 0.;
-
-
- for(s = s00; isspace((unsigned char) *s); s++)
- ;
-
- if (*s == '-') {
- sign = 1;
- s++;
- } else if (*s == '+') {
- s++;
- }
-
- if (*s == '\0') {
- s = s00;
- goto ret;
- }
-
- if (*s == '0') {
- nz0 = 1;
- while(*++s == '0') ;
- if (!*s)
- goto ret;
- }
- s0 = s;
- y = z = 0;
- for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
- if (nd < 9)
- y = 10*y + c - '0';
- else if (nd < 16)
- z = 10*z + c - '0';
- nd0 = nd;
- if (c == decimal_point) {
- c = *++s;
- if (!nd) {
- for(; c == '0'; c = *++s)
- nz++;
- if (c > '0' && c <= '9') {
- s0 = s;
- nf += nz;
- nz = 0;
- goto have_dig;
- }
- goto dig_done;
- }
- for(; c >= '0' && c <= '9'; c = *++s) {
- have_dig:
- nz++;
- if (c -= '0') {
- nf += nz;
- for(i = 1; i < nz; i++)
- if (nd++ < 9)
- y *= 10;
- else if (nd <= DBL_DIG + 1)
- z *= 10;
- if (nd++ < 9)
- y = 10*y + c;
- else if (nd <= DBL_DIG + 1)
- z = 10*z + c;
- nz = 0;
- }
- }
- }
- dig_done:
- e = 0;
- if (c == 'e' || c == 'E') {
- if (!nd && !nz && !nz0) {
- s = s00;
- goto ret;
- }
- s00 = s;
- esign = 0;
- switch(c = *++s) {
- case '-':
- esign = 1;
- case '+':
- c = *++s;
- }
- if (c >= '0' && c <= '9') {
- while(c == '0')
- c = *++s;
- if (c > '0' && c <= '9') {
- L = c - '0';
- s1 = s;
- while((c = *++s) >= '0' && c <= '9')
- L = 10*L + c - '0';
- if (s - s1 > 8 || L > 19999)
- /* Avoid confusion from exponents
- * so large that e might overflow.
- */
- e = 19999; /* safe for 16 bit ints */
- else
- e = (int)L;
- if (esign)
- e = -e;
- }
- else
- e = 0;
- }
- else
- s = s00;
- }
- if (!nd) {
- if (!nz && !nz0)
- s = s00;
- goto ret;
- }
- e1 = e -= nf;
-
- /* Now we have nd0 digits, starting at s0, followed by a
- * decimal point, followed by nd-nd0 digits. The number we're
- * after is the integer represented by those digits times
- * 10**e */
-
- if (!nd0)
- nd0 = nd;
- k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
- value(rv) = y;
- if (k > 9)
- value(rv) = tens[k - 9] * value(rv) + z;
- bd0 = 0;
- if (nd <= DBL_DIG
-#ifndef RND_PRODQUOT
- && FLT_ROUNDS == 1
-#endif
- ) {
- if (!e)
- goto ret;
- if (e > 0) {
- if (e <= Ten_pmax) {
-#ifdef VAX
- goto vax_ovfl_check;
-#else
- /* value(rv) = */ rounded_product(value(rv),
- tens[e]);
- goto ret;
-#endif
- }
- i = DBL_DIG - nd;
- if (e <= Ten_pmax + i) {
- /* A fancier test would sometimes let us do
- * this for larger i values.
- */
- e -= i;
- value(rv) *= tens[i];
-#ifdef VAX
- /* VAX exponent range is so narrow we must
- * worry about overflow here...
- */
- vax_ovfl_check:
- word0(rv) -= P*Exp_msk1;
- /* value(rv) = */ rounded_product(value(rv),
- tens[e]);
- if ((word0(rv) & Exp_mask)
- > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
- goto ovfl;
- word0(rv) += P*Exp_msk1;
-#else
- /* value(rv) = */ rounded_product(value(rv),
- tens[e]);
-#endif
- goto ret;
- }
- }
-#ifndef Inaccurate_Divide
- else if (e >= -Ten_pmax) {
- /* value(rv) = */ rounded_quotient(value(rv),
- tens[-e]);
- goto ret;
- }
-#endif
- }
- e1 += nd - k;
-
- /* Get starting approximation = rv * 10**e1 */
-
- if (e1 > 0) {
- if (i = e1 & 15)
- value(rv) *= tens[i];
- if (e1 &= ~15) {
- if (e1 > DBL_MAX_10_EXP) {
- ovfl:
- errno = ERANGE;
-#ifndef Bad_float_h
- value(rv) = HUGE_VAL;
-#else
- /* Can't trust HUGE_VAL */
-#ifdef IEEE_Arith
- word0(rv) = Exp_mask;
- word1(rv) = 0;
-#else
- word0(rv) = Big0;
- word1(rv) = Big1;
-#endif
-#endif
- if (bd0)
- goto retfree;
- goto ret;
- }
- if (e1 >>= 4) {
- for(j = 0; e1 > 1; j++, e1 >>= 1)
- if (e1 & 1)
- value(rv) *= bigtens[j];
- /* The last multiplication could overflow. */
- word0(rv) -= P*Exp_msk1;
- value(rv) *= bigtens[j];
- if ((z = word0(rv) & Exp_mask)
- > Exp_msk1*(DBL_MAX_EXP+Bias-P))
- goto ovfl;
- if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
- /* set to largest number */
- /* (Can't trust DBL_MAX) */
- word0(rv) = Big0;
- word1(rv) = Big1;
- }
- else
- word0(rv) += P*Exp_msk1;
- }
-
- }
- }
- else if (e1 < 0) {
- e1 = -e1;
- if (i = e1 & 15)
- value(rv) /= tens[i];
- if (e1 &= ~15) {
- e1 >>= 4;
- if (e1 >= 1 << n_bigtens)
- goto undfl;
- for(j = 0; e1 > 1; j++, e1 >>= 1)
- if (e1 & 1)
- value(rv) *= tinytens[j];
- /* The last multiplication could underflow. */
- value(rv0) = value(rv);
- value(rv) *= tinytens[j];
- if (!value(rv)) {
- value(rv) = 2.*value(rv0);
- value(rv) *= tinytens[j];
- if (!value(rv)) {
- undfl:
- value(rv) = 0.;
- errno = ERANGE;
- if (bd0)
- goto retfree;
- goto ret;
- }
- word0(rv) = Tiny0;
- word1(rv) = Tiny1;
- /* The refinement below will clean
- * this approximation up.
- */
- }
- }
- }
-
- /* Now the hard part -- adjusting rv to the correct value.*/
-
- /* Put digits into bd: true value = bd * 10^e */
-
- bd0 = s2b(s0, nd0, nd, y);
-
- for(;;) {
- bd = Balloc(bd0->k);
- Bcopy(bd, bd0);
- bb = d2b(value(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
- bs = i2b(1);
-
- if (e >= 0) {
- bb2 = bb5 = 0;
- bd2 = bd5 = e;
- }
- else {
- bb2 = bb5 = -e;
- bd2 = bd5 = 0;
- }
- if (bbe >= 0)
- bb2 += bbe;
- else
- bd2 -= bbe;
- bs2 = bb2;
-#ifdef Sudden_Underflow
-#ifdef IBM
- j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
-#else
- j = P + 1 - bbbits;
-#endif
-#else
- i = bbe + bbbits - 1; /* logb(rv) */
- if (i < Emin) /* denormal */
- j = bbe + (P-Emin);
- else
- j = P + 1 - bbbits;
-#endif
- bb2 += j;
- bd2 += j;
- i = bb2 < bd2 ? bb2 : bd2;
- if (i > bs2)
- i = bs2;
- if (i > 0) {
- bb2 -= i;
- bd2 -= i;
- bs2 -= i;
- }
- if (bb5 > 0) {
- bs = pow5mult(bs, bb5);
- bb1 = mult(bs, bb);
- Bfree(bb);
- bb = bb1;
- }
- if (bb2 > 0)
- bb = lshift(bb, bb2);
- if (bd5 > 0)
- bd = pow5mult(bd, bd5);
- if (bd2 > 0)
- bd = lshift(bd, bd2);
- if (bs2 > 0)
- bs = lshift(bs, bs2);
- delta = diff(bb, bd);
- dsign = delta->sign;
- delta->sign = 0;
- i = cmp(delta, bs);
- if (i < 0) {
- /* Error is less than half an ulp -- check for
- * special case of mantissa a power of two.
- */
- if (dsign || word1(rv) || word0(rv) & Bndry_mask)
- break;
- delta = lshift(delta,Log2P);
- if (cmp(delta, bs) > 0)
- goto drop_down;
- break;
- }
- if (i == 0) {
- /* exactly half-way between */
- if (dsign) {
- if ((word0(rv) & Bndry_mask1) == Bndry_mask1
- && word1(rv) == 0xffffffff) {
- /*boundary case -- increment exponent*/
- word0(rv) = (word0(rv) & Exp_mask)
- + Exp_msk1
-#ifdef IBM
- | Exp_msk1 >> 4
-#endif
- ;
- word1(rv) = 0;
- break;
- }
- }
- else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
- drop_down:
- /* boundary case -- decrement exponent */
-#ifdef Sudden_Underflow
- L = word0(rv) & Exp_mask;
-#ifdef IBM
- if (L < Exp_msk1)
-#else
- if (L <= Exp_msk1)
-#endif
- goto undfl;
- L -= Exp_msk1;
-#else
- L = (word0(rv) & Exp_mask) - Exp_msk1;
-#endif
- word0(rv) = L | Bndry_mask1;
- word1(rv) = 0xffffffff;
-#ifdef IBM
- goto cont;
-#else
- break;
-#endif
- }
-#ifndef ROUND_BIASED
- if (!(word1(rv) & LSB))
- break;
-#endif
- if (dsign)
- value(rv) += ulp(value(rv));
-#ifndef ROUND_BIASED
- else {
- value(rv) -= ulp(value(rv));
-#ifndef Sudden_Underflow
- if (!value(rv))
- goto undfl;
-#endif
- }
-#endif
- break;
- }
- if ((aadj = ratio(delta, bs)) <= 2.) {
- if (dsign)
- aadj = aadj1 = 1.;
- else if (word1(rv) || word0(rv) & Bndry_mask) {
-#ifndef Sudden_Underflow
- if (word1(rv) == Tiny1 && !word0(rv))
- goto undfl;
-#endif
- aadj = 1.;
- aadj1 = -1.;
- }
- else {
- /* special case -- power of FLT_RADIX to be */
- /* rounded down... */
-
- if (aadj < 2./FLT_RADIX)
- aadj = 1./FLT_RADIX;
- else
- aadj *= 0.5;
- aadj1 = -aadj;
- }
- }
- else {
- aadj *= 0.5;
- aadj1 = dsign ? aadj : -aadj;
-#ifdef Check_FLT_ROUNDS
- switch(FLT_ROUNDS) {
- case 2: /* towards +infinity */
- aadj1 -= 0.5;
- break;
- case 0: /* towards 0 */
- case 3: /* towards -infinity */
- aadj1 += 0.5;
- }
-#else
- if (FLT_ROUNDS == 0)
- aadj1 += 0.5;
-#endif
- }
- y = word0(rv) & Exp_mask;
-
- /* Check for overflow */
-
- if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
- value(rv0) = value(rv);
- word0(rv) -= P*Exp_msk1;
- adj = aadj1 * ulp(value(rv));
- value(rv) += adj;
- if ((word0(rv) & Exp_mask) >=
- Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
- if (word0(rv0) == Big0 && word1(rv0) == Big1)
- goto ovfl;
- word0(rv) = Big0;
- word1(rv) = Big1;
- goto cont;
- }
- else
- word0(rv) += P*Exp_msk1;
- }
- else {
-#ifdef Sudden_Underflow
- if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
- value(rv0) = value(rv);
- word0(rv) += P*Exp_msk1;
- adj = aadj1 * ulp(value(rv));
- value(rv) += adj;
-#ifdef IBM
- if ((word0(rv) & Exp_mask) < P*Exp_msk1)
-#else
- if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
-#endif
- {
- if (word0(rv0) == Tiny0
- && word1(rv0) == Tiny1)
- goto undfl;
- word0(rv) = Tiny0;
- word1(rv) = Tiny1;
- goto cont;
- }
- else
- word0(rv) -= P*Exp_msk1;
- }
- else {
- adj = aadj1 * ulp(value(rv));
- value(rv) += adj;
- }
-#else
- /* Compute adj so that the IEEE rounding rules will
- * correctly round rv + adj in some half-way cases.
- * If rv * ulp(rv) is denormalized (i.e.,
- * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
- * trouble from bits lost to denormalization;
- * example: 1.2e-307 .
- */
- if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
- aadj1 = (double)(int)(aadj + 0.5);
- if (!dsign)
- aadj1 = -aadj1;
- }
- adj = aadj1 * ulp(value(rv));
- value(rv) += adj;
-#endif
- }
- z = word0(rv) & Exp_mask;
- if (y == z) {
- /* Can we stop now? */
- L = aadj;
- aadj -= L;
- /* The tolerances below are conservative. */
- if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
- if (aadj < .4999999 || aadj > .5000001)
- break;
- }
- else if (aadj < .4999999/FLT_RADIX)
- break;
- }
- cont:
- Bfree(bb);
- Bfree(bd);
- Bfree(bs);
- Bfree(delta);
- }
- retfree:
- Bfree(bb);
- Bfree(bd);
- Bfree(bs);
- Bfree(bd0);
- Bfree(delta);
- ret:
- if (se)
- *se = (char *)s;
- return sign ? -value(rv) : value(rv);
- }
-
- static int
-quorem(Bigint *b, Bigint *S)
-{
- int n;
- Long borrow, y;
- ULong carry, q, ys;
- ULong *bx, *bxe, *sx, *sxe;
-#ifdef Pack_32
- Long z;
- ULong si, zs;
-#endif
-
- n = S->wds;
-#ifdef DEBUG
- /*debug*/ if (b->wds > n)
- /*debug*/ Bug("oversize b in quorem");
-#endif
- if (b->wds < n)
- return 0;
- sx = S->x;
- sxe = sx + --n;
- bx = b->x;
- bxe = bx + n;
- q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
-#ifdef DEBUG
- /*debug*/ if (q > 9)
- /*debug*/ Bug("oversized quotient in quorem");
-#endif
- if (q) {
- borrow = 0;
- carry = 0;
- do {
-#ifdef Pack_32
- si = *sx++;
- ys = (si & 0xffff) * q + carry;
- zs = (si >> 16) * q + (ys >> 16);
- carry = zs >> 16;
- y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- z = (*bx >> 16) - (zs & 0xffff) + borrow;
- borrow = z >> 16;
- Sign_Extend(borrow, z);
- Storeinc(bx, z, y);
-#else
- ys = *sx++ * q + carry;
- carry = ys >> 16;
- y = *bx - (ys & 0xffff) + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- *bx++ = y & 0xffff;
-#endif
- }
- while(sx <= sxe);
- if (!*bxe) {
- bx = b->x;
- while(--bxe > bx && !*bxe)
- --n;
- b->wds = n;
- }
- }
- if (cmp(b, S) >= 0) {
- q++;
- borrow = 0;
- carry = 0;
- bx = b->x;
- sx = S->x;
- do {
-#ifdef Pack_32
- si = *sx++;
- ys = (si & 0xffff) + carry;
- zs = (si >> 16) + (ys >> 16);
- carry = zs >> 16;
- y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- z = (*bx >> 16) - (zs & 0xffff) + borrow;
- borrow = z >> 16;
- Sign_Extend(borrow, z);
- Storeinc(bx, z, y);
-#else
- ys = *sx++ + carry;
- carry = ys >> 16;
- y = *bx - (ys & 0xffff) + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- *bx++ = y & 0xffff;
-#endif
- }
- while(sx <= sxe);
- bx = b->x;
- bxe = bx + n;
- if (!*bxe) {
- while(--bxe > bx && !*bxe)
- --n;
- b->wds = n;
- }
- }
- return q;
- }
-
-/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
- *
- * Inspired by "How to Print Floating-Point Numbers Accurately" by
- * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
- *
- * Modifications:
- * 1. Rather than iterating, we use a simple numeric overestimate
- * to determine k = floor(log10(d)). We scale relevant
- * quantities using O(log2(k)) rather than O(k) multiplications.
- * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
- * try to generate digits strictly left to right. Instead, we
- * compute with fewer bits and propagate the carry if necessary
- * when rounding the final digit up. This is often faster.
- * 3. Under the assumption that input will be rounded nearest,
- * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
- * That is, we allow equality in stopping tests when the
- * round-nearest rule will give the same floating-point value
- * as would satisfaction of the stopping test with strict
- * inequality.
- * 4. We remove common factors of powers of 2 from relevant
- * quantities.
- * 5. When converting floating-point integers less than 1e16,
- * we use floating-point arithmetic rather than resorting
- * to multiple-precision integers.
- * 6. When asked to produce fewer than 15 digits, we first try
- * to get by with floating-point arithmetic; we resort to
- * multiple-precision integer arithmetic only if we cannot
- * guarantee that the floating-point calculation has given
- * the correctly rounded result. For k requested digits and
- * "uniformly" distributed input, the probability is
- * something like 10^(k-15) that we must resort to the Long
- * calculation.
- */
-
- char *
-__dtoa(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
-{
- /* Arguments ndigits, decpt, sign are similar to those
- of ecvt and fcvt; trailing zeros are suppressed from
- the returned string. If not null, *rve is set to point
- to the end of the return value. If d is +-Infinity or NaN,
- then *decpt is set to 9999.
-
- mode:
- 0 ==> shortest string that yields d when read in
- and rounded to nearest.
- 1 ==> like 0, but with Steele & White stopping rule;
- e.g. with IEEE P754 arithmetic , mode 0 gives
- 1e23 whereas mode 1 gives 9.999999999999999e22.
- 2 ==> max(1,ndigits) significant digits. This gives a
- return value similar to that of ecvt, except
- that trailing zeros are suppressed.
- 3 ==> through ndigits past the decimal point. This
- gives a return value similar to that from fcvt,
- except that trailing zeros are suppressed, and
- ndigits can be negative.
- 4-9 should give the same return values as 2-3, i.e.,
- 4 <= mode <= 9 ==> same return as mode
- 2 + (mode & 1). These modes are mainly for
- debugging; often they run slower but sometimes
- faster than modes 2-3.
- 4,5,8,9 ==> left-to-right digit generation.
- 6-9 ==> don't try fast floating-point estimate
- (if applicable).
-
- Values of mode other than 0-9 are treated as mode 0.
-
- Sufficient space is allocated to the return value
- to hold the suppressed trailing zeros.
- */
-
- int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
- j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
- spec_case, try_quick;
- Long L;
-#ifndef Sudden_Underflow
- int denorm;
- ULong x;
-#endif
- Bigint *b, *b1, *delta, *mlo, *mhi, *S;
- double ds;
- char *s, *s0;
- _double d, d2, eps;
-
- value(d) = _d;
-
- if (word0(d) & Sign_bit) {
- /* set sign for everything, including 0's and NaNs */
- *sign = 1;
- word0(d) &= ~Sign_bit; /* clear sign bit */
- }
- else
- *sign = 0;
-
-#if defined(IEEE_Arith) + defined(VAX)
-#ifdef IEEE_Arith
- if ((word0(d) & Exp_mask) == Exp_mask)
-#else
- if (word0(d) == 0x8000)
-#endif
- {
- /* Infinity or NaN */
- *decpt = 9999;
-#ifdef IEEE_Arith
- if (!word1(d) && !(word0(d) & 0xfffff))
- return nrv_alloc("Infinity", rve, 8);
-#endif
- return nrv_alloc("NaN", rve, 3);
- }
-#endif
-#ifdef IBM
- value(d) += 0; /* normalize */
-#endif
- if (!value(d)) {
- *decpt = 1;
- return nrv_alloc("0", rve, 1);
- }
-
- b = d2b(value(d), &be, &bbits);
-#ifdef Sudden_Underflow
- i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
-#else
- if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) {
-#endif
- value(d2) = value(d);
- word0(d2) &= Frac_mask1;
- word0(d2) |= Exp_11;
-#ifdef IBM
- if (j = 11 - hi0bits(word0(d2) & Frac_mask))
- value(d2) /= 1 << j;
-#endif
-
- /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
- * log10(x) = log(x) / log(10)
- * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
- * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
- *
- * This suggests computing an approximation k to log10(d) by
- *
- * k = (i - Bias)*0.301029995663981
- * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
- *
- * We want k to be too large rather than too small.
- * The error in the first-order Taylor series approximation
- * is in our favor, so we just round up the constant enough
- * to compensate for any error in the multiplication of
- * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
- * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
- * adding 1e-13 to the constant term more than suffices.
- * Hence we adjust the constant term to 0.1760912590558.
- * (We could get a more accurate k by invoking log10,
- * but this is probably not worthwhile.)
- */
-
- i -= Bias;
-#ifdef IBM
- i <<= 2;
- i += j;
-#endif
-#ifndef Sudden_Underflow
- denorm = 0;
- }
- else {
- /* d is denormalized */
-
- i = bbits + be + (Bias + (P-1) - 1);
- x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
- : word1(d) << 32 - i;
- value(d2) = x;
- word0(d2) -= 31*Exp_msk1; /* adjust exponent */
- i -= (Bias + (P-1) - 1) + 1;
- denorm = 1;
- }
-#endif
- ds = (value(d2)-1.5)*0.289529654602168 + 0.1760912590558 +
- i*0.301029995663981;
- k = (int)ds;
- if (ds < 0. && ds != k)
- k--; /* want k = floor(ds) */
- k_check = 1;
- if (k >= 0 && k <= Ten_pmax) {
- if (value(d) < tens[k])
- k--;
- k_check = 0;
- }
- j = bbits - i - 1;
- if (j >= 0) {
- b2 = 0;
- s2 = j;
- }
- else {
- b2 = -j;
- s2 = 0;
- }
- if (k >= 0) {
- b5 = 0;
- s5 = k;
- s2 += k;
- }
- else {
- b2 -= k;
- b5 = -k;
- s5 = 0;
- }
- if (mode < 0 || mode > 9)
- mode = 0;
- try_quick = 1;
- if (mode > 5) {
- mode -= 4;
- try_quick = 0;
- }
- leftright = 1;
- switch(mode) {
- case 0:
- case 1:
- ilim = ilim1 = -1;
- i = 18;
- ndigits = 0;
- break;
- case 2:
- leftright = 0;
- /* no break */
- case 4:
- if (ndigits <= 0)
- ndigits = 1;
- ilim = ilim1 = i = ndigits;
- break;
- case 3:
- leftright = 0;
- /* no break */
- case 5:
- i = ndigits + k + 1;
- ilim = i;
- ilim1 = i - 1;
- if (i <= 0)
- i = 1;
- }
- s = s0 = rv_alloc(i);
-
- if (ilim >= 0 && ilim <= Quick_max && try_quick) {
-
- /* Try to get by with floating-point arithmetic. */
-
- i = 0;
- value(d2) = value(d);
- k0 = k;
- ilim0 = ilim;
- ieps = 2; /* conservative */
- if (k > 0) {
- ds = tens[k&0xf];
- j = k >> 4;
- if (j & Bletch) {
- /* prevent overflows */
- j &= Bletch - 1;
- value(d) /= bigtens[n_bigtens-1];
- ieps++;
- }
- for(; j; j >>= 1, i++)
- if (j & 1) {
- ieps++;
- ds *= bigtens[i];
- }
- value(d) /= ds;
- }
- else if (j1 = -k) {
- value(d) *= tens[j1 & 0xf];
- for(j = j1 >> 4; j; j >>= 1, i++)
- if (j & 1) {
- ieps++;
- value(d) *= bigtens[i];
- }
- }
- if (k_check && value(d) < 1. && ilim > 0) {
- if (ilim1 <= 0)
- goto fast_failed;
- ilim = ilim1;
- k--;
- value(d) *= 10.;
- ieps++;
- }
- value(eps) = ieps*value(d) + 7.;
- word0(eps) -= (P-1)*Exp_msk1;
- if (ilim == 0) {
- S = mhi = 0;
- value(d) -= 5.;
- if (value(d) > value(eps))
- goto one_digit;
- if (value(d) < -value(eps))
- goto no_digits;
- goto fast_failed;
- }
-#ifndef No_leftright
- if (leftright) {
- /* Use Steele & White method of only
- * generating digits needed.
- */
- value(eps) = 0.5/tens[ilim-1] - value(eps);
- for(i = 0;;) {
- L = value(d);
- value(d) -= L;
- *s++ = '0' + (int)L;
- if (value(d) < value(eps))
- goto ret1;
- if (1. - value(d) < value(eps))
- goto bump_up;
- if (++i >= ilim)
- break;
- value(eps) *= 10.;
- value(d) *= 10.;
- }
- }
- else {
-#endif
- /* Generate ilim digits, then fix them up. */
- value(eps) *= tens[ilim-1];
- for(i = 1;; i++, value(d) *= 10.) {
- L = value(d);
- value(d) -= L;
- *s++ = '0' + (int)L;
- if (i == ilim) {
- if (value(d) > 0.5 + value(eps))
- goto bump_up;
- else if (value(d) < 0.5 - value(eps)) {
- while(*--s == '0');
- s++;
- goto ret1;
- }
- break;
- }
- }
-#ifndef No_leftright
- }
-#endif
- fast_failed:
- s = s0;
- value(d) = value(d2);
- k = k0;
- ilim = ilim0;
- }
-
- /* Do we have a "small" integer? */
-
- if (be >= 0 && k <= Int_max) {
- /* Yes. */
- ds = tens[k];
- if (ndigits < 0 && ilim <= 0) {
- S = mhi = 0;
- if (ilim < 0 || value(d) <= 5*ds)
- goto no_digits;
- goto one_digit;
- }
- for(i = 1;; i++) {
- L = value(d) / ds;
- value(d) -= L*ds;
-#ifdef Check_FLT_ROUNDS
- /* If FLT_ROUNDS == 2, L will usually be high by 1 */
- if (value(d) < 0) {
- L--;
- value(d) += ds;
- }
-#endif
- *s++ = '0' + (int)L;
- if (i == ilim) {
- value(d) += value(d);
- if (value(d) > ds || value(d) == ds && L & 1) {
- bump_up:
- while(*--s == '9')
- if (s == s0) {
- k++;
- *s = '0';
- break;
- }
- ++*s++;
- }
- break;
- }
- if (!(value(d) *= 10.))
- break;
- }
- goto ret1;
- }
-
- m2 = b2;
- m5 = b5;
- mhi = mlo = 0;
- if (leftright) {
- if (mode < 2) {
- i =
-#ifndef Sudden_Underflow
- denorm ? be + (Bias + (P-1) - 1 + 1) :
-#endif
-#ifdef IBM
- 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
-#else
- 1 + P - bbits;
-#endif
- }
- else {
- j = ilim - 1;
- if (m5 >= j)
- m5 -= j;
- else {
- s5 += j -= m5;
- b5 += j;
- m5 = 0;
- }
- if ((i = ilim) < 0) {
- m2 -= i;
- i = 0;
- }
- }
- b2 += i;
- s2 += i;
- mhi = i2b(1);
- }
- if (m2 > 0 && s2 > 0) {
- i = m2 < s2 ? m2 : s2;
- b2 -= i;
- m2 -= i;
- s2 -= i;
- }
- if (b5 > 0) {
- if (leftright) {
- if (m5 > 0) {
- mhi = pow5mult(mhi, m5);
- b1 = mult(mhi, b);
- Bfree(b);
- b = b1;
- }
- if (j = b5 - m5)
- b = pow5mult(b, j);
- }
- else
- b = pow5mult(b, b5);
- }
- S = i2b(1);
- if (s5 > 0)
- S = pow5mult(S, s5);
-
- /* Check for special case that d is a normalized power of 2. */
-
- if (mode < 2) {
- if (!word1(d) && !(word0(d) & Bndry_mask)
-#ifndef Sudden_Underflow
- && word0(d) & Exp_mask
-#endif
- ) {
- /* The special case */
- b2 += Log2P;
- s2 += Log2P;
- spec_case = 1;
- }
- else
- spec_case = 0;
- }
-
- /* Arrange for convenient computation of quotients:
- * shift left if necessary so divisor has 4 leading 0 bits.
- *
- * Perhaps we should just compute leading 28 bits of S once
- * and for all and pass them and a shift to quorem, so it
- * can do shifts and ors to compute the numerator for q.
- */
-#ifdef Pack_32
- if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)
- i = 32 - i;
-#else
- if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
- i = 16 - i;
-#endif
- if (i > 4) {
- i -= 4;
- b2 += i;
- m2 += i;
- s2 += i;
- }
- else if (i < 4) {
- i += 28;
- b2 += i;
- m2 += i;
- s2 += i;
- }
- if (b2 > 0)
- b = lshift(b, b2);
- if (s2 > 0)
- S = lshift(S, s2);
- if (k_check) {
- if (cmp(b,S) < 0) {
- k--;
- b = multadd(b, 10, 0); /* we botched the k estimate */
- if (leftright)
- mhi = multadd(mhi, 10, 0);
- ilim = ilim1;
- }
- }
- if (ilim <= 0 && mode > 2) {
- if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
- /* no digits, fcvt style */
- no_digits:
- k = -1 - ndigits;
- goto ret;
- }
- one_digit:
- *s++ = '1';
- k++;
- goto ret;
- }
- if (leftright) {
- if (m2 > 0)
- mhi = lshift(mhi, m2);
-
- /* Compute mlo -- check for special case
- * that d is a normalized power of 2.
- */
-
- mlo = mhi;
- if (spec_case) {
- mhi = Balloc(mhi->k);
- Bcopy(mhi, mlo);
- mhi = lshift(mhi, Log2P);
- }
-
- for(i = 1;;i++) {
- dig = quorem(b,S) + '0';
- /* Do we yet have the shortest decimal string
- * that will round to d?
- */
- j = cmp(b, mlo);
- delta = diff(S, mhi);
- j1 = delta->sign ? 1 : cmp(b, delta);
- Bfree(delta);
-#ifndef ROUND_BIASED
- if (j1 == 0 && !mode && !(word1(d) & 1)) {
- if (dig == '9')
- goto round_9_up;
- if (j > 0)
- dig++;
- *s++ = dig;
- goto ret;
- }
-#endif
- if (j < 0 || j == 0 && !mode
-#ifndef ROUND_BIASED
- && !(word1(d) & 1)
-#endif
- ) {
- if (j1 > 0) {
- b = lshift(b, 1);
- j1 = cmp(b, S);
- if ((j1 > 0 || j1 == 0 && dig & 1)
- && dig++ == '9')
- goto round_9_up;
- }
- *s++ = dig;
- goto ret;
- }
- if (j1 > 0) {
- if (dig == '9') { /* possible if i == 1 */
- round_9_up:
- *s++ = '9';
- goto roundoff;
- }
- *s++ = dig + 1;
- goto ret;
- }
- *s++ = dig;
- if (i == ilim)
- break;
- b = multadd(b, 10, 0);
- if (mlo == mhi)
- mlo = mhi = multadd(mhi, 10, 0);
- else {
- mlo = multadd(mlo, 10, 0);
- mhi = multadd(mhi, 10, 0);
- }
- }
- }
- else
- for(i = 1;; i++) {
- *s++ = dig = quorem(b,S) + '0';
- if (i >= ilim)
- break;
- b = multadd(b, 10, 0);
- }
-
- /* Round off last digit */
-
- b = lshift(b, 1);
- j = cmp(b, S);
- if (j > 0 || j == 0 && dig & 1) {
- roundoff:
- while(*--s == '9')
- if (s == s0) {
- k++;
- *s++ = '1';
- goto ret;
- }
- ++*s++;
- }
- else {
- while(*--s == '0');
- s++;
- }
- ret:
- Bfree(S);
- if (mhi) {
- if (mlo && mlo != mhi)
- Bfree(mlo);
- Bfree(mhi);
- }
- ret1:
- Bfree(b);
- if (s == s0) { /* don't return empty string */
- *s++ = '0';
- k = 0;
- }
- *s = 0;
- *decpt = k + 1;
- if (rve)
- *rve = s;
- return s0;
- }
-#ifdef __cplusplus
-}
-#endif
diff --git a/lib/libm/Makefile b/lib/libm/Makefile
index 8e259df2088..575b40c3880 100644
--- a/lib/libm/Makefile
+++ b/lib/libm/Makefile
@@ -1,5 +1,5 @@
# $NetBSD: Makefile,v 1.28 1995/11/20 22:06:19 jtc Exp $
-# $OpenBSD: Makefile,v 1.53 2008/07/30 08:02:34 jmc Exp $
+# $OpenBSD: Makefile,v 1.54 2008/09/07 20:36:08 martynas Exp $
#
# @(#)Makefile 5.1beta 93/09/24
#
@@ -11,42 +11,10 @@
# software is freely granted, provided that this notice
# is preserved.
# ====================================================
-#
-#
-#
-# There are two options in making libm at fdlibm compile time:
-# _IEEE_LIBM --- IEEE libm; smaller, and somewhat faster
-# _MULTI_LIBM --- Support multi-standard at runtime by
-# imposing wrapper functions defined in
-# fdlibm.h:
-# _IEEE_MODE -- IEEE
-# _XOPEN_MODE -- X/OPEN
-# _POSIX_MODE -- POSIX/ANSI
-# _SVID3_MODE -- SVID
-#
-# Here is how to set up CFLAGS to create the desired libm at
-# compile time:
-#
-# CFLAGS = -D_IEEE_LIBM ... IEEE libm (recommended)
-# CFLAGS = -D_SVID3_MODE ... Multi-standard supported
-# libm with SVID as the
-# default standard
-# CFLAGS = -D_XOPEN_MODE ... Multi-standard supported
-# libm with XOPEN as the
-# default standard
-# CFLAGS = -D_POSIX_MODE ... Multi-standard supported
-# libm with POSIX as the
-# default standard
-# CFLAGS = ... Multi-standard supported
-# libm with IEEE as the
-# default standard
-#
# For NOPROFILE and NOPIC
.include <bsd.own.mk>
-CFLAGS+= -D__LIBM_PRIVATE -D_USE_WRITE
-
.if (${MACHINE_ARCH} == "sparc")
CFLAGS+= -O0
.endif
@@ -94,10 +62,6 @@ ARCH_SRCS = n_atan2.S n_cabs.S n_cbrt.S n_sincos.S n_tan.S n_support.S
.PATH: ${.CURDIR}/src
.PATH: ${.CURDIR}/noieee_src
-.if (${MACHINE_ARCH} != "vax")
-CFLAGS+= -D_MULTI_LIBM -D_POSIX_MODE
-.endif
-
LIB= m
WANTLINT=
COMMON_SRCS = b_exp__D.c b_log__D.c b_tgamma.c \
@@ -105,31 +69,34 @@ COMMON_SRCS = b_exp__D.c b_log__D.c b_tgamma.c \
e_atan2.c e_atan2f.c e_atanh.c e_atanhf.c e_cosh.c e_coshf.c e_exp.c \
e_expf.c e_fmod.c e_fmodf.c e_hypot.c e_hypotf.c e_j0.c e_j0f.c \
e_j1.c e_j1f.c e_jn.c e_jnf.c e_lgamma_r.c e_lgammaf_r.c e_log.c \
- e_log10.c e_log10f.c e_logf.c e_pow.c e_powf.c e_rem_pio2.c \
+ e_log10.c e_log10f.c e_log2.c e_log2f.c e_logf.c e_pow.c e_powf.c \
+ e_rem_pio2.c \
e_rem_pio2f.c e_remainder.c e_remainderf.c e_scalb.c e_scalbf.c \
e_sinh.c e_sinhf.c e_sqrt.c e_sqrtf.c \
k_cos.c k_cosf.c k_rem_pio2.c k_rem_pio2f.c k_sin.c k_sinf.c \
- k_standard.c k_tan.c k_tanf.c \
+ k_tan.c k_tanf.c \
s_lround.c s_lroundf.c s_llround.c s_llroundf.c \
- s_asinh.c s_asinhf.c s_atan.c s_atanf.c s_cbrt.c s_cbrtf.c s_ceil.c \
- s_ceilf.c s_copysign.c s_copysignf.c s_cos.c s_cosf.c s_erf.c s_erff.c \
- s_exp2.c s_exp2f.c s_expm1.c s_expm1f.c s_fabsf.c s_finite.c s_finitef.c \
+ s_asinh.c s_asinhf.c s_atan.c s_atanf.c s_cabs.c s_cabsf.c s_cacos.c \
+ s_cacosf.c s_cacosh.c s_cacoshf.c s_carg.c s_cargf.c s_casin.c \
+ s_casinf.c s_casinh.c s_casinhf.c s_catan.c s_catanf.c s_catanh.c \
+ s_catanhf.c s_cbrt.c s_cbrtf.c s_conj.c s_conjf.c s_ccos.c s_ccosf.c \
+ s_ccosh.c s_ccoshf.c s_ceil.c \
+ s_ceilf.c s_cexp.c s_cexpf.c s_cimag.c s_cimagf.c s_clog.c s_clogf.c \
+ s_copysign.c s_copysignf.c s_cos.c s_cosf.c s_cpow.c s_cpowf.c \
+ s_cproj.c s_cprojf.c s_creal.c s_crealf.c s_csin.c s_csinf.c s_csinh.c \
+ s_csinhf.c s_csqrt.c s_csqrtf.c s_ctan.c s_ctanf.c s_ctanh.c \
+ s_ctanhf.c s_erf.c s_erff.c s_exp2.c s_exp2f.c s_expm1.c s_expm1f.c \
+ s_fabsf.c s_fdim.c s_fmax.c s_fmaxf.c s_fmin.c s_fminf.c s_finite.c \
+ s_finitef.c \
s_floor.c s_floorf.c s_frexpf.c s_ilogb.c s_ilogbf.c \
- s_ldexpf.c s_lib_version.c s_log1p.c \
+ s_ldexpf.c s_log1p.c \
s_log1pf.c s_logb.c s_logbf.c s_llrint.c s_llrintf.c s_lrint.c \
- s_lrintf.c s_matherr.c s_modff.c s_nan.c \
+ s_lrintf.c s_modff.c s_nan.c \
s_nextafter.c s_nextafterf.c s_remquo.c s_remquof.c s_rint.c \
s_rintf.c s_round.c s_roundf.c \
s_scalbn.c s_scalbnf.c s_signgam.c s_significand.c s_significandf.c \
- s_sin.c s_sinf.c s_tan.c s_tanf.c s_tanh.c s_tanhf.c s_trunc.c s_truncf.c \
- w_acos.c w_acosf.c w_acosh.c w_acoshf.c w_asin.c w_asinf.c w_atan2.c \
- w_atan2f.c w_atanh.c w_atanhf.c w_cabs.c w_cabsf.c w_cosh.c w_coshf.c \
- w_drem.c w_dremf.c w_exp.c w_expf.c w_fmod.c w_fmodf.c w_gamma.c \
- w_gamma_r.c w_gammaf.c w_gammaf_r.c w_hypot.c w_hypotf.c w_j0.c \
- w_j0f.c w_j1.c w_j1f.c w_jn.c w_jnf.c w_lgamma.c w_lgamma_r.c \
- w_lgammaf.c w_lgammaf_r.c w_log.c w_log10.c w_log10f.c w_logf.c \
- w_pow.c w_powf.c w_remainder.c w_remainderf.c w_scalb.c w_scalbf.c \
- w_sinh.c w_sinhf.c w_sqrt.c w_sqrtf.c
+ s_sin.c s_sinf.c s_tan.c s_tanf.c s_tanh.c s_tanhf.c s_trunc.c \
+ s_truncf.c w_drem.c w_dremf.c w_gamma.c w_gamma_r.c
# math routines for non-IEEE architectures.
NOIEEE_SRCS = n_asincos.c n_acosh.c n_asinh.c n_atan.c n_atanh.c n_cosh.c \
@@ -257,7 +224,7 @@ MLINKS+=trunc.3 truncf.3
#.endif
#e_acos.o:
-# cpp -D__LIBM_PRIVATE -D_USE_WRITE -D_MULTI_LIBM -D_POSIX_MODE \
+# cpp \
# /usr/src/lib/libm/arch/mc68881/e_acos.S | as -o e_acos.o
diff --git a/lib/libm/arch/amd64/e_acos.S b/lib/libm/arch/amd64/e_acos.S
index ecaa57f3c85..5b493c291e8 100644
--- a/lib/libm/arch/amd64/e_acos.S
+++ b/lib/libm/arch/amd64/e_acos.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_acos.S,v 1.3 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_acos.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
@@ -9,7 +9,7 @@
#include "abi.h"
/* acos = atan (sqrt(1 - x^2) / x) */
-ENTRY(__ieee754_acos)
+ENTRY(acos)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_ONE /* x */
fld %st(0)
diff --git a/lib/libm/arch/amd64/e_asin.S b/lib/libm/arch/amd64/e_asin.S
index dc22db5dea2..3e337c88453 100644
--- a/lib/libm/arch/amd64/e_asin.S
+++ b/lib/libm/arch/amd64/e_asin.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_asin.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_asin.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
@@ -9,7 +9,7 @@
#include "abi.h"
/* asin = atan (x / sqrt(1 - x^2)) */
-ENTRY(__ieee754_asin)
+ENTRY(asin)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_ONE /* x */
fld %st(0)
diff --git a/lib/libm/arch/amd64/e_atan2.S b/lib/libm/arch/amd64/e_atan2.S
index 11f5cf02af0..ac7c6bb627d 100644
--- a/lib/libm/arch/amd64/e_atan2.S
+++ b/lib/libm/arch/amd64/e_atan2.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_atan2.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_atan2.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
@@ -8,7 +8,7 @@
#include "abi.h"
-ENTRY(__ieee754_atan2)
+ENTRY(atan2)
XMM_TWO_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_ONE
fldl ARG_DOUBLE_TWO
diff --git a/lib/libm/arch/amd64/e_atan2f.S b/lib/libm/arch/amd64/e_atan2f.S
index c313367d836..77bd7cd4199 100644
--- a/lib/libm/arch/amd64/e_atan2f.S
+++ b/lib/libm/arch/amd64/e_atan2f.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_atan2f.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_atan2f.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
@@ -8,7 +8,7 @@
#include "abi.h"
-ENTRY(__ieee754_atan2f)
+ENTRY(atan2f)
XMM_TWO_ARG_FLOAT_PROLOGUE
flds ARG_FLOAT_ONE
flds ARG_FLOAT_TWO
diff --git a/lib/libm/arch/amd64/e_exp.S b/lib/libm/arch/amd64/e_exp.S
index 5ae6516e991..101e3c74804 100644
--- a/lib/libm/arch/amd64/e_exp.S
+++ b/lib/libm/arch/amd64/e_exp.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_exp.S,v 1.4 2006/03/19 00:01:04 kettenis Exp $ */
+/* $OpenBSD: e_exp.S,v 1.5 2008/09/07 20:36:08 martynas Exp $ */
/* $NetBSD: e_exp.S,v 1.12 2002/02/27 16:32:46 christos Exp $ */
/*
@@ -41,7 +41,7 @@
#include "abi.h"
/* e^x = 2^(x * log2(e)) */
-ENTRY(__ieee754_exp)
+ENTRY(exp)
XMM_ONE_ARG_DOUBLE_PROLOGUE
/*
* If x is +-Inf, then the subtraction would give Inf-Inf = NaN.
diff --git a/lib/libm/arch/amd64/e_fmod.S b/lib/libm/arch/amd64/e_fmod.S
index 4a4eb5d3f9f..71c8f9c3349 100644
--- a/lib/libm/arch/amd64/e_fmod.S
+++ b/lib/libm/arch/amd64/e_fmod.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_fmod.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_fmod.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
@@ -9,7 +9,7 @@
#include "abi.h"
-ENTRY(__ieee754_fmod)
+ENTRY(fmod)
XMM_TWO_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_TWO
fldl ARG_DOUBLE_ONE
diff --git a/lib/libm/arch/amd64/e_log.S b/lib/libm/arch/amd64/e_log.S
index f92ec13f303..e0293b2c05d 100644
--- a/lib/libm/arch/amd64/e_log.S
+++ b/lib/libm/arch/amd64/e_log.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_log.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_log.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
@@ -8,7 +8,7 @@
#include "abi.h"
-ENTRY(__ieee754_log)
+ENTRY(log)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldln2
fldl ARG_DOUBLE_ONE
diff --git a/lib/libm/arch/amd64/e_log10.S b/lib/libm/arch/amd64/e_log10.S
index 4c7fdd0fba2..d0439b55b03 100644
--- a/lib/libm/arch/amd64/e_log10.S
+++ b/lib/libm/arch/amd64/e_log10.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_log10.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_log10.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
@@ -8,7 +8,7 @@
#include "abi.h"
-ENTRY(__ieee754_log10)
+ENTRY(log10)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldlg2
fldl ARG_DOUBLE_ONE
diff --git a/lib/libm/arch/amd64/e_remainder.S b/lib/libm/arch/amd64/e_remainder.S
index a72ca5904f8..1971538cf05 100644
--- a/lib/libm/arch/amd64/e_remainder.S
+++ b/lib/libm/arch/amd64/e_remainder.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_remainder.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_remainder.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
@@ -8,7 +8,7 @@
#include "abi.h"
-ENTRY(__ieee754_remainder)
+ENTRY(remainder)
XMM_TWO_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_TWO
fldl ARG_DOUBLE_ONE
diff --git a/lib/libm/arch/amd64/e_remainderf.S b/lib/libm/arch/amd64/e_remainderf.S
index fe635ce83b2..c739332cb68 100644
--- a/lib/libm/arch/amd64/e_remainderf.S
+++ b/lib/libm/arch/amd64/e_remainderf.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_remainderf.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_remainderf.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
@@ -8,7 +8,7 @@
#include "abi.h"
-ENTRY(__ieee754_remainderf)
+ENTRY(remainderf)
XMM_TWO_ARG_FLOAT_PROLOGUE
flds ARG_FLOAT_TWO
flds ARG_FLOAT_ONE
diff --git a/lib/libm/arch/amd64/e_scalb.S b/lib/libm/arch/amd64/e_scalb.S
index 1f05561ada9..ac5549999d2 100644
--- a/lib/libm/arch/amd64/e_scalb.S
+++ b/lib/libm/arch/amd64/e_scalb.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_scalb.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_scalb.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
@@ -8,7 +8,7 @@
#include "abi.h"
-ENTRY(__ieee754_scalb)
+ENTRY(scalb)
XMM_TWO_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_TWO
fldl ARG_DOUBLE_ONE
diff --git a/lib/libm/arch/amd64/e_sqrt.S b/lib/libm/arch/amd64/e_sqrt.S
index 6b8a722a144..65f26380f0e 100644
--- a/lib/libm/arch/amd64/e_sqrt.S
+++ b/lib/libm/arch/amd64/e_sqrt.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_sqrt.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_sqrt.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
@@ -6,7 +6,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_sqrt)
+ENTRY(sqrt)
#ifdef __i386__
fldl 4(%esp)
fsqrt
diff --git a/lib/libm/arch/amd64/e_sqrtf.S b/lib/libm/arch/amd64/e_sqrtf.S
index f49826a0ced..599358f70f8 100644
--- a/lib/libm/arch/amd64/e_sqrtf.S
+++ b/lib/libm/arch/amd64/e_sqrtf.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_sqrtf.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_sqrtf.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
@@ -6,7 +6,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_sqrtf)
+ENTRY(sqrtf)
#ifdef __i386__
flds 4(%esp)
fsqrt
diff --git a/lib/libm/arch/hppa/e_remainder.c b/lib/libm/arch/hppa/e_remainder.c
index 15db821d42c..0098c39c911 100644
--- a/lib/libm/arch/hppa/e_remainder.c
+++ b/lib/libm/arch/hppa/e_remainder.c
@@ -3,13 +3,13 @@
*/
#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: e_remainder.c,v 1.1 2002/05/22 21:34:56 mickey Exp $";
+static char rcsid[] = "$OpenBSD: e_remainder.c,v 1.2 2008/09/07 20:36:08 martynas Exp $";
#endif
#include "math.h"
double
-__ieee754_remainder(double x, double p)
+remainder(double x, double p)
{
__asm__ __volatile__("frem,dbl %0,%1,%0" : "+f" (x) : "f" (p));
diff --git a/lib/libm/arch/hppa/e_remainderf.c b/lib/libm/arch/hppa/e_remainderf.c
index b39314978b7..87e0871ec27 100644
--- a/lib/libm/arch/hppa/e_remainderf.c
+++ b/lib/libm/arch/hppa/e_remainderf.c
@@ -3,13 +3,13 @@
*/
#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: e_remainderf.c,v 1.2 2004/05/22 23:36:27 mickey Exp $";
+static char rcsid[] = "$OpenBSD: e_remainderf.c,v 1.3 2008/09/07 20:36:08 martynas Exp $";
#endif
#include "math.h"
float
-__ieee754_remainderf(float x, float p)
+remainderf(float x, float p)
{
__asm__ __volatile__("frem,sgl %0,%1,%0" : "+f" (x) : "f" (p));
diff --git a/lib/libm/arch/hppa/e_sqrt.c b/lib/libm/arch/hppa/e_sqrt.c
index 1345f287269..5c2663a6934 100644
--- a/lib/libm/arch/hppa/e_sqrt.c
+++ b/lib/libm/arch/hppa/e_sqrt.c
@@ -3,13 +3,13 @@
*/
#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: e_sqrt.c,v 1.1 2002/05/22 20:55:56 mickey Exp $";
+static char rcsid[] = "$OpenBSD: e_sqrt.c,v 1.2 2008/09/07 20:36:08 martynas Exp $";
#endif
#include "math.h"
double
-__ieee754_sqrt(double x)
+sqrt(double x)
{
__asm__ __volatile__ ("fsqrt,dbl %0, %0" : "+f" (x));
return (x);
diff --git a/lib/libm/arch/hppa/e_sqrtf.c b/lib/libm/arch/hppa/e_sqrtf.c
index 81ba8ba38f4..c5fff115f13 100644
--- a/lib/libm/arch/hppa/e_sqrtf.c
+++ b/lib/libm/arch/hppa/e_sqrtf.c
@@ -3,13 +3,13 @@
*/
#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: e_sqrtf.c,v 1.1 2002/05/22 20:55:56 mickey Exp $";
+static char rcsid[] = "$OpenBSD: e_sqrtf.c,v 1.2 2008/09/07 20:36:08 martynas Exp $";
#endif
#include "math.h"
float
-__ieee754_sqrtf(float x)
+sqrtf(float x)
{
__asm__ __volatile__ ("fsqrt,sgl %0, %0" : "+f" (x));
return (x);
diff --git a/lib/libm/arch/i387/e_acos.S b/lib/libm/arch/i387/e_acos.S
index 154cb6f6621..d85aaad3e26 100644
--- a/lib/libm/arch/i387/e_acos.S
+++ b/lib/libm/arch/i387/e_acos.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_acos.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_acos.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
@@ -7,7 +7,7 @@
#include <machine/asm.h>
/* acos = atan (sqrt(1 - x^2) / x) */
-ENTRY(__ieee754_acos)
+ENTRY(acos)
fldl 4(%esp) /* x */
fst %st(1)
fmul %st(0) /* x^2 */
diff --git a/lib/libm/arch/i387/e_asin.S b/lib/libm/arch/i387/e_asin.S
index 0692cf3598d..bb3d0f95bfa 100644
--- a/lib/libm/arch/i387/e_asin.S
+++ b/lib/libm/arch/i387/e_asin.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_asin.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_asin.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
@@ -7,7 +7,7 @@
#include <machine/asm.h>
/* asin = atan (x / sqrt(1 - x^2)) */
-ENTRY(__ieee754_asin)
+ENTRY(asin)
fldl 4(%esp) /* x */
fst %st(1)
fmul %st(0) /* x^2 */
diff --git a/lib/libm/arch/i387/e_atan2.S b/lib/libm/arch/i387/e_atan2.S
index d36838a358f..9057bd97eea 100644
--- a/lib/libm/arch/i387/e_atan2.S
+++ b/lib/libm/arch/i387/e_atan2.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_atan2.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_atan2.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
@@ -6,7 +6,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_atan2)
+ENTRY(atan2)
fldl 4(%esp)
fldl 12(%esp)
fpatan
diff --git a/lib/libm/arch/i387/e_atan2f.S b/lib/libm/arch/i387/e_atan2f.S
index 747f30832ac..734d101c977 100644
--- a/lib/libm/arch/i387/e_atan2f.S
+++ b/lib/libm/arch/i387/e_atan2f.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_atan2f.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_atan2f.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
@@ -6,7 +6,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_atan2f)
+ENTRY(atan2f)
flds 4(%esp)
flds 8(%esp)
fpatan
diff --git a/lib/libm/arch/i387/e_exp.S b/lib/libm/arch/i387/e_exp.S
index 3880dbc4311..2d085df48d9 100644
--- a/lib/libm/arch/i387/e_exp.S
+++ b/lib/libm/arch/i387/e_exp.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_exp.S,v 1.7 2006/03/18 23:56:14 kettenis Exp $ */
+/* $OpenBSD: e_exp.S,v 1.8 2008/09/07 20:36:08 martynas Exp $ */
/* $NetBSD: e_exp.S,v 1.12 2002/02/27 16:32:46 christos Exp $ */
/*
@@ -39,7 +39,7 @@
#include <machine/asm.h>
/* e^x = 2^(x * log2(e)) */
-ENTRY(__ieee754_exp)
+ENTRY(exp)
/*
* If x is +-Inf, then the subtraction would give Inf-Inf = NaN.
* Avoid this. Also avoid it if x is NaN for convenience.
diff --git a/lib/libm/arch/i387/e_fmod.S b/lib/libm/arch/i387/e_fmod.S
index c4e6790e9e3..daa1dfa34a7 100644
--- a/lib/libm/arch/i387/e_fmod.S
+++ b/lib/libm/arch/i387/e_fmod.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_fmod.S,v 1.3 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_fmod.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
@@ -6,7 +6,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_fmod)
+ENTRY(fmod)
fldl 12(%esp)
fldl 4(%esp)
1: fprem
diff --git a/lib/libm/arch/i387/e_log.S b/lib/libm/arch/i387/e_log.S
index 2b50032caa3..54e9423f03c 100644
--- a/lib/libm/arch/i387/e_log.S
+++ b/lib/libm/arch/i387/e_log.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_log.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_log.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
@@ -6,7 +6,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_log)
+ENTRY(log)
fldln2
fldl 4(%esp)
fyl2x
diff --git a/lib/libm/arch/i387/e_log10.S b/lib/libm/arch/i387/e_log10.S
index 71cb29b5a66..4045a56ee6a 100644
--- a/lib/libm/arch/i387/e_log10.S
+++ b/lib/libm/arch/i387/e_log10.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_log10.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_log10.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
@@ -6,7 +6,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_log10)
+ENTRY(log10)
fldlg2
fldl 4(%esp)
fyl2x
diff --git a/lib/libm/arch/i387/e_remainder.S b/lib/libm/arch/i387/e_remainder.S
index 86f7d761f3d..a9f31df1b17 100644
--- a/lib/libm/arch/i387/e_remainder.S
+++ b/lib/libm/arch/i387/e_remainder.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_remainder.S,v 1.3 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_remainder.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
@@ -6,7 +6,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_remainder)
+ENTRY(remainder)
fldl 12(%esp)
fldl 4(%esp)
1: fprem1
diff --git a/lib/libm/arch/i387/e_remainderf.S b/lib/libm/arch/i387/e_remainderf.S
index 39a09370407..dc92ee23dfd 100644
--- a/lib/libm/arch/i387/e_remainderf.S
+++ b/lib/libm/arch/i387/e_remainderf.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_remainderf.S,v 1.3 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_remainderf.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
@@ -6,7 +6,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_remainderf)
+ENTRY(remainderf)
flds 8(%esp)
flds 4(%esp)
1: fprem1
diff --git a/lib/libm/arch/i387/e_scalb.S b/lib/libm/arch/i387/e_scalb.S
index 65ab69e39de..b515d76e713 100644
--- a/lib/libm/arch/i387/e_scalb.S
+++ b/lib/libm/arch/i387/e_scalb.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_scalb.S,v 1.3 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_scalb.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
@@ -6,7 +6,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_scalb)
+ENTRY(scalb)
fldl 12(%esp)
fldl 4(%esp)
fscale
diff --git a/lib/libm/arch/i387/e_sqrt.S b/lib/libm/arch/i387/e_sqrt.S
index aa5402f5e01..9e9e5854679 100644
--- a/lib/libm/arch/i387/e_sqrt.S
+++ b/lib/libm/arch/i387/e_sqrt.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_sqrt.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_sqrt.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
@@ -6,7 +6,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_sqrt)
+ENTRY(sqrt)
fldl 4(%esp)
fsqrt
ret
diff --git a/lib/libm/arch/i387/e_sqrtf.S b/lib/libm/arch/i387/e_sqrtf.S
index 8de86dffe38..f6e30ef258f 100644
--- a/lib/libm/arch/i387/e_sqrtf.S
+++ b/lib/libm/arch/i387/e_sqrtf.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_sqrtf.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
+/* $OpenBSD: e_sqrtf.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
@@ -6,7 +6,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_sqrtf)
+ENTRY(sqrtf)
flds 4(%esp)
fsqrt
ret
diff --git a/lib/libm/arch/mc68881/e_acos.S b/lib/libm/arch/mc68881/e_acos.S
index 6920f26124d..b37d54ba829 100644
--- a/lib/libm/arch/mc68881/e_acos.S
+++ b/lib/libm/arch/mc68881/e_acos.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_acos.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */
+/* $OpenBSD: e_acos.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -34,7 +34,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_acos)
+ENTRY(acos)
facosd sp@(4),fp0
fmoved fp0,sp@-
movel sp@+,d0
diff --git a/lib/libm/arch/mc68881/e_asin.S b/lib/libm/arch/mc68881/e_asin.S
index ea94bc0b637..38d8910cd1f 100644
--- a/lib/libm/arch/mc68881/e_asin.S
+++ b/lib/libm/arch/mc68881/e_asin.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_asin.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */
+/* $OpenBSD: e_asin.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -34,7 +34,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_asin)
+ENTRY(asin)
fasind sp@(4),fp0
fmoved fp0,sp@-
movel sp@+,d0
diff --git a/lib/libm/arch/mc68881/e_atanh.S b/lib/libm/arch/mc68881/e_atanh.S
index ab74bfe7534..4084b0b3bff 100644
--- a/lib/libm/arch/mc68881/e_atanh.S
+++ b/lib/libm/arch/mc68881/e_atanh.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_atanh.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */
+/* $OpenBSD: e_atanh.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -34,7 +34,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_atanh)
+ENTRY(atanh)
fatanhd sp@(4),fp0
fmoved fp0,sp@-
movel sp@+,d0
diff --git a/lib/libm/arch/mc68881/e_cosh.S b/lib/libm/arch/mc68881/e_cosh.S
index 1b2ca0506ff..b2cf85b7cdb 100644
--- a/lib/libm/arch/mc68881/e_cosh.S
+++ b/lib/libm/arch/mc68881/e_cosh.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_cosh.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */
+/* $OpenBSD: e_cosh.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -34,7 +34,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_cosh)
+ENTRY(cosh)
fcoshd sp@(4),fp0
fmoved fp0,sp@-
movel sp@+,d0
diff --git a/lib/libm/arch/mc68881/e_exp.S b/lib/libm/arch/mc68881/e_exp.S
index 39920d4b480..3fd33ea1791 100644
--- a/lib/libm/arch/mc68881/e_exp.S
+++ b/lib/libm/arch/mc68881/e_exp.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_exp.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */
+/* $OpenBSD: e_exp.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -34,7 +34,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_exp)
+ENTRY(exp)
fetoxd sp@(4),fp0
fmoved fp0,sp@-
movel sp@+,d0
diff --git a/lib/libm/arch/mc68881/e_log.S b/lib/libm/arch/mc68881/e_log.S
index d8b03499e8a..ecca1c78db9 100644
--- a/lib/libm/arch/mc68881/e_log.S
+++ b/lib/libm/arch/mc68881/e_log.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_log.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */
+/* $OpenBSD: e_log.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -34,7 +34,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_log)
+ENTRY(log)
flognd sp@(4),fp0
fmoved fp0,sp@-
movel sp@+,d0
diff --git a/lib/libm/arch/mc68881/e_log10.S b/lib/libm/arch/mc68881/e_log10.S
index d057e409f70..9be1b63c0b5 100644
--- a/lib/libm/arch/mc68881/e_log10.S
+++ b/lib/libm/arch/mc68881/e_log10.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_log10.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */
+/* $OpenBSD: e_log10.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -34,7 +34,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_log10)
+ENTRY(log10)
flog10d sp@(4),fp0
fmoved fp0,sp@-
movel sp@+,d0
diff --git a/lib/libm/arch/mc68881/e_remainder.S b/lib/libm/arch/mc68881/e_remainder.S
index d4433fe858a..87dd01cfc63 100644
--- a/lib/libm/arch/mc68881/e_remainder.S
+++ b/lib/libm/arch/mc68881/e_remainder.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_remainder.S,v 1.2 2005/08/02 11:17:32 espie Exp $ */
+/* $OpenBSD: e_remainder.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
@@ -6,7 +6,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_remainder)
+ENTRY(remainder)
fmoved sp@(4),fp0
fremd sp@(12),fp0
fmoved fp0,sp@-
diff --git a/lib/libm/arch/mc68881/e_scalb.S b/lib/libm/arch/mc68881/e_scalb.S
index 724a6996bb4..f133e0621c1 100644
--- a/lib/libm/arch/mc68881/e_scalb.S
+++ b/lib/libm/arch/mc68881/e_scalb.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_scalb.S,v 1.2 2005/08/02 11:17:32 espie Exp $ */
+/* $OpenBSD: e_scalb.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
@@ -6,7 +6,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_scalb)
+ENTRY(scalb)
fmoved sp@(4),fp0
fbeq Ldone
fscaled sp@(12),fp0
diff --git a/lib/libm/arch/mc68881/e_sinh.S b/lib/libm/arch/mc68881/e_sinh.S
index 60a21c47c69..10e35b20882 100644
--- a/lib/libm/arch/mc68881/e_sinh.S
+++ b/lib/libm/arch/mc68881/e_sinh.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_sinh.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */
+/* $OpenBSD: e_sinh.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -34,7 +34,7 @@
#include <machine/asm.h>
-ENTRY(__ieee754_sinh)
+ENTRY(sinh)
fsinhd sp@(4),fp0
fmoved fp0,sp@-
movel sp@+,d0
diff --git a/lib/libm/arch/mc68881/e_sqrt.S b/lib/libm/arch/mc68881/e_sqrt.S
index 0639e5fcf7e..df4f21f01e1 100644
--- a/lib/libm/arch/mc68881/e_sqrt.S
+++ b/lib/libm/arch/mc68881/e_sqrt.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_sqrt.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */
+/* $OpenBSD: e_sqrt.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -40,7 +40,7 @@
* to the rounding mode.
*/
-ENTRY(__ieee754_sqrt)
+ENTRY(sqrt)
fsqrtd sp@(4),fp0
fmoved fp0,sp@-
movel sp@+,d0
diff --git a/lib/libm/shlib_version b/lib/libm/shlib_version
index 012c14171d3..d9961ea9fef 100644
--- a/lib/libm/shlib_version
+++ b/lib/libm/shlib_version
@@ -1,2 +1,2 @@
-major=3
+major=4
minor=0
diff --git a/lib/libm/src/e_acos.c b/lib/libm/src/e_acos.c
index a5301808768..2ae24586cc1 100644
--- a/lib/libm/src/e_acos.c
+++ b/lib/libm/src/e_acos.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_acos.c,v 1.9 1995/05/12 04:57:13 jtc Exp $";
#endif
-/* __ieee754_acos(x)
+/* acos(x)
* Method :
* acos(x) = pi/2 - asin(x)
* acos(-x) = pi/2 + asin(x)
@@ -35,7 +35,7 @@ static char rcsid[] = "$NetBSD: e_acos.c,v 1.9 1995/05/12 04:57:13 jtc Exp $";
* if x is NaN, return x itself;
* if |x|>1, return NaN with invalid signal.
*
- * Function needed: __ieee754_sqrt
+ * Function needed: sqrt
*/
#include "math.h"
@@ -58,7 +58,7 @@ qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
double
-__ieee754_acos(double x)
+acos(double x)
{
double z,p,q,r,w,s,c,df;
int32_t hx,ix;
@@ -84,13 +84,13 @@ __ieee754_acos(double x)
z = (one+x)*0.5;
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
- s = __ieee754_sqrt(z);
+ s = sqrt(z);
r = p/q;
w = r*s-pio2_lo;
return pi - 2.0*(s+w);
} else { /* x > 0.5 */
z = (one-x)*0.5;
- s = __ieee754_sqrt(z);
+ s = sqrt(z);
df = s;
SET_LOW_WORD(df,0);
c = (z-df*df)/(s+df);
diff --git a/lib/libm/src/e_acosf.c b/lib/libm/src/e_acosf.c
index 5407842186c..57f42b18f8f 100644
--- a/lib/libm/src/e_acosf.c
+++ b/lib/libm/src/e_acosf.c
@@ -37,7 +37,7 @@ qS3 = -6.8828397989e-01, /* 0xbf303361 */
qS4 = 7.7038154006e-02; /* 0x3d9dc62e */
float
-__ieee754_acosf(float x)
+acosf(float x)
{
float z,p,q,r,w,s,c,df;
int32_t hx,ix;
@@ -60,14 +60,14 @@ __ieee754_acosf(float x)
z = (one+x)*(float)0.5;
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
- s = __ieee754_sqrtf(z);
+ s = sqrtf(z);
r = p/q;
w = r*s-pio2_lo;
return pi - (float)2.0*(s+w);
} else { /* x > 0.5 */
int32_t idf;
z = (one-x)*(float)0.5;
- s = __ieee754_sqrtf(z);
+ s = sqrtf(z);
df = s;
GET_FLOAT_WORD(idf,df);
SET_FLOAT_WORD(df,idf&0xfffff000);
diff --git a/lib/libm/src/e_acosh.c b/lib/libm/src/e_acosh.c
index fbfb65e09d0..273b93d02a6 100644
--- a/lib/libm/src/e_acosh.c
+++ b/lib/libm/src/e_acosh.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_acosh.c,v 1.9 1995/05/12 04:57:18 jtc Exp $";
#endif
-/* __ieee754_acosh(x)
+/* acosh(x)
* Method :
* Based on
* acosh(x) = log [ x + sqrt(x*x-1) ]
@@ -36,7 +36,7 @@ one = 1.0,
ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */
double
-__ieee754_acosh(double x)
+acosh(double x)
{
double t;
int32_t hx;
@@ -48,12 +48,12 @@ __ieee754_acosh(double x)
if(hx >=0x7ff00000) { /* x is inf of NaN */
return x+x;
} else
- return __ieee754_log(x)+ln2; /* acosh(huge)=log(2x) */
+ return log(x)+ln2; /* acosh(huge)=log(2x) */
} else if(((hx-0x3ff00000)|lx)==0) {
return 0.0; /* acosh(1) = 0 */
} else if (hx > 0x40000000) { /* 2**28 > x > 2 */
t=x*x;
- return __ieee754_log(2.0*x-one/(x+__ieee754_sqrt(t-one)));
+ return log(2.0*x-one/(x+sqrt(t-one)));
} else { /* 1<x<2 */
t = x-one;
return log1p(t+sqrt(2.0*t+t*t));
diff --git a/lib/libm/src/e_acoshf.c b/lib/libm/src/e_acoshf.c
index 6e3b1e96870..515d33daf0c 100644
--- a/lib/libm/src/e_acoshf.c
+++ b/lib/libm/src/e_acoshf.c
@@ -25,7 +25,7 @@ one = 1.0,
ln2 = 6.9314718246e-01; /* 0x3f317218 */
float
-__ieee754_acoshf(float x)
+acoshf(float x)
{
float t;
int32_t hx;
@@ -36,12 +36,12 @@ __ieee754_acoshf(float x)
if(hx >=0x7f800000) { /* x is inf of NaN */
return x+x;
} else
- return __ieee754_logf(x)+ln2; /* acosh(huge)=log(2x) */
+ return logf(x)+ln2; /* acosh(huge)=log(2x) */
} else if (hx==0x3f800000) {
return 0.0; /* acosh(1) = 0 */
} else if (hx > 0x40000000) { /* 2**28 > x > 2 */
t=x*x;
- return __ieee754_logf((float)2.0*x-one/(x+__ieee754_sqrtf(t-one)));
+ return logf((float)2.0*x-one/(x+sqrtf(t-one)));
} else { /* 1<x<2 */
t = x-one;
return log1pf(t+sqrtf((float)2.0*t+t*t));
diff --git a/lib/libm/src/e_asin.c b/lib/libm/src/e_asin.c
index 0d358012280..4c732971e40 100644
--- a/lib/libm/src/e_asin.c
+++ b/lib/libm/src/e_asin.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_asin.c,v 1.9 1995/05/12 04:57:22 jtc Exp $";
#endif
-/* __ieee754_asin(x)
+/* asin(x)
* Method :
* Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
* we approximate asin(x) on [0,0.5] by
@@ -67,7 +67,7 @@ qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
double
-__ieee754_asin(double x)
+asin(double x)
{
double t,w,p,q,c,r,s;
int32_t hx,ix;
@@ -95,7 +95,7 @@ __ieee754_asin(double x)
t = w*0.5;
p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
- s = __ieee754_sqrt(t);
+ s = sqrt(t);
if(ix>=0x3FEF3333) { /* if |x| > 0.975 */
w = p/q;
t = pio2_hi-(2.0*(s+s*w)-pio2_lo);
diff --git a/lib/libm/src/e_asinf.c b/lib/libm/src/e_asinf.c
index f4e780847ed..3f70199fbc9 100644
--- a/lib/libm/src/e_asinf.c
+++ b/lib/libm/src/e_asinf.c
@@ -39,7 +39,7 @@ qS3 = -6.8828397989e-01, /* 0xbf303361 */
qS4 = 7.7038154006e-02; /* 0x3d9dc62e */
float
-__ieee754_asinf(float x)
+asinf(float x)
{
float t,w,p,q,c,r,s;
int32_t hx,ix;
@@ -65,7 +65,7 @@ __ieee754_asinf(float x)
t = w*(float)0.5;
p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
- s = __ieee754_sqrtf(t);
+ s = sqrtf(t);
if(ix>=0x3F79999A) { /* if |x| > 0.975 */
w = p/q;
t = pio2_hi-((float)2.0*(s+s*w)-pio2_lo);
diff --git a/lib/libm/src/e_atan2.c b/lib/libm/src/e_atan2.c
index d469450efe0..f8a0330dcb8 100644
--- a/lib/libm/src/e_atan2.c
+++ b/lib/libm/src/e_atan2.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_atan2.c,v 1.8 1995/05/10 20:44:51 jtc Exp $";
#endif
-/* __ieee754_atan2(y,x)
+/* atan2(y,x)
* Method :
* 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
* 2. Reduce x to positive by (if x and y are unexceptional):
@@ -53,7 +53,7 @@ pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
double
-__ieee754_atan2(double y, double x)
+atan2(double y, double x)
{
double z;
int32_t k,m,hx,hy,ix,iy;
diff --git a/lib/libm/src/e_atan2f.c b/lib/libm/src/e_atan2f.c
index ead3b133972..0855bd4ffb5 100644
--- a/lib/libm/src/e_atan2f.c
+++ b/lib/libm/src/e_atan2f.c
@@ -29,7 +29,7 @@ pi = 3.1415925026e+00, /* 0x40490fda */
pi_lo = 1.5099578832e-07; /* 0x34222168 */
float
-__ieee754_atan2f(float y, float x)
+atan2f(float y, float x)
{
float z;
int32_t k,m,hx,hy,ix,iy;
diff --git a/lib/libm/src/e_atanh.c b/lib/libm/src/e_atanh.c
index fd9d952b61f..1cd468b8e56 100644
--- a/lib/libm/src/e_atanh.c
+++ b/lib/libm/src/e_atanh.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_atanh.c,v 1.8 1995/05/10 20:44:55 jtc Exp $";
#endif
-/* __ieee754_atanh(x)
+/* atanh(x)
* Method :
* 1.Reduced x to positive by atanh(-x) = -atanh(x)
* 2.For x>=0.5
@@ -39,7 +39,7 @@ static const double one = 1.0, huge = 1e300;
static const double zero = 0.0;
double
-__ieee754_atanh(double x)
+atanh(double x)
{
double t;
int32_t hx,ix;
diff --git a/lib/libm/src/e_atanhf.c b/lib/libm/src/e_atanhf.c
index 8d912239224..40322c2cf0c 100644
--- a/lib/libm/src/e_atanhf.c
+++ b/lib/libm/src/e_atanhf.c
@@ -24,7 +24,7 @@ static const float one = 1.0, huge = 1e30;
static const float zero = 0.0;
float
-__ieee754_atanhf(float x)
+atanhf(float x)
{
float t;
int32_t hx,ix;
diff --git a/lib/libm/src/e_cosh.c b/lib/libm/src/e_cosh.c
index 4d7b61bfdc9..afad33162af 100644
--- a/lib/libm/src/e_cosh.c
+++ b/lib/libm/src/e_cosh.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_cosh.c,v 1.7 1995/05/10 20:44:58 jtc Exp $";
#endif
-/* __ieee754_cosh(x)
+/* cosh(x)
* Method :
* mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
* 1. Replace x by |x| (cosh(x) = cosh(-x)).
@@ -41,7 +41,7 @@ static char rcsid[] = "$NetBSD: e_cosh.c,v 1.7 1995/05/10 20:44:58 jtc Exp $";
static const double one = 1.0, half=0.5, huge = 1.0e300;
double
-__ieee754_cosh(double x)
+cosh(double x)
{
double t,w;
int32_t ix;
@@ -64,18 +64,18 @@ __ieee754_cosh(double x)
/* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
if (ix < 0x40360000) {
- t = __ieee754_exp(fabs(x));
+ t = exp(fabs(x));
return half*t+half/t;
}
/* |x| in [22, log(maxdouble)] return half*exp(|x|) */
- if (ix < 0x40862E42) return half*__ieee754_exp(fabs(x));
+ if (ix < 0x40862E42) return half*exp(fabs(x));
/* |x| in [log(maxdouble), overflowthresold] */
GET_LOW_WORD(lx,x);
if (ix<0x408633CE ||
((ix==0x408633ce)&&(lx<=(u_int32_t)0x8fb9f87d))) {
- w = __ieee754_exp(half*fabs(x));
+ w = exp(half*fabs(x));
t = half*w;
return t*w;
}
diff --git a/lib/libm/src/e_coshf.c b/lib/libm/src/e_coshf.c
index ae52f14d7a3..29eb56cfd4e 100644
--- a/lib/libm/src/e_coshf.c
+++ b/lib/libm/src/e_coshf.c
@@ -24,7 +24,7 @@ static const volatile float huge = 1.0e30;
static const float one = 1.0, half=0.5;
float
-__ieee754_coshf(float x)
+coshf(float x)
{
float t,w;
int32_t ix;
@@ -45,16 +45,16 @@ __ieee754_coshf(float x)
/* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
if (ix < 0x41b00000) {
- t = __ieee754_expf(fabsf(x));
+ t = expf(fabsf(x));
return half*t+half/t;
}
/* |x| in [22, log(maxdouble)] return half*exp(|x|) */
- if (ix < 0x42b17180) return half*__ieee754_expf(fabsf(x));
+ if (ix < 0x42b17180) return half*expf(fabsf(x));
/* |x| in [log(maxdouble), overflowthresold] */
if (ix<=0x42b2d4fc) {
- w = __ieee754_expf(half*fabsf(x));
+ w = expf(half*fabsf(x));
t = half*w;
return t*w;
}
diff --git a/lib/libm/src/e_exp.c b/lib/libm/src/e_exp.c
index c9ecdecdc04..aef00ba006d 100644
--- a/lib/libm/src/e_exp.c
+++ b/lib/libm/src/e_exp.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_exp.c,v 1.8 1995/05/10 20:45:03 jtc Exp $";
#endif
-/* __ieee754_exp(x)
+/* exp(x)
* Returns the exponential of x.
*
* Method
@@ -100,7 +100,7 @@ P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
double
-__ieee754_exp(double x) /* default IEEE double exp */
+exp(double x) /* default IEEE double exp */
{
double y,hi,lo,c,t;
int32_t k,xsb;
diff --git a/lib/libm/src/e_expf.c b/lib/libm/src/e_expf.c
index 2457f286bb9..ac0fc40df09 100644
--- a/lib/libm/src/e_expf.c
+++ b/lib/libm/src/e_expf.c
@@ -40,7 +40,7 @@ P4 = -1.6533901999e-06, /* 0xb5ddea0e */
P5 = 4.1381369442e-08; /* 0x3331bb4c */
float
-__ieee754_expf(float x) /* default IEEE double exp */
+expf(float x) /* default IEEE double exp */
{
float y,hi,lo,c,t;
int32_t k,xsb;
diff --git a/lib/libm/src/e_fmod.c b/lib/libm/src/e_fmod.c
index 377dee8e569..1a85f8295c1 100644
--- a/lib/libm/src/e_fmod.c
+++ b/lib/libm/src/e_fmod.c
@@ -15,7 +15,7 @@ static char rcsid[] = "$NetBSD: e_fmod.c,v 1.8 1995/05/10 20:45:07 jtc Exp $";
#endif
/*
- * __ieee754_fmod(x,y)
+ * fmod(x,y)
* Return x mod y in exact arithmetic
* Method: shift and subtract
*/
@@ -26,7 +26,7 @@ static char rcsid[] = "$NetBSD: e_fmod.c,v 1.8 1995/05/10 20:45:07 jtc Exp $";
static const double one = 1.0, Zero[] = {0.0, -0.0,};
double
-__ieee754_fmod(double x, double y)
+fmod(double x, double y)
{
int32_t n,hx,hy,hz,ix,iy,sx,i;
u_int32_t lx,ly,lz;
diff --git a/lib/libm/src/e_fmodf.c b/lib/libm/src/e_fmodf.c
index 5313a0efdf9..0bb8d172925 100644
--- a/lib/libm/src/e_fmodf.c
+++ b/lib/libm/src/e_fmodf.c
@@ -18,7 +18,7 @@ static char rcsid[] = "$NetBSD: e_fmodf.c,v 1.4 1995/05/10 20:45:10 jtc Exp $";
#endif
/*
- * __ieee754_fmodf(x,y)
+ * fmodf(x,y)
* Return x mod y in exact arithmetic
* Method: shift and subtract
*/
@@ -29,7 +29,7 @@ static char rcsid[] = "$NetBSD: e_fmodf.c,v 1.4 1995/05/10 20:45:10 jtc Exp $";
static const float one = 1.0, Zero[] = {0.0, -0.0,};
float
-__ieee754_fmodf(float x, float y)
+fmodf(float x, float y)
{
int32_t n,hx,hy,hz,ix,iy,sx,i;
diff --git a/lib/libm/src/e_hypot.c b/lib/libm/src/e_hypot.c
index 6dc49042b63..23cf67f766d 100644
--- a/lib/libm/src/e_hypot.c
+++ b/lib/libm/src/e_hypot.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_hypot.c,v 1.9 1995/05/12 04:57:27 jtc Exp $";
#endif
-/* __ieee754_hypot(x,y)
+/* hypot(x,y)
*
* Method :
* If (assume round-to-nearest) z=x*x+y*y
@@ -50,7 +50,7 @@ static char rcsid[] = "$NetBSD: e_hypot.c,v 1.9 1995/05/12 04:57:27 jtc Exp $";
#include "math_private.h"
double
-__ieee754_hypot(double x, double y)
+hypot(double x, double y)
{
double a=x,b=y,t1,t2,yy1,y2,w;
int32_t j,k,ha,hb;
@@ -103,7 +103,7 @@ __ieee754_hypot(double x, double y)
t1 = 0;
SET_HIGH_WORD(t1,ha);
t2 = a-t1;
- w = __ieee754_sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
+ w = sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
} else {
a = a+a;
yy1 = 0;
@@ -112,7 +112,7 @@ __ieee754_hypot(double x, double y)
t1 = 0;
SET_HIGH_WORD(t1,ha+0x00100000);
t2 = a - t1;
- w = __ieee754_sqrt(t1*yy1-(w*(-w)-(t1*y2+t2*b)));
+ w = sqrt(t1*yy1-(w*(-w)-(t1*y2+t2*b)));
}
if(k!=0) {
u_int32_t high;
diff --git a/lib/libm/src/e_hypotf.c b/lib/libm/src/e_hypotf.c
index db781f5dfdc..863899f2ef6 100644
--- a/lib/libm/src/e_hypotf.c
+++ b/lib/libm/src/e_hypotf.c
@@ -21,7 +21,7 @@ static char rcsid[] = "$NetBSD: e_hypotf.c,v 1.5 1995/05/12 04:57:30 jtc Exp $";
#include "math_private.h"
float
-__ieee754_hypotf(float x, float y)
+hypotf(float x, float y)
{
float a=x,b=y,t1,t2,yy1,y2,w;
int32_t j,k,ha,hb;
@@ -67,14 +67,14 @@ __ieee754_hypotf(float x, float y)
if (w>b) {
SET_FLOAT_WORD(t1,ha&0xfffff000);
t2 = a-t1;
- w = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
+ w = sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
} else {
a = a+a;
SET_FLOAT_WORD(yy1,hb&0xfffff000);
y2 = b - yy1;
SET_FLOAT_WORD(t1,ha+0x00800000);
t2 = a - t1;
- w = __ieee754_sqrtf(t1*yy1-(w*(-w)-(t1*y2+t2*b)));
+ w = sqrtf(t1*yy1-(w*(-w)-(t1*y2+t2*b)));
}
if(k!=0) {
SET_FLOAT_WORD(t1,0x3f800000+(k<<23));
diff --git a/lib/libm/src/e_j0.c b/lib/libm/src/e_j0.c
index d49297ca8f3..ef34cb7887b 100644
--- a/lib/libm/src/e_j0.c
+++ b/lib/libm/src/e_j0.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_j0.c,v 1.8 1995/05/10 20:45:23 jtc Exp $";
#endif
-/* __ieee754_j0(x), __ieee754_y0(x)
+/* j0(x), y0(x)
* Bessel function of the first and second kinds of order zero.
* Method -- j0(x):
* 1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ...
@@ -82,7 +82,7 @@ S04 = 1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */
static const double zero = 0.0;
double
-__ieee754_j0(double x)
+j0(double x)
{
double z, s,c,ss,cc,r,u,v;
int32_t hx,ix;
@@ -143,7 +143,7 @@ v03 = 2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */
v04 = 4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */
double
-__ieee754_y0(double x)
+y0(double x)
{
double z, s,c,ss,cc,u,v;
int32_t hx,ix,lx;
@@ -187,12 +187,12 @@ __ieee754_y0(double x)
return z;
}
if(ix<=0x3e400000) { /* x < 2**-27 */
- return(u00 + tpi*__ieee754_log(x));
+ return(u00 + tpi*log(x));
}
z = x*x;
u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
v = one+z*(v01+z*(v02+z*(v03+z*v04)));
- return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x)));
+ return(u/v + tpi*(j0(x)*log(x)));
}
/* The asymptotic expansions of pzero is
diff --git a/lib/libm/src/e_j0f.c b/lib/libm/src/e_j0f.c
index 02471711017..f5000adf5b6 100644
--- a/lib/libm/src/e_j0f.c
+++ b/lib/libm/src/e_j0f.c
@@ -40,7 +40,7 @@ S04 = 1.1661400734e-09; /* 0x30a045e8 */
static const float zero = 0.0;
float
-__ieee754_j0f(float x)
+j0f(float x)
{
float z, s,c,ss,cc,r,u,v;
int32_t hx,ix;
@@ -101,7 +101,7 @@ v03 = 2.5915085189e-07, /* 0x348b216c */
v04 = 4.4111031494e-10; /* 0x2ff280c2 */
float
-__ieee754_y0f(float x)
+y0f(float x)
{
float z, s,c,ss,cc,u,v;
int32_t hx,ix;
@@ -145,12 +145,12 @@ __ieee754_y0f(float x)
return z;
}
if(ix<=0x32000000) { /* x < 2**-27 */
- return(u00 + tpi*__ieee754_logf(x));
+ return(u00 + tpi*logf(x));
}
z = x*x;
u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
v = one+z*(v01+z*(v02+z*(v03+z*v04)));
- return(u/v + tpi*(__ieee754_j0f(x)*__ieee754_logf(x)));
+ return(u/v + tpi*(j0f(x)*logf(x)));
}
/* The asymptotic expansions of pzero is
diff --git a/lib/libm/src/e_j1.c b/lib/libm/src/e_j1.c
index 372767ad582..3a783c80f08 100644
--- a/lib/libm/src/e_j1.c
+++ b/lib/libm/src/e_j1.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_j1.c,v 1.8 1995/05/10 20:45:27 jtc Exp $";
#endif
-/* __ieee754_j1(x), __ieee754_y1(x)
+/* j1(x), y1(x)
* Bessel function of the first and second kinds of order zero.
* Method -- j1(x):
* 1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ...
@@ -83,7 +83,7 @@ s05 = 1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */
static const double zero = 0.0;
double
-__ieee754_j1(double x)
+j1(double x)
{
double z, s,c,ss,cc,r,u,v,y;
int32_t hx,ix;
@@ -140,7 +140,7 @@ static const double V0[5] = {
};
double
-__ieee754_y1(double x)
+y1(double x)
{
double z, s,c,ss,cc,u,v;
int32_t hx,ix,lx;
@@ -185,7 +185,7 @@ __ieee754_y1(double x)
z = x*x;
u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
- return(x*(u/v) + tpi*(__ieee754_j1(x)*__ieee754_log(x)-one/x));
+ return(x*(u/v) + tpi*(j1(x)*log(x)-one/x));
}
/* For x >= 8, the asymptotic expansions of pone is
diff --git a/lib/libm/src/e_j1f.c b/lib/libm/src/e_j1f.c
index bccc8f68ccc..62b34072ea8 100644
--- a/lib/libm/src/e_j1f.c
+++ b/lib/libm/src/e_j1f.c
@@ -41,7 +41,7 @@ s05 = 1.2354227016e-11; /* 0x2d59567e */
static const float zero = 0.0;
float
-__ieee754_j1f(float x)
+j1f(float x)
{
float z, s,c,ss,cc,r,u,v,y;
int32_t hx,ix;
@@ -98,7 +98,7 @@ static const float V0[5] = {
};
float
-__ieee754_y1f(float x)
+y1f(float x)
{
float z, s,c,ss,cc,u,v;
int32_t hx,ix;
@@ -143,7 +143,7 @@ __ieee754_y1f(float x)
z = x*x;
u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
- return(x*(u/v) + tpi*(__ieee754_j1f(x)*__ieee754_logf(x)-one/x));
+ return(x*(u/v) + tpi*(j1f(x)*logf(x)-one/x));
}
/* For x >= 8, the asymptotic expansions of pone is
diff --git a/lib/libm/src/e_jn.c b/lib/libm/src/e_jn.c
index ada373aa6b4..f22231a8e97 100644
--- a/lib/libm/src/e_jn.c
+++ b/lib/libm/src/e_jn.c
@@ -15,7 +15,7 @@ static char rcsid[] = "$NetBSD: e_jn.c,v 1.9 1995/05/10 20:45:34 jtc Exp $";
#endif
/*
- * __ieee754_jn(n, x), __ieee754_yn(n, x)
+ * jn(n, x), yn(n, x)
* floating point Bessel's function of the 1st and 2nd kind
* of order n
*
@@ -51,7 +51,7 @@ one = 1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */
static const double zero = 0.00000000000000000000e+00;
double
-__ieee754_jn(int n, double x)
+jn(int n, double x)
{
int32_t i,hx,ix,lx, sgn;
double a, b, temp, di;
@@ -69,8 +69,8 @@ __ieee754_jn(int n, double x)
x = -x;
hx ^= 0x80000000;
}
- if(n==0) return(__ieee754_j0(x));
- if(n==1) return(__ieee754_j1(x));
+ if(n==0) return(j0(x));
+ if(n==1) return(j1(x));
sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */
x = fabs(x);
if((ix|lx)==0||ix>=0x7ff00000) /* if x is 0 or inf */
@@ -99,8 +99,8 @@ __ieee754_jn(int n, double x)
}
b = invsqrtpi*temp/sqrt(x);
} else {
- a = __ieee754_j0(x);
- b = __ieee754_j1(x);
+ a = j0(x);
+ b = j1(x);
for(i=1;i<n;i++){
temp = b;
b = b*((double)(i+i)/x) - a; /* avoid underflow */
@@ -176,7 +176,7 @@ __ieee754_jn(int n, double x)
*/
tmp = n;
v = two/x;
- tmp = tmp*__ieee754_log(fabs(v*tmp));
+ tmp = tmp*log(fabs(v*tmp));
if(tmp<7.09782712893383973096e+02) {
for(i=n-1,di=(double)(i+i);i>0;i--){
temp = b;
@@ -200,14 +200,14 @@ __ieee754_jn(int n, double x)
}
}
}
- b = (t*__ieee754_j0(x)/b);
+ b = (t*j0(x)/b);
}
}
if(sgn==1) return -b; else return b;
}
double
-__ieee754_yn(int n, double x)
+yn(int n, double x)
{
int32_t i,hx,ix,lx;
int32_t sign;
@@ -224,8 +224,8 @@ __ieee754_yn(int n, double x)
n = -n;
sign = 1 - ((n&1)<<1);
}
- if(n==0) return(__ieee754_y0(x));
- if(n==1) return(sign*__ieee754_y1(x));
+ if(n==0) return(y0(x));
+ if(n==1) return(sign*y1(x));
if(ix==0x7ff00000) return zero;
if(ix>=0x52D00000) { /* x > 2**302 */
/* (x >> n**2)
@@ -250,8 +250,8 @@ __ieee754_yn(int n, double x)
b = invsqrtpi*temp/sqrt(x);
} else {
u_int32_t high;
- a = __ieee754_y0(x);
- b = __ieee754_y1(x);
+ a = y0(x);
+ b = y1(x);
/* quit if b is -inf */
GET_HIGH_WORD(high,b);
for(i=1;i<n&&high!=0xfff00000;i++){
diff --git a/lib/libm/src/e_jnf.c b/lib/libm/src/e_jnf.c
index 3512c9f51a2..c96d9670e27 100644
--- a/lib/libm/src/e_jnf.c
+++ b/lib/libm/src/e_jnf.c
@@ -27,7 +27,7 @@ one = 1.0000000000e+00; /* 0x3F800000 */
static const float zero = 0.0000000000e+00;
float
-__ieee754_jnf(int n, float x)
+jnf(int n, float x)
{
int32_t i,hx,ix, sgn;
float a, b, temp, di;
@@ -45,16 +45,16 @@ __ieee754_jnf(int n, float x)
x = -x;
hx ^= 0x80000000;
}
- if(n==0) return(__ieee754_j0f(x));
- if(n==1) return(__ieee754_j1f(x));
+ if(n==0) return(j0f(x));
+ if(n==1) return(j1f(x));
sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */
x = fabsf(x);
if(ix==0||ix>=0x7f800000) /* if x is 0 or inf */
b = zero;
else if((float)n<=x) {
/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
- a = __ieee754_j0f(x);
- b = __ieee754_j1f(x);
+ a = j0f(x);
+ b = j1f(x);
for(i=1;i<n;i++){
temp = b;
b = b*((float)(i+i)/x) - a; /* avoid underflow */
@@ -129,7 +129,7 @@ __ieee754_jnf(int n, float x)
*/
tmp = n;
v = two/x;
- tmp = tmp*__ieee754_logf(fabsf(v*tmp));
+ tmp = tmp*logf(fabsf(v*tmp));
if(tmp<(float)8.8721679688e+01) {
for(i=n-1,di=(float)(i+i);i>0;i--){
temp = b;
@@ -153,14 +153,14 @@ __ieee754_jnf(int n, float x)
}
}
}
- b = (t*__ieee754_j0f(x)/b);
+ b = (t*j0f(x)/b);
}
}
if(sgn==1) return -b; else return b;
}
float
-__ieee754_ynf(int n, float x)
+ynf(int n, float x)
{
int32_t i,hx,ix,ib;
int32_t sign;
@@ -177,12 +177,12 @@ __ieee754_ynf(int n, float x)
n = -n;
sign = 1 - ((n&1)<<1);
}
- if(n==0) return(__ieee754_y0f(x));
- if(n==1) return(sign*__ieee754_y1f(x));
+ if(n==0) return(y0f(x));
+ if(n==1) return(sign*y1f(x));
if(ix==0x7f800000) return zero;
- a = __ieee754_y0f(x);
- b = __ieee754_y1f(x);
+ a = y0f(x);
+ b = y1f(x);
/* quit if b is -inf */
GET_FLOAT_WORD(ib,b);
for(i=1;i<n&&ib!=0xff800000;i++){
diff --git a/lib/libm/src/e_lgamma_r.c b/lib/libm/src/e_lgamma_r.c
index 1da673bc0c4..dbca95d5ea0 100644
--- a/lib/libm/src/e_lgamma_r.c
+++ b/lib/libm/src/e_lgamma_r.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_lgamma_r.c,v 1.7 1995/05/10 20:45:42 jtc Exp $";
#endif
-/* __ieee754_lgamma_r(x, signgamp)
+/* lgamma_r(x, signgamp)
* Reentrant version of the logarithm of the Gamma function
* with user provide pointer for the sign of Gamma(x).
*
@@ -201,7 +201,7 @@ sin_pi(double x)
double
-__ieee754_lgamma_r(double x, int *signgamp)
+lgamma_r(double x, int *signgamp)
{
double t,y,z,nadj,p,p1,p2,p3,q,r,w;
int i,hx,lx,ix;
@@ -216,15 +216,15 @@ __ieee754_lgamma_r(double x, int *signgamp)
if(ix<0x3b900000) { /* |x|<2**-70, return -log(|x|) */
if(hx<0) {
*signgamp = -1;
- return -__ieee754_log(-x);
- } else return -__ieee754_log(x);
+ return - log(-x);
+ } else return - log(x);
}
if(hx<0) {
if(ix>=0x43300000) /* |x|>=2**52, must be -integer */
return one/zero;
t = sin_pi(x);
if(t==zero) return one/zero; /* -integer */
- nadj = __ieee754_log(pi/fabs(t*x));
+ nadj = log(pi/fabs(t*x));
if(t<zero) *signgamp = -1;
x = -x;
}
@@ -234,7 +234,7 @@ __ieee754_lgamma_r(double x, int *signgamp)
/* for x < 2.0 */
else if(ix<0x40000000) {
if(ix<=0x3feccccc) { /* lgamma(x) = lgamma(x+1)-log(x) */
- r = -__ieee754_log(x);
+ r = - log(x);
if(ix>=0x3FE76944) {y = one-x; i= 0;}
else if(ix>=0x3FCDA661) {y= x-(tc-one); i=1;}
else {y = x; i=2;}
@@ -279,18 +279,18 @@ __ieee754_lgamma_r(double x, int *signgamp)
case 5: z *= (y+4.0); /* FALLTHRU */
case 4: z *= (y+3.0); /* FALLTHRU */
case 3: z *= (y+2.0); /* FALLTHRU */
- r += __ieee754_log(z); break;
+ r += log(z); break;
}
/* 8.0 <= x < 2**58 */
} else if (ix < 0x43900000) {
- t = __ieee754_log(x);
+ t = log(x);
z = one/x;
y = z*z;
w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
r = (x-half)*(t-one)+w;
} else
/* 2**58 <= x <= inf */
- r = x*(__ieee754_log(x)-one);
+ r = x*(log(x)-one);
if(hx<0) r = nadj - r;
return r;
}
diff --git a/lib/libm/src/e_lgammaf_r.c b/lib/libm/src/e_lgammaf_r.c
index 4f67523ecf9..1dfef89f9f9 100644
--- a/lib/libm/src/e_lgammaf_r.c
+++ b/lib/libm/src/e_lgammaf_r.c
@@ -137,7 +137,7 @@ sin_pif(float x)
float
-__ieee754_lgammaf_r(float x, int *signgamp)
+lgammaf_r(float x, int *signgamp)
{
float t,y,z,nadj,p,p1,p2,p3,q,r,w;
int i,hx,ix;
@@ -152,15 +152,15 @@ __ieee754_lgammaf_r(float x, int *signgamp)
if(ix<0x1c800000) { /* |x|<2**-70, return -log(|x|) */
if(hx<0) {
*signgamp = -1;
- return -__ieee754_logf(-x);
- } else return -__ieee754_logf(x);
+ return - logf(-x);
+ } else return - logf(x);
}
if(hx<0) {
if(ix>=0x4b000000) /* |x|>=2**23, must be -integer */
return one/zero;
t = sin_pif(x);
if(t==zero) return one/zero; /* -integer */
- nadj = __ieee754_logf(pi/fabsf(t*x));
+ nadj = logf(pi/fabsf(t*x));
if(t<zero) *signgamp = -1;
x = -x;
}
@@ -170,7 +170,7 @@ __ieee754_lgammaf_r(float x, int *signgamp)
/* for x < 2.0 */
else if(ix<0x40000000) {
if(ix<=0x3f666666) { /* lgamma(x) = lgamma(x+1)-log(x) */
- r = -__ieee754_logf(x);
+ r = - logf(x);
if(ix>=0x3f3b4a20) {y = one-x; i= 0;}
else if(ix>=0x3e6d3308) {y= x-(tc-one); i=1;}
else {y = x; i=2;}
@@ -215,18 +215,18 @@ __ieee754_lgammaf_r(float x, int *signgamp)
case 5: z *= (y+(float)4.0); /* FALLTHRU */
case 4: z *= (y+(float)3.0); /* FALLTHRU */
case 3: z *= (y+(float)2.0); /* FALLTHRU */
- r += __ieee754_logf(z); break;
+ r += logf(z); break;
}
/* 8.0 <= x < 2**58 */
} else if (ix < 0x5c800000) {
- t = __ieee754_logf(x);
+ t = logf(x);
z = one/x;
y = z*z;
w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
r = (x-half)*(t-one)+w;
} else
/* 2**58 <= x <= inf */
- r = x*(__ieee754_logf(x)-one);
+ r = x*(logf(x)-one);
if(hx<0) r = nadj - r;
return r;
}
diff --git a/lib/libm/src/e_log.c b/lib/libm/src/e_log.c
index 968faea8ce5..052deba253c 100644
--- a/lib/libm/src/e_log.c
+++ b/lib/libm/src/e_log.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_log.c,v 1.8 1995/05/10 20:45:49 jtc Exp $";
#endif
-/* __ieee754_log(x)
+/* log(x)
* Return the logrithm of x
*
* Method :
@@ -83,7 +83,7 @@ Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
static const double zero = 0.0;
double
-__ieee754_log(double x)
+log(double x)
{
double hfsq,f,s,z,R,w,t1,t2,dk;
int32_t k,hx,i,j;
diff --git a/lib/libm/src/e_log10.c b/lib/libm/src/e_log10.c
index 7b2e09969da..ac8b87cfa03 100644
--- a/lib/libm/src/e_log10.c
+++ b/lib/libm/src/e_log10.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_log10.c,v 1.9 1995/05/10 20:45:51 jtc Exp $";
#endif
-/* __ieee754_log10(x)
+/* log10(x)
* Return the base 10 logarithm of x
*
* Method :
@@ -59,7 +59,7 @@ log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */
static const double zero = 0.0;
double
-__ieee754_log10(double x)
+log10(double x)
{
double y,z;
int32_t i,k,hx;
@@ -81,6 +81,6 @@ __ieee754_log10(double x)
hx = (hx&0x000fffff)|((0x3ff-i)<<20);
y = (double)(k+i);
SET_HIGH_WORD(x,hx);
- z = y*log10_2lo + ivln10*__ieee754_log(x);
+ z = y*log10_2lo + ivln10*log(x);
return z+y*log10_2hi;
}
diff --git a/lib/libm/src/e_log10f.c b/lib/libm/src/e_log10f.c
index b491f166e38..d4777bf8409 100644
--- a/lib/libm/src/e_log10f.c
+++ b/lib/libm/src/e_log10f.c
@@ -29,7 +29,7 @@ log10_2lo = 7.9034151668e-07; /* 0x355427db */
static const float zero = 0.0;
float
-__ieee754_log10f(float x)
+log10f(float x)
{
float y,z;
int32_t i,k,hx;
@@ -50,6 +50,6 @@ __ieee754_log10f(float x)
hx = (hx&0x007fffff)|((0x7f-i)<<23);
y = (float)(k+i);
SET_FLOAT_WORD(x,hx);
- z = y*log10_2lo + ivln10*__ieee754_logf(x);
+ z = y*log10_2lo + ivln10*logf(x);
return z+y*log10_2hi;
}
diff --git a/lib/libm/src/e_log2.c b/lib/libm/src/e_log2.c
new file mode 100644
index 00000000000..aed716670dc
--- /dev/null
+++ b/lib/libm/src/e_log2.c
@@ -0,0 +1,74 @@
+/* @(#)e_log.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double
+ln2 = 0.6931471805599452862268,
+two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */
+Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
+Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
+Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
+Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
+Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
+Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
+Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
+
+static const double zero = 0.0;
+
+double
+log2(double x)
+{
+ double hfsq,f,s,z,R,w,t1,t2,dk;
+ int32_t k,hx,i,j;
+ u_int32_t lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+
+ k=0;
+ if (hx < 0x00100000) { /* x < 2**-1022 */
+ if (((hx&0x7fffffff)|lx)==0)
+ return -two54/zero; /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
+ k -= 54; x *= two54; /* subnormal number, scale up x */
+ GET_HIGH_WORD(hx,x);
+ }
+ if (hx >= 0x7ff00000) return x+x;
+ k += (hx>>20)-1023;
+ hx &= 0x000fffff;
+ i = (hx+0x95f64)&0x100000;
+ SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */
+ k += (i>>20);
+ f = x-1.0;
+ dk = (double)k;
+ if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */
+ if (f==zero)
+ return (dk);
+ R = f*f*(0.5-0.33333333333333333*f);
+ return (dk-(R-f)/ln2);
+ }
+ s = f/(2.0+f);
+ z = s*s;
+ i = hx-0x6147a;
+ w = z*z;
+ j = 0x6b851-hx;
+ t1= w*(Lg2+w*(Lg4+w*Lg6));
+ t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+ i |= j;
+ R = t2+t1;
+ if(i>0) {
+ hfsq=0.5*f*f;
+ return (dk-(hfsq-s*(hfsq+R)-f)/ln2);
+ } else
+ return (dk-((s*(f-R))-f)/ln2);
+}
diff --git a/lib/libm/src/e_log2f.c b/lib/libm/src/e_log2f.c
new file mode 100644
index 00000000000..c454775feff
--- /dev/null
+++ b/lib/libm/src/e_log2f.c
@@ -0,0 +1,76 @@
+/* e_logf.c -- float version of e_log.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const float
+ln2 = 0.6931471805599452862268,
+two25 = 3.355443200e+07, /* 0x4c000000 */
+Lg1 = 6.6666668653e-01, /* 3F2AAAAB */
+Lg2 = 4.0000000596e-01, /* 3ECCCCCD */
+Lg3 = 2.8571429849e-01, /* 3E924925 */
+Lg4 = 2.2222198546e-01, /* 3E638E29 */
+Lg5 = 1.8183572590e-01, /* 3E3A3325 */
+Lg6 = 1.5313838422e-01, /* 3E1CD04F */
+Lg7 = 1.4798198640e-01; /* 3E178897 */
+
+static const float zero = 0.0;
+
+float
+log2f(float x)
+{
+ float hfsq,f,s,z,R,w,t1,t2,dk;
+ int32_t k,ix,i,j;
+
+ GET_FLOAT_WORD(ix,x);
+
+ k=0;
+ if (ix < 0x00800000) { /* x < 2**-126 */
+ if ((ix&0x7fffffff)==0)
+ return -two25/zero; /* log(+-0)=-inf */
+ if (ix<0) return (x-x)/zero; /* log(-#) = NaN */
+ k -= 25; x *= two25; /* subnormal number, scale up x */
+ GET_FLOAT_WORD(ix,x);
+ }
+ if (ix >= 0x7f800000) return x+x;
+ k += (ix>>23)-127;
+ ix &= 0x007fffff;
+ i = (ix+(0x95f64<<3))&0x800000;
+ SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */
+ k += (i>>23);
+ dk = (float)k;
+ f = x-(float)1.0;
+ if((0x007fffff&(15+ix))<16) { /* |f| < 2**-20 */
+ if (f==zero)
+ return (dk);
+ R = f*f*((float)0.5-(float)0.33333333333333333*f);
+ return (dk-(R-f)/ln2);
+ }
+ s = f/((float)2.0+f);
+ z = s*s;
+ i = ix-(0x6147a<<3);
+ w = z*z;
+ j = (0x6b851<<3)-ix;
+ t1= w*(Lg2+w*(Lg4+w*Lg6));
+ t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+ i |= j;
+ R = t2+t1;
+ if(i>0) {
+ hfsq=(float)0.5*f*f;
+ return (dk-(hfsq-s*(hfsq+R)-f)/ln2);
+ } else
+ return (dk-((s*(f-R))-f)/ln2);
+}
diff --git a/lib/libm/src/e_logf.c b/lib/libm/src/e_logf.c
index 60d327a089f..9491341e6b2 100644
--- a/lib/libm/src/e_logf.c
+++ b/lib/libm/src/e_logf.c
@@ -35,7 +35,7 @@ Lg7 = 1.4798198640e-01; /* 3E178897 */
static const float zero = 0.0;
float
-__ieee754_logf(float x)
+logf(float x)
{
float hfsq,f,s,z,R,w,t1,t2,dk;
int32_t k,ix,i,j;
diff --git a/lib/libm/src/e_pow.c b/lib/libm/src/e_pow.c
index 4c4ad3bd112..2aa035eee83 100644
--- a/lib/libm/src/e_pow.c
+++ b/lib/libm/src/e_pow.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_pow.c,v 1.9 1995/05/12 04:57:32 jtc Exp $";
#endif
-/* __ieee754_pow(x,y) return x**y
+/* pow(x,y) return x**y
*
* n
* Method: Let x = 2 * (1+f)
@@ -96,7 +96,7 @@ ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
double
-__ieee754_pow(double x, double y)
+pow(double x, double y)
{
double z,ax,z_h,z_l,p_h,p_l;
double yy1,t1,t2,r,s,t,u,v,w;
@@ -152,7 +152,7 @@ __ieee754_pow(double x, double y)
if(hy==0x40000000) return x*x; /* y is 2 */
if(hy==0x3fe00000) { /* y is 0.5 */
if(hx>=0) /* x >= +0 */
- return __ieee754_sqrt(x);
+ return sqrt(x);
}
}
diff --git a/lib/libm/src/e_powf.c b/lib/libm/src/e_powf.c
index ec93660cc3f..9e520f486b9 100644
--- a/lib/libm/src/e_powf.c
+++ b/lib/libm/src/e_powf.c
@@ -54,7 +54,7 @@ ivln2_h = 1.4426879883e+00, /* 0x3fb8aa00 =16b 1/ln2*/
ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
float
-__ieee754_powf(float x, float y)
+powf(float x, float y)
{
float z,ax,z_h,z_l,p_h,p_l;
float yy1,t1,t2,r,s,t,u,v,w;
@@ -103,7 +103,7 @@ __ieee754_powf(float x, float y)
if(hy==0x40000000) return x*x; /* y is 2 */
if(hy==0x3f000000) { /* y is 0.5 */
if(hx>=0) /* x >= +0 */
- return __ieee754_sqrtf(x);
+ return sqrtf(x);
}
ax = fabsf(x);
diff --git a/lib/libm/src/e_remainder.c b/lib/libm/src/e_remainder.c
index cd67c4410ff..623a13b141e 100644
--- a/lib/libm/src/e_remainder.c
+++ b/lib/libm/src/e_remainder.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_remainder.c,v 1.8 1995/05/10 20:46:05 jtc Exp $";
#endif
-/* __ieee754_remainder(x,p)
+/* remainder(x,p)
* Return :
* returns x REM p = x - [x/p]*p as if in infinite
* precise arithmetic, where [x/p] is the (infinite bit)
@@ -30,7 +30,7 @@ static const double zero = 0.0;
double
-__ieee754_remainder(double x, double p)
+remainder(double x, double p)
{
int32_t hx,hp;
u_int32_t sx,lx,lp;
@@ -50,7 +50,7 @@ __ieee754_remainder(double x, double p)
return (x*p)/(x*p);
- if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */
+ if (hp<=0x7fdfffff) x = fmod(x,p+p); /* now x < 2p */
if (((hx-hp)|(lx-lp))==0) return zero*x;
x = fabs(x);
p = fabs(p);
diff --git a/lib/libm/src/e_remainderf.c b/lib/libm/src/e_remainderf.c
index 36ec236732e..4405866914d 100644
--- a/lib/libm/src/e_remainderf.c
+++ b/lib/libm/src/e_remainderf.c
@@ -23,7 +23,7 @@ static char rcsid[] = "$NetBSD: e_remainderf.c,v 1.4 1995/05/10 20:46:08 jtc Exp
static const float zero = 0.0;
float
-__ieee754_remainderf(float x, float p)
+remainderf(float x, float p)
{
int32_t hx,hp;
u_int32_t sx;
@@ -42,7 +42,7 @@ __ieee754_remainderf(float x, float p)
return (x*p)/(x*p);
- if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p); /* now x < 2p */
+ if (hp<=0x7effffff) x = fmodf(x,p+p); /* now x < 2p */
if ((hx-hp)==0) return zero*x;
x = fabsf(x);
p = fabsf(p);
diff --git a/lib/libm/src/e_scalb.c b/lib/libm/src/e_scalb.c
index e51f5447d60..d07808896f1 100644
--- a/lib/libm/src/e_scalb.c
+++ b/lib/libm/src/e_scalb.c
@@ -15,7 +15,7 @@ static char rcsid[] = "$NetBSD: e_scalb.c,v 1.6 1995/05/10 20:46:09 jtc Exp $";
#endif
/*
- * __ieee754_scalb(x, fn) is provide for
+ * scalb(x, fn) is provide for
* passing various standard test suite. One
* should use scalbn() instead.
*/
@@ -25,7 +25,7 @@ static char rcsid[] = "$NetBSD: e_scalb.c,v 1.6 1995/05/10 20:46:09 jtc Exp $";
#ifdef _SCALB_INT
double
-__ieee754_scalb(double x, int fn)
+scalb(double x, int fn)
{
return scalbn(x, fn);
}
@@ -33,7 +33,7 @@ __ieee754_scalb(double x, int fn)
#else
double
-__ieee754_scalb(double x, double fn)
+scalb(double x, double fn)
{
if (isnan(x)||isnan(fn)) return x*fn;
if (!finite(fn)) {
diff --git a/lib/libm/src/e_scalbf.c b/lib/libm/src/e_scalbf.c
index 58587f5d98c..e50179a1835 100644
--- a/lib/libm/src/e_scalbf.c
+++ b/lib/libm/src/e_scalbf.c
@@ -22,7 +22,7 @@ static char rcsid[] = "$NetBSD: e_scalbf.c,v 1.3 1995/05/10 20:46:12 jtc Exp $";
#ifdef _SCALB_INT
float
-__ieee754_scalbf(float x, int fn)
+scalbf(float x, int fn)
{
return scalbnf(x,fn);
}
@@ -30,7 +30,7 @@ __ieee754_scalbf(float x, int fn)
#else
float
-__ieee754_scalbf(float x, float fn)
+scalbf(float x, float fn)
{
if (isnanf(x)||isnanf(fn)) return x*fn;
if (!finitef(fn)) {
diff --git a/lib/libm/src/e_sinh.c b/lib/libm/src/e_sinh.c
index 03cb60b3ef3..68be7b5080f 100644
--- a/lib/libm/src/e_sinh.c
+++ b/lib/libm/src/e_sinh.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_sinh.c,v 1.7 1995/05/10 20:46:13 jtc Exp $";
#endif
-/* __ieee754_sinh(x)
+/* sinh(x)
* Method :
* mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
* 1. Replace x by |x| (sinh(-x) = -sinh(x)).
@@ -38,7 +38,7 @@ static char rcsid[] = "$NetBSD: e_sinh.c,v 1.7 1995/05/10 20:46:13 jtc Exp $";
static const double one = 1.0, shuge = 1.0e307;
double
-__ieee754_sinh(double x)
+sinh(double x)
{
double t,w,h;
int32_t ix,jx;
@@ -63,12 +63,12 @@ __ieee754_sinh(double x)
}
/* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
- if (ix < 0x40862E42) return h*__ieee754_exp(fabs(x));
+ if (ix < 0x40862E42) return h*exp(fabs(x));
/* |x| in [log(maxdouble), overflowthresold] */
GET_LOW_WORD(lx,x);
if (ix<0x408633CE || ((ix==0x408633ce)&&(lx<=(u_int32_t)0x8fb9f87d))) {
- w = __ieee754_exp(0.5*fabs(x));
+ w = exp(0.5*fabs(x));
t = h*w;
return t*w;
}
diff --git a/lib/libm/src/e_sinhf.c b/lib/libm/src/e_sinhf.c
index a4b27c77ff4..a593c488b95 100644
--- a/lib/libm/src/e_sinhf.c
+++ b/lib/libm/src/e_sinhf.c
@@ -23,7 +23,7 @@ static char rcsid[] = "$NetBSD: e_sinhf.c,v 1.4 1995/05/10 20:46:15 jtc Exp $";
static const float one = 1.0, shuge = 1.0e37;
float
-__ieee754_sinhf(float x)
+sinhf(float x)
{
float t,w,h;
int32_t ix,jx;
@@ -46,11 +46,11 @@ __ieee754_sinhf(float x)
}
/* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
- if (ix < 0x42b17180) return h*__ieee754_expf(fabsf(x));
+ if (ix < 0x42b17180) return h*expf(fabsf(x));
/* |x| in [log(maxdouble), overflowthresold] */
if (ix<=0x42b2d4fc) {
- w = __ieee754_expf((float)0.5*fabsf(x));
+ w = expf((float)0.5*fabsf(x));
t = h*w;
return t*w;
}
diff --git a/lib/libm/src/e_sqrt.c b/lib/libm/src/e_sqrt.c
index 4cf344e064a..05355a33291 100644
--- a/lib/libm/src/e_sqrt.c
+++ b/lib/libm/src/e_sqrt.c
@@ -14,7 +14,7 @@
static char rcsid[] = "$NetBSD: e_sqrt.c,v 1.8 1995/05/10 20:46:17 jtc Exp $";
#endif
-/* __ieee754_sqrt(x)
+/* sqrt(x)
* Return correctly rounded sqrt.
* ------------------------------------------
* | Use the hardware sqrt if you have one |
@@ -90,7 +90,7 @@ static char rcsid[] = "$NetBSD: e_sqrt.c,v 1.8 1995/05/10 20:46:17 jtc Exp $";
static const double one = 1.0, tiny=1.0e-300;
double
-__ieee754_sqrt(double x)
+sqrt(double x)
{
double z;
int32_t sign = (int)0x80000000;
diff --git a/lib/libm/src/e_sqrtf.c b/lib/libm/src/e_sqrtf.c
index f886fecc583..2dee4848572 100644
--- a/lib/libm/src/e_sqrtf.c
+++ b/lib/libm/src/e_sqrtf.c
@@ -23,7 +23,7 @@ static char rcsid[] = "$NetBSD: e_sqrtf.c,v 1.4 1995/05/10 20:46:19 jtc Exp $";
static const float one = 1.0, tiny=1.0e-30;
float
-__ieee754_sqrtf(float x)
+sqrtf(float x)
{
float z;
int32_t sign = (int)0x80000000;
diff --git a/lib/libm/src/k_standard.c b/lib/libm/src/k_standard.c
deleted file mode 100644
index 2ed40b44b87..00000000000
--- a/lib/libm/src/k_standard.c
+++ /dev/null
@@ -1,773 +0,0 @@
-/* @(#)k_standard.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: k_standard.c,v 1.6 1995/05/10 20:46:35 jtc Exp $";
-#endif
-
-#include "math.h"
-#include "math_private.h"
-#include <errno.h>
-#include <stdio.h> /* fputs(), stderr */
-
-#ifndef _USE_WRITE
-#define WRITE2(u,v) fputs(u, stderr)
-#else /* !defined(_USE_WRITE) */
-#include <unistd.h> /* write */
-#define WRITE2(u,v) write(2, u, v)
-#endif /* !defined(_USE_WRITE) */
-
-static const double zero = 0.0; /* used as const */
-
-/*
- * Standard conformance (non-IEEE) on exception cases.
- * Mapping:
- * 1 -- acos(|x|>1)
- * 2 -- asin(|x|>1)
- * 3 -- atan2(+-0,+-0)
- * 4 -- hypot overflow
- * 5 -- cosh overflow
- * 6 -- exp overflow
- * 7 -- exp underflow
- * 8 -- y0(0)
- * 9 -- y0(-ve)
- * 10-- y1(0)
- * 11-- y1(-ve)
- * 12-- yn(0)
- * 13-- yn(-ve)
- * 14-- lgamma(finite) overflow
- * 15-- lgamma(-integer)
- * 16-- log(0)
- * 17-- log(x<0)
- * 18-- log10(0)
- * 19-- log10(x<0)
- * 20-- pow(0.0,0.0)
- * 21-- pow(x,y) overflow
- * 22-- pow(x,y) underflow
- * 23-- pow(0,negative)
- * 24-- pow(neg,non-integral)
- * 25-- sinh(finite) overflow
- * 26-- sqrt(negative)
- * 27-- fmod(x,0)
- * 28-- remainder(x,0)
- * 29-- acosh(x<1)
- * 30-- atanh(|x|>1)
- * 31-- atanh(|x|=1)
- * 32-- scalb overflow
- * 33-- scalb underflow
- * 34-- j0(|x|>X_TLOSS)
- * 35-- y0(x>X_TLOSS)
- * 36-- j1(|x|>X_TLOSS)
- * 37-- y1(x>X_TLOSS)
- * 38-- jn(|x|>X_TLOSS, n)
- * 39-- yn(x>X_TLOSS, n)
- * 40-- gamma(finite) overflow
- * 41-- gamma(-integer)
- * 42-- pow(NaN,0.0)
- */
-
-
-double
-__kernel_standard(double x, double y, int type)
-{
- struct exception exc;
-#ifndef HUGE_VAL /* this is the only routine that uses HUGE_VAL */
-#define HUGE_VAL inf
- double inf = 0.0;
-
- SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */
-#endif
-
-#ifdef _USE_WRITE
- (void) fflush(stdout);
-#endif
- exc.arg1 = x;
- exc.arg2 = y;
- switch(type) {
- case 1:
- case 101:
- /* acos(|x|>1) */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "acos" : "acosf";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if(_LIB_VERSION == _SVID_) {
- (void) WRITE2("acos: DOMAIN error\n", 19);
- }
- errno = EDOM;
- }
- break;
- case 2:
- case 102:
- /* asin(|x|>1) */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "asin" : "asinf";
- exc.retval = zero;
- if(_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if(_LIB_VERSION == _SVID_) {
- (void) WRITE2("asin: DOMAIN error\n", 19);
- }
- errno = EDOM;
- }
- break;
- case 3:
- case 103:
- /* atan2(+-0,+-0) */
- exc.arg1 = y;
- exc.arg2 = x;
- exc.type = DOMAIN;
- exc.name = type < 100 ? "atan2" : "atan2f";
- exc.retval = zero;
- if(_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if(_LIB_VERSION == _SVID_) {
- (void) WRITE2("atan2: DOMAIN error\n", 20);
- }
- errno = EDOM;
- }
- break;
- case 4:
- case 104:
- /* hypot(finite,finite) overflow */
- exc.type = OVERFLOW;
- exc.name = type < 100 ? "hypot" : "hypotf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = HUGE;
- else
- exc.retval = HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- errno = ERANGE;
- }
- break;
- case 5:
- case 105:
- /* cosh(finite) overflow */
- exc.type = OVERFLOW;
- exc.name = type < 100 ? "cosh" : "coshf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = HUGE;
- else
- exc.retval = HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- errno = ERANGE;
- }
- break;
- case 6:
- case 106:
- /* exp(finite) overflow */
- exc.type = OVERFLOW;
- exc.name = type < 100 ? "exp" : "expf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = HUGE;
- else
- exc.retval = HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- errno = ERANGE;
- }
- break;
- case 7:
- case 107:
- /* exp(finite) underflow */
- exc.type = UNDERFLOW;
- exc.name = type < 100 ? "exp" : "expf";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- errno = ERANGE;
- }
- break;
- case 8:
- case 108:
- /* y0(0) = -inf */
- exc.type = DOMAIN; /* should be SING for IEEE */
- exc.name = type < 100 ? "y0" : "y0f";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("y0: DOMAIN error\n", 17);
- }
- errno = EDOM;
- }
- break;
- case 9:
- case 109:
- /* y0(x<0) = NaN */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "y0" : "y0f";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("y0: DOMAIN error\n", 17);
- }
- errno = EDOM;
- }
- break;
- case 10:
- case 110:
- /* y1(0) = -inf */
- exc.type = DOMAIN; /* should be SING for IEEE */
- exc.name = type < 100 ? "y1" : "y1f";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("y1: DOMAIN error\n", 17);
- }
- errno = EDOM;
- }
- break;
- case 11:
- case 111:
- /* y1(x<0) = NaN */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "y1" : "y1f";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("y1: DOMAIN error\n", 17);
- }
- errno = EDOM;
- }
- break;
- case 12:
- case 112:
- /* yn(n,0) = -inf */
- exc.type = DOMAIN; /* should be SING for IEEE */
- exc.name = type < 100 ? "yn" : "ynf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("yn: DOMAIN error\n", 17);
- }
- errno = EDOM;
- }
- break;
- case 13:
- case 113:
- /* yn(x<0) = NaN */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "yn" : "ynf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("yn: DOMAIN error\n", 17);
- }
- errno = EDOM;
- }
- break;
- case 14:
- case 114:
- /* lgamma(finite) overflow */
- exc.type = OVERFLOW;
- exc.name = type < 100 ? "lgamma" : "lgammaf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = HUGE;
- else
- exc.retval = HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- errno = ERANGE;
- }
- break;
- case 15:
- case 115:
- /* lgamma(-integer) or lgamma(0) */
- exc.type = SING;
- exc.name = type < 100 ? "lgamma" : "lgammaf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = HUGE;
- else
- exc.retval = HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("lgamma: SING error\n", 19);
- }
- errno = EDOM;
- }
- break;
- case 16:
- case 116:
- /* log(0) */
- exc.type = SING;
- exc.name = type < 100 ? "log" : "logf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("log: SING error\n", 16);
- }
- errno = EDOM;
- }
- break;
- case 17:
- case 117:
- /* log(x<0) */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "log" : "logf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("log: DOMAIN error\n", 18);
- }
- errno = EDOM;
- }
- break;
- case 18:
- case 118:
- /* log10(0) */
- exc.type = SING;
- exc.name = type < 100 ? "log10" : "log10f";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("log10: SING error\n", 18);
- }
- errno = EDOM;
- }
- break;
- case 19:
- case 119:
- /* log10(x<0) */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "log10" : "log10f";
- if (_LIB_VERSION == _SVID_)
- exc.retval = -HUGE;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("log10: DOMAIN error\n", 20);
- }
- errno = EDOM;
- }
- break;
- case 20:
- case 120:
- /* pow(0.0,0.0) */
- /* error only if _LIB_VERSION == _SVID_ */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "pow" : "powf";
- exc.retval = zero;
- if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
- else if (!matherr(&exc)) {
- (void) WRITE2("pow(0,0): DOMAIN error\n", 23);
- errno = EDOM;
- }
- break;
- case 21:
- case 121:
- /* pow(x,y) overflow */
- exc.type = OVERFLOW;
- exc.name = type < 100 ? "pow" : "powf";
- if (_LIB_VERSION == _SVID_) {
- exc.retval = HUGE;
- y *= 0.5;
- if(x<zero&&rint(y)!=y) exc.retval = -HUGE;
- } else {
- exc.retval = HUGE_VAL;
- y *= 0.5;
- if(x<zero&&rint(y)!=y) exc.retval = -HUGE_VAL;
- }
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- errno = ERANGE;
- }
- break;
- case 22:
- case 122:
- /* pow(x,y) underflow */
- exc.type = UNDERFLOW;
- exc.name = type < 100 ? "pow" : "powf";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- errno = ERANGE;
- }
- break;
- case 23:
- case 123:
- /* 0**neg */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "pow" : "powf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = zero;
- else
- exc.retval = -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
- }
- errno = EDOM;
- }
- break;
- case 24:
- case 124:
- /* neg**non-integral */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "pow" : "powf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = zero;
- else
- exc.retval = zero/zero; /* X/Open allow NaN */
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
- }
- errno = EDOM;
- }
- break;
- case 25:
- case 125:
- /* sinh(finite) overflow */
- exc.type = OVERFLOW;
- exc.name = type < 100 ? "sinh" : "sinhf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = ( (x>zero) ? HUGE : -HUGE);
- else
- exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- errno = ERANGE;
- }
- break;
- case 26:
- case 126:
- /* sqrt(x<0) */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "sqrt" : "sqrtf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = zero;
- else
- exc.retval = zero/zero;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("sqrt: DOMAIN error\n", 19);
- }
- errno = EDOM;
- }
- break;
- case 27:
- case 127:
- /* fmod(x,0) */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "fmod" : "fmodf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = x;
- else
- exc.retval = zero/zero;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("fmod: DOMAIN error\n", 20);
- }
- errno = EDOM;
- }
- break;
- case 28:
- case 128:
- /* remainder(x,0) */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "remainder" : "remainderf";
- exc.retval = zero/zero;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("remainder: DOMAIN error\n", 24);
- }
- errno = EDOM;
- }
- break;
- case 29:
- case 129:
- /* acosh(x<1) */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "acosh" : "acoshf";
- exc.retval = zero/zero;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("acosh: DOMAIN error\n", 20);
- }
- errno = EDOM;
- }
- break;
- case 30:
- case 130:
- /* atanh(|x|>1) */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "atanh" : "atanhf";
- exc.retval = zero/zero;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("atanh: DOMAIN error\n", 20);
- }
- errno = EDOM;
- }
- break;
- case 31:
- case 131:
- /* atanh(|x|=1) */
- exc.type = SING;
- exc.name = type < 100 ? "atanh" : "atanhf";
- exc.retval = x/zero; /* sign(x)*inf */
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("atanh: SING error\n", 18);
- }
- errno = EDOM;
- }
- break;
- case 32:
- case 132:
- /* scalb overflow; SVID also returns +-HUGE_VAL */
- exc.type = OVERFLOW;
- exc.name = type < 100 ? "scalb" : "scalbf";
- exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- errno = ERANGE;
- }
- break;
- case 33:
- case 133:
- /* scalb underflow */
- exc.type = UNDERFLOW;
- exc.name = type < 100 ? "scalb" : "scalbf";
- exc.retval = copysign(zero,x);
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- errno = ERANGE;
- }
- break;
- case 34:
- case 134:
- /* j0(|x|>X_TLOSS) */
- exc.type = TLOSS;
- exc.name = type < 100 ? "j0" : "j0f";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2(exc.name, 2);
- (void) WRITE2(": TLOSS error\n", 14);
- }
- errno = ERANGE;
- }
- break;
- case 35:
- case 135:
- /* y0(x>X_TLOSS) */
- exc.type = TLOSS;
- exc.name = type < 100 ? "y0" : "y0f";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2(exc.name, 2);
- (void) WRITE2(": TLOSS error\n", 14);
- }
- errno = ERANGE;
- }
- break;
- case 36:
- case 136:
- /* j1(|x|>X_TLOSS) */
- exc.type = TLOSS;
- exc.name = type < 100 ? "j1" : "j1f";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2(exc.name, 2);
- (void) WRITE2(": TLOSS error\n", 14);
- }
- errno = ERANGE;
- }
- break;
- case 37:
- case 137:
- /* y1(x>X_TLOSS) */
- exc.type = TLOSS;
- exc.name = type < 100 ? "y1" : "y1f";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2(exc.name, 2);
- (void) WRITE2(": TLOSS error\n", 14);
- }
- errno = ERANGE;
- }
- break;
- case 38:
- case 138:
- /* jn(|x|>X_TLOSS) */
- exc.type = TLOSS;
- exc.name = type < 100 ? "jn" : "jnf";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2(exc.name, 2);
- (void) WRITE2(": TLOSS error\n", 14);
- }
- errno = ERANGE;
- }
- break;
- case 39:
- case 139:
- /* yn(x>X_TLOSS) */
- exc.type = TLOSS;
- exc.name = type < 100 ? "yn" : "ynf";
- exc.retval = zero;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2(exc.name, 2);
- (void) WRITE2(": TLOSS error\n", 14);
- }
- errno = ERANGE;
- }
- break;
- case 40:
- case 140:
- /* gamma(finite) overflow */
- exc.type = OVERFLOW;
- exc.name = type < 100 ? "gamma" : "gammaf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = HUGE;
- else
- exc.retval = HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = ERANGE;
- else if (!matherr(&exc)) {
- errno = ERANGE;
- }
- break;
- case 41:
- case 141:
- /* gamma(-integer) or gamma(0) */
- exc.type = SING;
- exc.name = type < 100 ? "gamma" : "gammaf";
- if (_LIB_VERSION == _SVID_)
- exc.retval = HUGE;
- else
- exc.retval = HUGE_VAL;
- if (_LIB_VERSION == _POSIX_)
- errno = EDOM;
- else if (!matherr(&exc)) {
- if (_LIB_VERSION == _SVID_) {
- (void) WRITE2("gamma: SING error\n", 18);
- }
- errno = EDOM;
- }
- break;
- case 42:
- case 142:
- /* pow(NaN,0.0) */
- /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
- exc.type = DOMAIN;
- exc.name = type < 100 ? "pow" : "powf";
- exc.retval = x;
- if (_LIB_VERSION == _IEEE_ ||
- _LIB_VERSION == _POSIX_) exc.retval = 1.0;
- else if (!matherr(&exc)) {
- errno = EDOM;
- }
- break;
- }
- return exc.retval;
-}
diff --git a/lib/libm/src/math_private.h b/lib/libm/src/math_private.h
index cdfd07affe1..0fc4f6a78d3 100644
--- a/lib/libm/src/math_private.h
+++ b/lib/libm/src/math_private.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: math_private.h,v 1.9 2008/07/24 09:40:16 martynas Exp $ */
+/* $OpenBSD: math_private.h,v 1.10 2008/09/07 20:36:09 martynas Exp $ */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -213,73 +213,15 @@ do { \
#endif
#endif
-/* ieee style elementary functions */
-extern double __ieee754_sqrt(double);
-extern double __ieee754_acos(double);
-extern double __ieee754_acosh(double);
-extern double __ieee754_log(double);
-extern double __ieee754_atanh(double);
-extern double __ieee754_asin(double);
-extern double __ieee754_atan2(double,double);
-extern double __ieee754_exp(double);
-extern double __ieee754_cosh(double);
-extern double __ieee754_fmod(double,double);
-extern double __ieee754_pow(double,double);
-extern double __ieee754_lgamma_r(double,int *);
-extern double __ieee754_gamma_r(double,int *);
-extern double __ieee754_lgamma(double);
-extern double __ieee754_gamma(double);
-extern double __ieee754_log10(double);
-extern double __ieee754_sinh(double);
-extern double __ieee754_hypot(double,double);
-extern double __ieee754_j0(double);
-extern double __ieee754_j1(double);
-extern double __ieee754_y0(double);
-extern double __ieee754_y1(double);
-extern double __ieee754_jn(int,double);
-extern double __ieee754_yn(int,double);
-extern double __ieee754_remainder(double,double);
-extern int __ieee754_rem_pio2(double,double*);
-extern double __ieee754_scalb(double,double);
-
/* fdlibm kernel function */
-extern double __kernel_standard(double,double,int);
+extern int __ieee754_rem_pio2(double,double*);
extern double __kernel_sin(double,double,int);
extern double __kernel_cos(double,double);
extern double __kernel_tan(double,double,int);
extern int __kernel_rem_pio2(double*,double*,int,int,int,const int*);
-
-/* ieee style elementary float functions */
-extern float __ieee754_sqrtf(float);
-extern float __ieee754_acosf(float);
-extern float __ieee754_acoshf(float);
-extern float __ieee754_logf(float);
-extern float __ieee754_atanhf(float);
-extern float __ieee754_asinf(float);
-extern float __ieee754_atan2f(float,float);
-extern float __ieee754_expf(float);
-extern float __ieee754_coshf(float);
-extern float __ieee754_fmodf(float,float);
-extern float __ieee754_powf(float,float);
-extern float __ieee754_lgammaf_r(float,int *);
-extern float __ieee754_gammaf_r(float,int *);
-extern float __ieee754_lgammaf(float);
-extern float __ieee754_gammaf(float);
-extern float __ieee754_log10f(float);
-extern float __ieee754_sinhf(float);
-extern float __ieee754_hypotf(float,float);
-extern float __ieee754_j0f(float);
-extern float __ieee754_j1f(float);
-extern float __ieee754_y0f(float);
-extern float __ieee754_y1f(float);
-extern float __ieee754_jnf(int,float);
-extern float __ieee754_ynf(int,float);
-extern float __ieee754_remainderf(float,float);
-extern int __ieee754_rem_pio2f(float,float*);
-extern float __ieee754_scalbf(float,float);
-
/* float versions of fdlibm kernel functions */
+extern int __ieee754_rem_pio2f(float,float*);
extern float __kernel_sinf(float,float,int);
extern float __kernel_cosf(float,float);
extern float __kernel_tanf(float,float,int);
diff --git a/lib/libm/src/s_asinh.c b/lib/libm/src/s_asinh.c
index da49239a015..7398aa9d057 100644
--- a/lib/libm/src/s_asinh.c
+++ b/lib/libm/src/s_asinh.c
@@ -45,13 +45,13 @@ asinh(double x)
if(huge+x>one) return x; /* return x inexact except 0 */
}
if(ix>0x41b00000) { /* |x| > 2**28 */
- w = __ieee754_log(fabs(x))+ln2;
+ w = log(fabs(x))+ln2;
} else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */
t = fabs(x);
- w = __ieee754_log(2.0*t+one/(__ieee754_sqrt(x*x+one)+t));
+ w = log(2.0*t+one/(sqrt(x*x+one)+t));
} else { /* 2.0 > |x| > 2**-28 */
t = x*x;
- w =log1p(fabs(x)+t/(one+__ieee754_sqrt(one+t)));
+ w =log1p(fabs(x)+t/(one+sqrt(one+t)));
}
if(hx>0) return w; else return -w;
}
diff --git a/lib/libm/src/s_asinhf.c b/lib/libm/src/s_asinhf.c
index 50e60b4d29e..e6426142985 100644
--- a/lib/libm/src/s_asinhf.c
+++ b/lib/libm/src/s_asinhf.c
@@ -37,13 +37,13 @@ asinhf(float x)
if(huge+x>one) return x; /* return x inexact except 0 */
}
if(ix>0x4d800000) { /* |x| > 2**28 */
- w = __ieee754_logf(fabsf(x))+ln2;
+ w = logf(fabsf(x))+ln2;
} else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */
t = fabsf(x);
- w = __ieee754_logf((float)2.0*t+one/(__ieee754_sqrtf(x*x+one)+t));
+ w = logf((float)2.0*t+one/(sqrtf(x*x+one)+t));
} else { /* 2.0 > |x| > 2**-28 */
t = x*x;
- w =log1pf(fabsf(x)+t/(one+__ieee754_sqrtf(one+t)));
+ w =log1pf(fabsf(x)+t/(one+sqrtf(one+t)));
}
if(hx>0) return w; else return -w;
}
diff --git a/lib/libm/src/s_cabs.c b/lib/libm/src/s_cabs.c
new file mode 100644
index 00000000000..d2f3f942c3f
--- /dev/null
+++ b/lib/libm/src/s_cabs.c
@@ -0,0 +1,25 @@
+/* $OpenBSD: s_cabs.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <complex.h>
+#include <math.h>
+
+double
+cabs(double complex z)
+{
+ return hypot(__real__ z, __imag__ z);
+}
diff --git a/lib/libc/stdlib/strtof.c b/lib/libm/src/s_cabsf.c
index 8c8db47ad82..d4d22f2dbb5 100644
--- a/lib/libc/stdlib/strtof.c
+++ b/lib/libm/src/s_cabsf.c
@@ -1,8 +1,6 @@
-/* $OpenBSD: strtof.c,v 1.1 2008/06/13 21:04:24 landry Exp $ */
-
+/* $OpenBSD: s_cabsf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
/*
- * Copyright (c) 2008 Landry Breuil
- * All rights reserved.
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -17,23 +15,11 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <errno.h>
-#include <limits.h>
-#include <stdlib.h>
+#include <complex.h>
#include <math.h>
float
-strtof(const char *s00, char **se)
+cabsf(float complex z)
{
- double d;
-
- d = strtod(s00, se);
- if (d > FLT_MAX) {
- errno = ERANGE;
- return (FLT_MAX);
- } else if (d < -FLT_MAX) {
- errno = ERANGE;
- return (-FLT_MAX);
- }
- return ((float) d);
+ return hypotf(__real__ z, __imag__ z);
}
diff --git a/lib/libm/src/s_cacos.c b/lib/libm/src/s_cacos.c
new file mode 100644
index 00000000000..96d26626b98
--- /dev/null
+++ b/lib/libm/src/s_cacos.c
@@ -0,0 +1,60 @@
+/* $OpenBSD: s_cacos.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* cacos()
+ *
+ * Complex circular arc cosine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex cacos();
+ * double complex z, w;
+ *
+ * w = cacos (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ *
+ * w = arccos z = PI/2 - arcsin z.
+ *
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * DEC -10,+10 5200 1.6e-15 2.8e-16
+ * IEEE -10,+10 30000 1.8e-14 2.2e-15
+ */
+
+#include <complex.h>
+#include <math.h>
+
+double complex
+cacos(double complex z)
+{
+ double complex w;
+
+ w = casin (z);
+ w = (M_PI_2 - creal (w)) - cimag (w) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_cacosf.c b/lib/libm/src/s_cacosf.c
new file mode 100644
index 00000000000..5a644c15bd1
--- /dev/null
+++ b/lib/libm/src/s_cacosf.c
@@ -0,0 +1,60 @@
+/* $OpenBSD: s_cacosf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* cacosf()
+ *
+ * Complex circular arc cosine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * void cacosf();
+ * cmplxf z, w;
+ *
+ * cacosf( &z, &w );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ *
+ * w = arccos z = PI/2 - arcsin z.
+ *
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 9.2e-6 1.2e-6
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+float complex
+cacosf(float complex z)
+{
+ float complex w;
+
+ w = casinf( z );
+ w = (M_PI_2 - creal (w)) - cimag (w) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_cacosh.c b/lib/libm/src/s_cacosh.c
new file mode 100644
index 00000000000..43ba99ad6f9
--- /dev/null
+++ b/lib/libm/src/s_cacosh.c
@@ -0,0 +1,55 @@
+/* $OpenBSD: s_cacosh.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* cacosh
+ *
+ * Complex inverse hyperbolic cosine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex cacosh();
+ * double complex z, w;
+ *
+ * w = cacosh (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * acosh z = i acos z .
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 1.6e-14 2.1e-15
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+double complex
+cacosh(double complex z)
+{
+ double complex w;
+
+ w = I * cacos (z);
+ return (w);
+}
diff --git a/lib/libm/src/s_cacoshf.c b/lib/libm/src/s_cacoshf.c
new file mode 100644
index 00000000000..d81f7843c91
--- /dev/null
+++ b/lib/libm/src/s_cacoshf.c
@@ -0,0 +1,55 @@
+/* $OpenBSD: s_cacoshf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* cacoshf
+ *
+ * Complex inverse hyperbolic cosine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float complex cacoshf();
+ * float complex z, w;
+ *
+ * w = cacoshf (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * acosh z = i acos z .
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 1.6e-14 2.1e-15
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+float complex
+cacoshf(float complex z)
+{
+ float complex w;
+
+ w = I * cacosf (z);
+ return (w);
+}
diff --git a/lib/libm/src/s_carg.c b/lib/libm/src/s_carg.c
new file mode 100644
index 00000000000..db51662a1d9
--- /dev/null
+++ b/lib/libm/src/s_carg.c
@@ -0,0 +1,25 @@
+/* $OpenBSD: s_carg.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <complex.h>
+#include <math.h>
+
+double
+carg(double complex z)
+{
+ return atan2 (__imag__ z, __real__ z);
+}
diff --git a/lib/libm/src/s_cargf.c b/lib/libm/src/s_cargf.c
new file mode 100644
index 00000000000..12dbcde753d
--- /dev/null
+++ b/lib/libm/src/s_cargf.c
@@ -0,0 +1,25 @@
+/* $OpenBSD: s_cargf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <complex.h>
+#include <math.h>
+
+float
+cargf(float complex z)
+{
+ return atan2f (__imag__ z, __real__ z);
+}
diff --git a/lib/libm/src/s_casin.c b/lib/libm/src/s_casin.c
new file mode 100644
index 00000000000..1c1b53541bb
--- /dev/null
+++ b/lib/libm/src/s_casin.c
@@ -0,0 +1,129 @@
+/* $OpenBSD: s_casin.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* casin()
+ *
+ * Complex circular arc sine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex casin();
+ * double complex z, w;
+ *
+ * w = casin (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Inverse complex sine:
+ *
+ * 2
+ * w = -i clog( iz + csqrt( 1 - z ) ).
+ *
+ * casin(z) = -i casinh(iz)
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * DEC -10,+10 10100 2.1e-15 3.4e-16
+ * IEEE -10,+10 30000 2.2e-14 2.7e-15
+ * Larger relative error can be observed for z near zero.
+ * Also tested by csin(casin(z)) = z.
+ */
+
+#include <complex.h>
+#include <math.h>
+
+double complex
+casin(double complex z)
+{
+ double complex w;
+ static double complex ca, ct, zz, z2;
+ double x, y;
+
+ x = creal (z);
+ y = cimag (z);
+
+ if (y == 0.0) {
+ if (fabs(x) > 1.0) {
+ w = M_PI_2 + 0.0 * I;
+ /*mtherr ("casin", DOMAIN);*/
+ }
+ else {
+ w = asin (x) + 0.0 * I;
+ }
+ return (w);
+ }
+
+ /* Power series expansion */
+ /*
+ b = cabs(z);
+ if( b < 0.125 ) {
+ z2.r = (x - y) * (x + y);
+ z2.i = 2.0 * x * y;
+
+ cn = 1.0;
+ n = 1.0;
+ ca.r = x;
+ ca.i = y;
+ sum.r = x;
+ sum.i = y;
+ do {
+ ct.r = z2.r * ca.r - z2.i * ca.i;
+ ct.i = z2.r * ca.i + z2.i * ca.r;
+ ca.r = ct.r;
+ ca.i = ct.i;
+
+ cn *= n;
+ n += 1.0;
+ cn /= n;
+ n += 1.0;
+ b = cn/n;
+
+ ct.r *= b;
+ ct.i *= b;
+ sum.r += ct.r;
+ sum.i += ct.i;
+ b = fabs(ct.r) + fabs(ct.i);
+ }
+ while( b > MACHEP );
+ w->r = sum.r;
+ w->i = sum.i;
+ return;
+ }
+ */
+
+ ca = x + y * I;
+ ct = ca * I;
+ /* sqrt( 1 - z*z) */
+ /* cmul( &ca, &ca, &zz ) */
+ /*x * x - y * y */
+ zz = (x - y) * (x + y) + (2.0 * x * y) * I;
+
+ zz = 1.0 - creal(zz) - cimag(zz) * I;
+ z2 = csqrt (zz);
+
+ zz = ct + z2;
+ zz = clog (zz);
+ /* multiply by 1/i = -i */
+ w = zz * (-1.0 * I);
+ return (w);
+}
diff --git a/lib/libm/src/s_casinf.c b/lib/libm/src/s_casinf.c
new file mode 100644
index 00000000000..84b2096a4fc
--- /dev/null
+++ b/lib/libm/src/s_casinf.c
@@ -0,0 +1,132 @@
+/* $OpenBSD: s_casinf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* casinf()
+ *
+ * Complex circular arc sine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * void casinf();
+ * cmplxf z, w;
+ *
+ * casinf( &z, &w );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Inverse complex sine:
+ *
+ * 2
+ * w = -i clog( iz + csqrt( 1 - z ) ).
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 1.1e-5 1.5e-6
+ * Larger relative error can be observed for z near zero.
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+float complex
+casinf(float complex z)
+{
+ float complex w;
+ float x, y;
+ static float complex ca, ct, zz, z2;
+ /*
+ float cn, n;
+ static float a, b, s, t, u, v, y2;
+ static cmplxf sum;
+ */
+
+ x = creal(z);
+ y = cimag(z);
+
+ if(y == 0.0f) {
+ if(fabsf(x) > 1.0f) {
+ w = M_PI_2 + 0.0f * I;
+ /*mtherr( "casinf", DOMAIN );*/
+ }
+ else {
+ w = asinf (x) + 0.0f * I;
+ }
+ return (w);
+ }
+
+ /* Power series expansion */
+ /*
+ b = cabsf(z);
+ if(b < 0.125) {
+ z2.r = (x - y) * (x + y);
+ z2.i = 2.0 * x * y;
+
+ cn = 1.0;
+ n = 1.0;
+ ca.r = x;
+ ca.i = y;
+ sum.r = x;
+ sum.i = y;
+ do {
+ ct.r = z2.r * ca.r - z2.i * ca.i;
+ ct.i = z2.r * ca.i + z2.i * ca.r;
+ ca.r = ct.r;
+ ca.i = ct.i;
+
+ cn *= n;
+ n += 1.0;
+ cn /= n;
+ n += 1.0;
+ b = cn/n;
+
+ ct.r *= b;
+ ct.i *= b;
+ sum.r += ct.r;
+ sum.i += ct.i;
+ b = fabsf(ct.r) + fabsf(ct.i);
+ }
+ while(b > MACHEPF);
+ w->r = sum.r;
+ w->i = sum.i;
+ return;
+ }
+ */
+
+
+ ca = x + y * I;
+ ct = ca * I; /* iz */
+ /* sqrt( 1 - z*z) */
+ /* cmul( &ca, &ca, &zz ) */
+ /*x * x - y * y */
+ zz = (x - y) * (x + y) + (2.0f * x * y) * I;
+ zz = 1.0f - creal(zz) - cimag(zz) * I;
+ z2 = csqrtf (zz);
+
+ zz = ct + z2;
+ zz = clogf (zz);
+ /* multiply by 1/i = -i */
+ w = zz * (-1.0f * I);
+ return (w);
+}
diff --git a/lib/libm/src/s_casinh.c b/lib/libm/src/s_casinh.c
new file mode 100644
index 00000000000..a249cf15ede
--- /dev/null
+++ b/lib/libm/src/s_casinh.c
@@ -0,0 +1,55 @@
+/* $OpenBSD: s_casinh.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* casinh
+ *
+ * Complex inverse hyperbolic sine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex casinh();
+ * double complex z, w;
+ *
+ * w = casinh (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * casinh z = -i casin iz .
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 1.8e-14 2.6e-15
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+double complex
+casinh(double complex z)
+{
+ double complex w;
+
+ w = -1.0 * I * casin (z * I);
+ return (w);
+}
diff --git a/lib/libm/src/s_casinhf.c b/lib/libm/src/s_casinhf.c
new file mode 100644
index 00000000000..334c29bcab2
--- /dev/null
+++ b/lib/libm/src/s_casinhf.c
@@ -0,0 +1,55 @@
+/* $OpenBSD: s_casinhf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* casinhf
+ *
+ * Complex inverse hyperbolic sine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float complex casinhf();
+ * float complex z, w;
+ *
+ * w = casinhf (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * casinh z = -i casin iz .
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 1.8e-14 2.6e-15
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+float complex
+casinhf(float complex z)
+{
+ float complex w;
+
+ w = -1.0f * I * casinf (z * I);
+ return (w);
+}
diff --git a/lib/libm/src/s_catan.c b/lib/libm/src/s_catan.c
new file mode 100644
index 00000000000..ddd7940456e
--- /dev/null
+++ b/lib/libm/src/s_catan.c
@@ -0,0 +1,126 @@
+/* $OpenBSD: s_catan.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* catan()
+ *
+ * Complex circular arc tangent
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex catan();
+ * double complex z, w;
+ *
+ * w = catan (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * If
+ * z = x + iy,
+ *
+ * then
+ * 1 ( 2x )
+ * Re w = - arctan(-----------) + k PI
+ * 2 ( 2 2)
+ * (1 - x - y )
+ *
+ * ( 2 2)
+ * 1 (x + (y+1) )
+ * Im w = - log(------------)
+ * 4 ( 2 2)
+ * (x + (y-1) )
+ *
+ * Where k is an arbitrary integer.
+ *
+ * catan(z) = -i catanh(iz).
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * DEC -10,+10 5900 1.3e-16 7.8e-18
+ * IEEE -10,+10 30000 2.3e-15 8.5e-17
+ * The check catan( ctan(z) ) = z, with |x| and |y| < PI/2,
+ * had peak relative error 1.5e-16, rms relative error
+ * 2.9e-17. See also clog().
+ */
+
+#include <complex.h>
+#include <math.h>
+
+#define MAXNUM 1.0e308
+
+static const double DP1 = 3.14159265160560607910E0;
+static const double DP2 = 1.98418714791870343106E-9;
+static const double DP3 = 1.14423774522196636802E-17;
+
+static double
+_redupi(double x)
+{
+ double t;
+ long i;
+
+ t = x/M_PI;
+ if(t >= 0.0)
+ t += 0.5;
+ else
+ t -= 0.5;
+
+ i = t; /* the multiple */
+ t = i;
+ t = ((x - t * DP1) - t * DP2) - t * DP3;
+ return (t);
+}
+
+double complex
+catan(double complex z)
+{
+ double complex w;
+ double a, t, x, x2, y;
+
+ x = creal (z);
+ y = cimag (z);
+
+ if ((x == 0.0) && (y > 1.0))
+ goto ovrf;
+
+ x2 = x * x;
+ a = 1.0 - x2 - (y * y);
+ if (a == 0.0)
+ goto ovrf;
+
+ t = 0.5 * atan2 (2.0 * x, a);
+ w = _redupi (t);
+
+ t = y - 1.0;
+ a = x2 + (t * t);
+ if (a == 0.0)
+ goto ovrf;
+
+ t = y + 1.0;
+ a = (x2 + (t * t))/a;
+ w = w + (0.25 * log (a)) * I;
+ return (w);
+
+ovrf:
+ /*mtherr ("catan", OVERFLOW);*/
+ w = MAXNUM + MAXNUM * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_catanf.c b/lib/libm/src/s_catanf.c
new file mode 100644
index 00000000000..e112e7f090a
--- /dev/null
+++ b/lib/libm/src/s_catanf.c
@@ -0,0 +1,124 @@
+/* $OpenBSD: s_catanf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* catanf()
+ *
+ * Complex circular arc tangent
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float complex catanf();
+ * float complex z, w;
+ *
+ * w = catanf( z );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * If
+ * z = x + iy,
+ *
+ * then
+ * 1 ( 2x )
+ * Re w = - arctan(-----------) + k PI
+ * 2 ( 2 2)
+ * (1 - x - y )
+ *
+ * ( 2 2)
+ * 1 (x + (y+1) )
+ * Im w = - log(------------)
+ * 4 ( 2 2)
+ * (x + (y-1) )
+ *
+ * Where k is an arbitrary integer.
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 2.3e-6 5.2e-8
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+#define MAXNUMF 1.0e38F
+
+static const double DP1 = 3.140625;
+static const double DP2 = 9.67502593994140625E-4;
+static const double DP3 = 1.509957990978376432E-7;
+
+static float
+_redupif(float xx)
+{
+ float x, t;
+ long i;
+
+ x = xx;
+ t = x/(float)M_PI;
+ if(t >= 0.0)
+ t += 0.5;
+ else
+ t -= 0.5;
+
+ i = t; /* the multiple */
+ t = i;
+ t = ((x - t * DP1) - t * DP2) - t * DP3;
+ return(t);
+}
+
+float complex
+catanf(float complex z)
+{
+ float complex w;
+ float a, t, x, x2, y;
+
+ x = creal (z);
+ y = cimag (z);
+
+ if((x == 0.0f) && (y > 1.0f))
+ goto ovrf;
+
+ x2 = x * x;
+ a = 1.0f - x2 - (y * y);
+ if (a == 0.0f)
+ goto ovrf;
+
+ t = 0.5f * atan2f(2.0f * x, a);
+ w = _redupif(t);
+
+ t = y - 1.0f;
+ a = x2 + (t * t);
+ if(a == 0.0f)
+ goto ovrf;
+
+ t = y + 1.0f;
+ a = (x2 + (t * t))/a;
+ w = w + (0.25f * logf (a)) * I;
+ return (w);
+
+ovrf:
+ /*mtherr( "catanf", OVERFLOW );*/
+ w = MAXNUMF + MAXNUMF * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_catanh.c b/lib/libm/src/s_catanh.c
new file mode 100644
index 00000000000..7a6d6f99646
--- /dev/null
+++ b/lib/libm/src/s_catanh.c
@@ -0,0 +1,55 @@
+/* $OpenBSD: s_catanh.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* catanh
+ *
+ * Complex inverse hyperbolic tangent
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex catanh();
+ * double complex z, w;
+ *
+ * w = catanh (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Inverse tanh, equal to -i catan (iz);
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 2.3e-16 6.2e-17
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+double complex
+catanh(double complex z)
+{
+ double complex w;
+
+ w = -1.0 * I * catan (z * I);
+ return (w);
+}
diff --git a/lib/libm/src/s_catanhf.c b/lib/libm/src/s_catanhf.c
new file mode 100644
index 00000000000..35fc8f7541d
--- /dev/null
+++ b/lib/libm/src/s_catanhf.c
@@ -0,0 +1,55 @@
+/* $OpenBSD: s_catanhf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* catanhf
+ *
+ * Complex inverse hyperbolic tangent
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float complex catanhf();
+ * float complex z, w;
+ *
+ * w = catanhf (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Inverse tanh, equal to -i catan (iz);
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 2.3e-16 6.2e-17
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+float complex
+catanhf(float complex z)
+{
+ float complex w;
+
+ w = -1.0f * I * catanf (z * I);
+ return (w);
+}
diff --git a/lib/libm/src/s_ccos.c b/lib/libm/src/s_ccos.c
new file mode 100644
index 00000000000..264143ab24c
--- /dev/null
+++ b/lib/libm/src/s_ccos.c
@@ -0,0 +1,84 @@
+/* $OpenBSD: s_ccos.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* ccos()
+ *
+ * Complex circular cosine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex ccos();
+ * double complex z, w;
+ *
+ * w = ccos (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * If
+ * z = x + iy,
+ *
+ * then
+ *
+ * w = cos x cosh y - i sin x sinh y.
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * DEC -10,+10 8400 4.5e-17 1.3e-17
+ * IEEE -10,+10 30000 3.8e-16 1.0e-16
+ */
+
+#include <complex.h>
+#include <math.h>
+
+/* calculate cosh and sinh */
+
+static void
+_cchsh(double x, double *c, double *s)
+{
+ double e, ei;
+
+ if (fabs(x) <= 0.5) {
+ *c = cosh(x);
+ *s = sinh(x);
+ }
+ else {
+ e = exp(x);
+ ei = 0.5/e;
+ e = 0.5 * e;
+ *s = e - ei;
+ *c = e + ei;
+ }
+}
+
+double complex
+ccos(double complex z)
+{
+ double complex w;
+ double ch, sh;
+
+ _cchsh( cimag(z), &ch, &sh );
+ w = cos(creal (z)) * ch - (sin (creal (z)) * sh) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_ccosf.c b/lib/libm/src/s_ccosf.c
new file mode 100644
index 00000000000..299e06b1276
--- /dev/null
+++ b/lib/libm/src/s_ccosf.c
@@ -0,0 +1,84 @@
+/* $OpenBSD: s_ccosf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* ccosf()
+ *
+ * Complex circular cosine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * void ccosf();
+ * cmplxf z, w;
+ *
+ * ccosf( &z, &w );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * If
+ * z = x + iy,
+ *
+ * then
+ *
+ * w = cos x cosh y - i sin x sinh y.
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 1.8e-7 5.5e-8
+ */
+
+#include <complex.h>
+#include <math.h>
+
+/* calculate cosh and sinh */
+
+static void
+_cchshf(float xx, float *c, float *s)
+{
+ float x, e, ei;
+
+ x = xx;
+ if(fabsf(x) <= 0.5f) {
+ *c = coshf(x);
+ *s = sinhf(x);
+ }
+ else {
+ e = expf(x);
+ ei = 0.5f/e;
+ e = 0.5f * e;
+ *s = e - ei;
+ *c = e + ei;
+ }
+}
+
+float complex
+ccosf(float complex z)
+{
+ float complex w;
+ float ch, sh;
+
+ _cchshf( cimag(z), &ch, &sh );
+ w = cosf( creal(z) ) * ch + ( -sinf( creal(z) ) * sh) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_ccosh.c b/lib/libm/src/s_ccosh.c
new file mode 100644
index 00000000000..0267b6f2a15
--- /dev/null
+++ b/lib/libm/src/s_ccosh.c
@@ -0,0 +1,58 @@
+/* $OpenBSD: s_ccosh.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* ccosh
+ *
+ * Complex hyperbolic cosine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex ccosh();
+ * double complex z, w;
+ *
+ * w = ccosh (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * ccosh(z) = cosh x cos y + i sinh x sin y .
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 2.9e-16 8.1e-17
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+double complex
+ccosh(double complex z)
+{
+ double complex w;
+ double x, y;
+
+ x = creal(z);
+ y = cimag(z);
+ w = cosh (x) * cos (y) + (sinh (x) * sin (y)) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_ccoshf.c b/lib/libm/src/s_ccoshf.c
new file mode 100644
index 00000000000..527a47afb98
--- /dev/null
+++ b/lib/libm/src/s_ccoshf.c
@@ -0,0 +1,58 @@
+/* $OpenBSD: s_ccoshf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* ccoshf
+ *
+ * Complex hyperbolic cosine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float complex ccoshf();
+ * float complex z, w;
+ *
+ * w = ccoshf (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * ccosh(z) = cosh x cos y + i sinh x sin y .
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 2.9e-16 8.1e-17
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+float complex
+ccoshf(float complex z)
+{
+ float complex w;
+ float x, y;
+
+ x = creal(z);
+ y = cimag(z);
+ w = coshf (x) * cosf (y) + (sinhf (x) * sinf (y)) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_cexp.c b/lib/libm/src/s_cexp.c
new file mode 100644
index 00000000000..52241a8eb5e
--- /dev/null
+++ b/lib/libm/src/s_cexp.c
@@ -0,0 +1,70 @@
+/* $OpenBSD: s_cexp.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* cexp()
+ *
+ * Complex exponential function
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex cexp ();
+ * double complex z, w;
+ *
+ * w = cexp (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the exponential of the complex argument z
+ * into the complex result w.
+ *
+ * If
+ * z = x + iy,
+ * r = exp(x),
+ *
+ * then
+ *
+ * w = r cos y + i r sin y.
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * DEC -10,+10 8700 3.7e-17 1.1e-17
+ * IEEE -10,+10 30000 3.0e-16 8.7e-17
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+double complex
+cexp(double complex z)
+{
+ double complex w;
+ double r, x, y;
+
+ x = creal (z);
+ y = cimag (z);
+ r = exp (x);
+ w = r * cos (y) + r * sin (y) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_cexpf.c b/lib/libm/src/s_cexpf.c
new file mode 100644
index 00000000000..041bf84318d
--- /dev/null
+++ b/lib/libm/src/s_cexpf.c
@@ -0,0 +1,67 @@
+/* $OpenBSD: s_cexpf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* cexpf()
+ *
+ * Complex exponential function
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * void cexpf();
+ * cmplxf z, w;
+ *
+ * cexpf( &z, &w );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the exponential of the complex argument z
+ * into the complex result w.
+ *
+ * If
+ * z = x + iy,
+ * r = exp(x),
+ *
+ * then
+ *
+ * w = r cos y + i r sin y.
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 1.4e-7 4.5e-8
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+float complex
+cexpf(float complex z)
+{
+ float complex w;
+ float r;
+
+ r = expf( creal(z) );
+ w = r * cosf( cimag(z) ) + r * sinf( cimag(z) ) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_cimag.c b/lib/libm/src/s_cimag.c
new file mode 100644
index 00000000000..85aaa2975d1
--- /dev/null
+++ b/lib/libm/src/s_cimag.c
@@ -0,0 +1,25 @@
+/* $OpenBSD: s_cimag.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <complex.h>
+#include <math.h>
+
+double
+cimag(double complex z)
+{
+ return __imag__ z;
+}
diff --git a/lib/libm/src/s_cimagf.c b/lib/libm/src/s_cimagf.c
new file mode 100644
index 00000000000..609851fbbda
--- /dev/null
+++ b/lib/libm/src/s_cimagf.c
@@ -0,0 +1,25 @@
+/* $OpenBSD: s_cimagf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <complex.h>
+#include <math.h>
+
+float
+cimagf(float complex z)
+{
+ return __imag__ z;
+}
diff --git a/lib/libm/src/s_clog.c b/lib/libm/src/s_clog.c
new file mode 100644
index 00000000000..31163700607
--- /dev/null
+++ b/lib/libm/src/s_clog.c
@@ -0,0 +1,72 @@
+/* $OpenBSD: s_clog.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* clog.c
+ *
+ * Complex natural logarithm
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex clog();
+ * double complex z, w;
+ *
+ * w = clog (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns complex logarithm to the base e (2.718...) of
+ * the complex argument x.
+ *
+ * If z = x + iy, r = sqrt( x**2 + y**2 ),
+ * then
+ * w = log(r) + i arctan(y/x).
+ *
+ * The arctangent ranges from -PI to +PI.
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * DEC -10,+10 7000 8.5e-17 1.9e-17
+ * IEEE -10,+10 30000 5.0e-15 1.1e-16
+ *
+ * Larger relative error can be observed for z near 1 +i0.
+ * In IEEE arithmetic the peak absolute error is 5.2e-16, rms
+ * absolute error 1.0e-16.
+ */
+
+#include <complex.h>
+#include <math.h>
+
+double complex
+clog(double complex z)
+{
+ double complex w;
+ double p, rr;
+
+ /*rr = sqrt( z->r * z->r + z->i * z->i );*/
+ rr = cabs(z);
+ p = log(rr);
+ rr = atan2 (cimag (z), creal (z));
+ w = p + rr * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_clogf.c b/lib/libm/src/s_clogf.c
new file mode 100644
index 00000000000..2cea0f218be
--- /dev/null
+++ b/lib/libm/src/s_clogf.c
@@ -0,0 +1,72 @@
+/* $OpenBSD: s_clogf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* clogf.c
+ *
+ * Complex natural logarithm
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * void clogf();
+ * cmplxf z, w;
+ *
+ * clogf( &z, &w );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns complex logarithm to the base e (2.718...) of
+ * the complex argument x.
+ *
+ * If z = x + iy, r = sqrt( x**2 + y**2 ),
+ * then
+ * w = log(r) + i arctan(y/x).
+ *
+ * The arctangent ranges from -PI to +PI.
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 1.9e-6 6.2e-8
+ *
+ * Larger relative error can be observed for z near 1 +i0.
+ * In IEEE arithmetic the peak absolute error is 3.1e-7.
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+float complex
+clogf(float complex z)
+{
+ float complex w;
+ float p, rr, x, y;
+
+ x = creal(z);
+ y = cimag(z);
+ rr = atan2f(y, x);
+ p = cabsf(z);
+ p = logf(p);
+ w = p + rr * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_conj.c b/lib/libm/src/s_conj.c
new file mode 100644
index 00000000000..fd38a9d034c
--- /dev/null
+++ b/lib/libm/src/s_conj.c
@@ -0,0 +1,25 @@
+/* $OpenBSD: s_conj.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <complex.h>
+#include <math.h>
+
+double complex
+conj(double complex z)
+{
+ return ~z;
+}
diff --git a/lib/libm/src/s_conjf.c b/lib/libm/src/s_conjf.c
new file mode 100644
index 00000000000..d5b765790c6
--- /dev/null
+++ b/lib/libm/src/s_conjf.c
@@ -0,0 +1,25 @@
+/* $OpenBSD: s_conjf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <complex.h>
+#include <math.h>
+
+float complex
+conjf(float complex z)
+{
+ return ~z;
+}
diff --git a/lib/libm/src/s_cpow.c b/lib/libm/src/s_cpow.c
new file mode 100644
index 00000000000..6b0537393ce
--- /dev/null
+++ b/lib/libm/src/s_cpow.c
@@ -0,0 +1,71 @@
+/* $OpenBSD: s_cpow.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* cpow
+ *
+ * Complex power function
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex cpow();
+ * double complex a, z, w;
+ *
+ * w = cpow (a, z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Raises complex A to the complex Zth power.
+ * Definition is per AMS55 # 4.2.8,
+ * analytically equivalent to cpow(a,z) = cexp(z clog(a)).
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 9.4e-15 1.5e-15
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+double complex
+cpow(double complex a, double complex z)
+{
+ double complex w;
+ double x, y, r, theta, absa, arga;
+
+ x = creal (z);
+ y = cimag (z);
+ absa = cabs (a);
+ if (absa == 0.0) {
+ return (0.0 + 0.0 * I);
+ }
+ arga = carg (a);
+ r = pow (absa, x);
+ theta = x * arga;
+ if (y != 0.0) {
+ r = r * exp (-y * arga);
+ theta = theta + y * log (absa);
+ }
+ w = r * cos (theta) + (r * sin (theta)) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_cpowf.c b/lib/libm/src/s_cpowf.c
new file mode 100644
index 00000000000..8a24596d338
--- /dev/null
+++ b/lib/libm/src/s_cpowf.c
@@ -0,0 +1,71 @@
+/* $OpenBSD: s_cpowf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* cpowf
+ *
+ * Complex power function
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float complex cpowf();
+ * float complex a, z, w;
+ *
+ * w = cpowf (a, z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Raises complex A to the complex Zth power.
+ * Definition is per AMS55 # 4.2.8,
+ * analytically equivalent to cpow(a,z) = cexp(z clog(a)).
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 9.4e-15 1.5e-15
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+float complex
+cpowf(float complex a, float complex z)
+{
+ float complex w;
+ float x, y, r, theta, absa, arga;
+
+ x = creal (z);
+ y = cimag (z);
+ absa = cabsf (a);
+ if (absa == 0.0f) {
+ return (0.0f + 0.0f * I);
+ }
+ arga = cargf (a);
+ r = powf (absa, x);
+ theta = x * arga;
+ if (y != 0.0f) {
+ r = r * expf (-y * arga);
+ theta = theta + y * logf (absa);
+ }
+ w = r * cosf (theta) + (r * sinf (theta)) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_cproj.c b/lib/libm/src/s_cproj.c
new file mode 100644
index 00000000000..7064e9285c3
--- /dev/null
+++ b/lib/libm/src/s_cproj.c
@@ -0,0 +1,32 @@
+/* $OpenBSD: s_cproj.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <complex.h>
+#include <math.h>
+
+double complex
+cproj(double complex z)
+{
+ double complex res;
+
+ if (isinf(__real__ z) || isinf(__imag__ z)) {
+ __real__ res = INFINITY;
+ __imag__ res = copysign(0.0, __imag__ z);
+ }
+
+ return res;
+}
diff --git a/lib/libm/src/s_cprojf.c b/lib/libm/src/s_cprojf.c
new file mode 100644
index 00000000000..af754ed3d70
--- /dev/null
+++ b/lib/libm/src/s_cprojf.c
@@ -0,0 +1,32 @@
+/* $OpenBSD: s_cprojf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <complex.h>
+#include <math.h>
+
+float complex
+cprojf(float complex z)
+{
+ float complex res;
+
+ if (isinf(__real__ z) || isinf(__imag__ z)) {
+ __real__ res = INFINITY;
+ __imag__ res = copysign(0.0, __imag__ z);
+ }
+
+ return res;
+}
diff --git a/lib/libm/src/s_creal.c b/lib/libm/src/s_creal.c
new file mode 100644
index 00000000000..55c36e8d839
--- /dev/null
+++ b/lib/libm/src/s_creal.c
@@ -0,0 +1,25 @@
+/* $OpenBSD: s_creal.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <complex.h>
+#include <math.h>
+
+double
+creal(double complex z)
+{
+ return __real__ z;
+}
diff --git a/lib/libm/src/s_crealf.c b/lib/libm/src/s_crealf.c
new file mode 100644
index 00000000000..12c54ea615b
--- /dev/null
+++ b/lib/libm/src/s_crealf.c
@@ -0,0 +1,25 @@
+/* $OpenBSD: s_crealf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 <complex.h>
+#include <math.h>
+
+float
+crealf(float complex z)
+{
+ return __real__ z;
+}
diff --git a/lib/libm/src/s_csin.c b/lib/libm/src/s_csin.c
new file mode 100644
index 00000000000..ad249de7ac0
--- /dev/null
+++ b/lib/libm/src/s_csin.c
@@ -0,0 +1,86 @@
+/* $OpenBSD: s_csin.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* csin()
+ *
+ * Complex circular sine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex csin();
+ * double complex z, w;
+ *
+ * w = csin (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * If
+ * z = x + iy,
+ *
+ * then
+ *
+ * w = sin x cosh y + i cos x sinh y.
+ *
+ * csin(z) = -i csinh(iz).
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * DEC -10,+10 8400 5.3e-17 1.3e-17
+ * IEEE -10,+10 30000 3.8e-16 1.0e-16
+ * Also tested by csin(casin(z)) = z.
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+/* calculate cosh and sinh */
+
+static void
+cchsh(double x, double *c, double *s)
+{
+ double e, ei;
+
+ if (fabs(x) <= 0.5) {
+ *c = cosh(x);
+ *s = sinh(x);
+ }
+ else {
+ e = exp(x);
+ ei = 0.5/e;
+ e = 0.5 * e;
+ *s = e - ei;
+ *c = e + ei;
+ }
+}
+
+double complex
+csin(double complex z)
+{
+ double complex w;
+ double ch, sh;
+
+ cchsh( cimag (z), &ch, &sh );
+ w = sin (creal(z)) * ch + (cos (creal(z)) * sh) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_csinf.c b/lib/libm/src/s_csinf.c
new file mode 100644
index 00000000000..aacc59f9dc6
--- /dev/null
+++ b/lib/libm/src/s_csinf.c
@@ -0,0 +1,85 @@
+/* $OpenBSD: s_csinf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* csinf()
+ *
+ * Complex circular sine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * void csinf();
+ * cmplxf z, w;
+ *
+ * csinf( &z, &w );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * If
+ * z = x + iy,
+ *
+ * then
+ *
+ * w = sin x cosh y + i cos x sinh y.
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 1.9e-7 5.5e-8
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+/* calculate cosh and sinh */
+
+static void
+cchshf(float xx, float *c, float *s)
+{
+ float x, e, ei;
+
+ x = xx;
+ if(fabsf(x) <= 0.5f) {
+ *c = coshf(x);
+ *s = sinhf(x);
+ }
+ else {
+ e = expf(x);
+ ei = 0.5f/e;
+ e = 0.5f * e;
+ *s = e - ei;
+ *c = e + ei;
+ }
+}
+
+float complex
+csinf(float complex z)
+{
+ float complex w;
+ float ch, sh;
+
+ cchshf((float) cimag(z), &ch, &sh);
+ w = sinf(creal(z)) * ch + (cosf(creal(z)) * sh) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_csinh.c b/lib/libm/src/s_csinh.c
new file mode 100644
index 00000000000..ece633cda8f
--- /dev/null
+++ b/lib/libm/src/s_csinh.c
@@ -0,0 +1,57 @@
+/* $OpenBSD: s_csinh.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* csinh
+ *
+ * Complex hyperbolic sine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex csinh();
+ * double complex z, w;
+ *
+ * w = csinh (z);
+ *
+ * DESCRIPTION:
+ *
+ * csinh z = (cexp(z) - cexp(-z))/2
+ * = sinh x * cos y + i cosh x * sin y .
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 3.1e-16 8.2e-17
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+double complex
+csinh(double complex z)
+{
+ double complex w;
+ double x, y;
+
+ x = creal(z);
+ y = cimag(z);
+ w = sinh (x) * cos (y) + (cosh (x) * sin (y)) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_csinhf.c b/lib/libm/src/s_csinhf.c
new file mode 100644
index 00000000000..170b4405640
--- /dev/null
+++ b/lib/libm/src/s_csinhf.c
@@ -0,0 +1,57 @@
+/* $OpenBSD: s_csinhf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* csinhf
+ *
+ * Complex hyperbolic sine
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float complex csinhf();
+ * float complex z, w;
+ *
+ * w = csinhf (z);
+ *
+ * DESCRIPTION:
+ *
+ * csinh z = (cexp(z) - cexp(-z))/2
+ * = sinh x * cos y + i cosh x * sin y .
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 3.1e-16 8.2e-17
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+float complex
+csinhf(float complex z)
+{
+ float complex w;
+ float x, y;
+
+ x = creal(z);
+ y = cimag(z);
+ w = sinhf (x) * cosf (y) + (coshf (x) * sinf (y)) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_csqrt.c b/lib/libm/src/s_csqrt.c
new file mode 100644
index 00000000000..3ed4aa56076
--- /dev/null
+++ b/lib/libm/src/s_csqrt.c
@@ -0,0 +1,131 @@
+/* $OpenBSD: s_csqrt.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* csqrt()
+ *
+ * Complex square root
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex csqrt();
+ * double complex z, w;
+ *
+ * w = csqrt (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ *
+ * If z = x + iy, r = |z|, then
+ *
+ * 1/2
+ * Re w = [ (r + x)/2 ] ,
+ *
+ * 1/2
+ * Im w = [ (r - x)/2 ] .
+ *
+ * Cancellation error in r-x or r+x is avoided by using the
+ * identity 2 Re w Im w = y.
+ *
+ * Note that -w is also a square root of z. The root chosen
+ * is always in the right half plane and Im w has the same sign as y.
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * DEC -10,+10 25000 3.2e-17 9.6e-18
+ * IEEE -10,+10 1,000,000 2.9e-16 6.1e-17
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+double complex
+csqrt(double complex z)
+{
+ double complex w;
+ double x, y, r, t, scale;
+
+ x = creal (z);
+ y = cimag (z);
+
+ if (y == 0.0) {
+ if (x == 0.0) {
+ w = 0.0 + y * I;
+ }
+ else {
+ r = fabs (x);
+ r = sqrt (r);
+ if (x < 0.0) {
+ w = 0.0 + r * I;
+ }
+ else {
+ w = r + y * I;
+ }
+ }
+ return (w);
+ }
+ if (x == 0.0) {
+ r = fabs (y);
+ r = sqrt (0.5*r);
+ if (y > 0)
+ w = r + r * I;
+ else
+ w = r - r * I;
+ return (w);
+ }
+ /* Rescale to avoid internal overflow or underflow. */
+ if ((fabs(x) > 4.0) || (fabs(y) > 4.0)) {
+ x *= 0.25;
+ y *= 0.25;
+ scale = 2.0;
+ }
+ else {
+ x *= 1.8014398509481984e16; /* 2^54 */
+ y *= 1.8014398509481984e16;
+ scale = 7.450580596923828125e-9; /* 2^-27 */
+#if 0
+ x *= 4.0;
+ y *= 4.0;
+ scale = 0.5;
+#endif
+ }
+ w = x + y * I;
+ r = cabs(w);
+ if (x > 0) {
+ t = sqrt(0.5 * r + 0.5 * x);
+ r = scale * fabs((0.5 * y) / t);
+ t *= scale;
+ }
+ else {
+ r = sqrt( 0.5 * r - 0.5 * x );
+ t = scale * fabs( (0.5 * y) / r );
+ r *= scale;
+ }
+ if (y < 0)
+ w = t - r * I;
+ else
+ w = t + r * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_csqrtf.c b/lib/libm/src/s_csqrtf.c
new file mode 100644
index 00000000000..9f9e8982b0e
--- /dev/null
+++ b/lib/libm/src/s_csqrtf.c
@@ -0,0 +1,131 @@
+/* $OpenBSD: s_csqrtf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* csqrtf()
+ *
+ * Complex square root
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float complex csqrtf();
+ * float complex z, w;
+ *
+ * w = csqrtf( z );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ *
+ * If z = x + iy, r = |z|, then
+ *
+ * 1/2
+ * Re w = [ (r + x)/2 ] ,
+ *
+ * 1/2
+ * Im w = [ (r - x)/2 ] .
+ *
+ * Cancellation error in r-x or r+x is avoided by using the
+ * identity 2 Re w Im w = y.
+ *
+ * Note that -w is also a square root of z. The root chosen
+ * is always in the right half plane and Im w has the same sign as y.
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 1,000,000 1.8e-7 3.5e-8
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+float complex
+csqrtf(float complex z)
+{
+ float complex w;
+ float x, y, r, t, scale;
+
+ x = creal(z);
+ y = cimag(z);
+
+ if(y == 0.0f) {
+ if (x < 0.0f) {
+ w = 0.0f + sqrtf(-x) * I;
+ return (w);
+ }
+ else if (x == 0.0f) {
+ return (0.0f + y * I);
+ }
+ else {
+ w = sqrtf(x) + y * I;
+ return (w);
+ }
+ }
+
+ if (x == 0.0f) {
+ r = fabsf(y);
+ r = sqrtf(0.5f*r);
+ if(y > 0)
+ w = r + r * I;
+ else
+ w = r - r * I;
+ return (w);
+ }
+
+ /* Rescale to avoid internal overflow or underflow. */
+ if ((fabsf(x) > 4.0f) || (fabsf(y) > 4.0f)) {
+ x *= 0.25f;
+ y *= 0.25f;
+ scale = 2.0f;
+ }
+ else {
+ x *= 6.7108864e7f; /* 2^26 */
+ y *= 6.7108864e7f;
+ scale = 1.220703125e-4f; /* 2^-13 */
+#if 0
+ x *= 4.0f;
+ y *= 4.0f;
+ scale = 0.5f;
+#endif
+ }
+ w = x + y * I;
+ r = cabsf(w);
+ if (x > 0) {
+ t = sqrtf( 0.5f * r + 0.5f * x );
+ r = scale * fabsf((0.5f * y) / t);
+ t *= scale;
+ }
+ else {
+ r = sqrtf(0.5f * r - 0.5f * x);
+ t = scale * fabsf((0.5f * y) / r);
+ r *= scale;
+ }
+
+ if (y < 0)
+ w = t - r * I;
+ else
+ w = t + r * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_ctan.c b/lib/libm/src/s_ctan.c
new file mode 100644
index 00000000000..4db6fb18e83
--- /dev/null
+++ b/lib/libm/src/s_ctan.c
@@ -0,0 +1,152 @@
+/* $OpenBSD: s_ctan.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* ctan()
+ *
+ * Complex circular tangent
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex ctan();
+ * double complex z, w;
+ *
+ * w = ctan (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * If
+ * z = x + iy,
+ *
+ * then
+ *
+ * sin 2x + i sinh 2y
+ * w = --------------------.
+ * cos 2x + cosh 2y
+ *
+ * On the real axis the denominator is zero at odd multiples
+ * of PI/2. The denominator is evaluated by its Taylor
+ * series near these points.
+ *
+ * ctan(z) = -i ctanh(iz).
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * DEC -10,+10 5200 7.1e-17 1.6e-17
+ * IEEE -10,+10 30000 7.2e-16 1.2e-16
+ * Also tested by ctan * ccot = 1 and catan(ctan(z)) = z.
+ */
+
+#include <complex.h>
+#include <math.h>
+
+#define MACHEP 1.1e-16
+#define MAXNUM 1.0e308
+
+static const double DP1 = 3.14159265160560607910E0;
+static const double DP2 = 1.98418714791870343106E-9;
+static const double DP3 = 1.14423774522196636802E-17;
+
+static double
+_redupi(double x)
+{
+ double t;
+ long i;
+
+ t = x/M_PI;
+ if (t >= 0.0)
+ t += 0.5;
+ else
+ t -= 0.5;
+
+ i = t; /* the multiple */
+ t = i;
+ t = ((x - t * DP1) - t * DP2) - t * DP3;
+ return (t);
+}
+
+/* Taylor series expansion for cosh(2y) - cos(2x) */
+
+static double
+_ctans(double complex z)
+{
+ double f, x, x2, y, y2, rn, t;
+ double d;
+
+ x = fabs (2.0 * creal (z));
+ y = fabs (2.0 * cimag(z));
+
+ x = _redupi(x);
+
+ x = x * x;
+ y = y * y;
+ x2 = 1.0;
+ y2 = 1.0;
+ f = 1.0;
+ rn = 0.0;
+ d = 0.0;
+ do {
+ rn += 1.0;
+ f *= rn;
+ rn += 1.0;
+ f *= rn;
+ x2 *= x;
+ y2 *= y;
+ t = y2 + x2;
+ t /= f;
+ d += t;
+
+ rn += 1.0;
+ f *= rn;
+ rn += 1.0;
+ f *= rn;
+ x2 *= x;
+ y2 *= y;
+ t = y2 - x2;
+ t /= f;
+ d += t;
+ }
+ while (fabs(t/d) > MACHEP)
+ ;
+ return (d);
+}
+
+double complex
+ctan(double complex z)
+{
+ double complex w;
+ double d;
+
+ d = cos (2.0 * creal (z)) + cosh (2.0 * cimag (z));
+
+ if (fabs(d) < 0.25)
+ d = _ctans (z);
+
+ if (d == 0.0) {
+ /*mtherr ("ctan", OVERFLOW);*/
+ w = MAXNUM + MAXNUM * I;
+ return (w);
+ }
+
+ w = sin (2.0 * creal(z)) / d + (sinh (2.0 * cimag(z)) / d) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_ctanf.c b/lib/libm/src/s_ctanf.c
new file mode 100644
index 00000000000..ca67d602e55
--- /dev/null
+++ b/lib/libm/src/s_ctanf.c
@@ -0,0 +1,148 @@
+/* $OpenBSD: s_ctanf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* ctanf()
+ *
+ * Complex circular tangent
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * void ctanf();
+ * cmplxf z, w;
+ *
+ * ctanf( &z, &w );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * If
+ * z = x + iy,
+ *
+ * then
+ *
+ * sin 2x + i sinh 2y
+ * w = --------------------.
+ * cos 2x + cosh 2y
+ *
+ * On the real axis the denominator is zero at odd multiples
+ * of PI/2. The denominator is evaluated by its Taylor
+ * series near these points.
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 3.3e-7 5.1e-8
+ */
+
+#include <complex.h>
+#include <math.h>
+
+#define MACHEPF 3.0e-8
+#define MAXNUMF 1.0e38f
+
+static const double DP1 = 3.140625;
+static const double DP2 = 9.67502593994140625E-4;
+static const double DP3 = 1.509957990978376432E-7;
+
+static float
+_redupif(float xx)
+{
+ float x, t;
+ long i;
+
+ x = xx;
+ t = x/(float)M_PI;
+ if(t >= 0.0)
+ t += 0.5;
+ else
+ t -= 0.5;
+
+ i = t; /* the multiple */
+ t = i;
+ t = ((x - t * DP1) - t * DP2) - t * DP3;
+ return(t);
+}
+
+/* Taylor series expansion for cosh(2y) - cos(2x) */
+
+static float
+_ctansf(float complex z)
+{
+ float f, x, x2, y, y2, rn, t, d;
+
+ x = fabsf(2.0f * creal(z));
+ y = fabsf(2.0f * cimag(z));
+
+ x = _redupif(x);
+
+ x = x * x;
+ y = y * y;
+ x2 = 1.0f;
+ y2 = 1.0f;
+ f = 1.0f;
+ rn = 0.0f;
+ d = 0.0f;
+ do {
+ rn += 1.0f;
+ f *= rn;
+ rn += 1.0f;
+ f *= rn;
+ x2 *= x;
+ y2 *= y;
+ t = y2 + x2;
+ t /= f;
+ d += t;
+
+ rn += 1.0f;
+ f *= rn;
+ rn += 1.0f;
+ f *= rn;
+ x2 *= x;
+ y2 *= y;
+ t = y2 - x2;
+ t /= f;
+ d += t;
+ }
+ while (fabsf(t/d) > MACHEPF)
+ ;
+ return(d);
+}
+
+float complex
+ctanf(float complex z)
+{
+ float complex w;
+ float d;
+
+ d = cosf( 2.0f * creal(z) ) + coshf( 2.0f * cimag(z) );
+
+ if(fabsf(d) < 0.25f)
+ d = _ctansf(z);
+
+ if (d == 0.0f) {
+ /*mtherr( "ctanf", OVERFLOW );*/
+ w = MAXNUMF + MAXNUMF * I;
+ return (w);
+ }
+ w = sinf (2.0f * creal(z)) / d + (sinhf (2.0f * cimag(z)) / d) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_ctanh.c b/lib/libm/src/s_ctanh.c
new file mode 100644
index 00000000000..30c20155672
--- /dev/null
+++ b/lib/libm/src/s_ctanh.c
@@ -0,0 +1,59 @@
+/* $OpenBSD: s_ctanh.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* ctanh
+ *
+ * Complex hyperbolic tangent
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex ctanh();
+ * double complex z, w;
+ *
+ * w = ctanh (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * tanh z = (sinh 2x + i sin 2y) / (cosh 2x + cos 2y) .
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 1.7e-14 2.4e-16
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+double complex
+ctanh(double complex z)
+{
+ double complex w;
+ double x, y, d;
+
+ x = creal(z);
+ y = cimag(z);
+ d = cosh (2.0 * x) + cos (2.0 * y);
+ w = sinh (2.0 * x) / d + (sin (2.0 * y) / d) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_ctanhf.c b/lib/libm/src/s_ctanhf.c
new file mode 100644
index 00000000000..a0f61614452
--- /dev/null
+++ b/lib/libm/src/s_ctanhf.c
@@ -0,0 +1,59 @@
+/* $OpenBSD: s_ctanhf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and 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.
+ */
+
+/* ctanhf
+ *
+ * Complex hyperbolic tangent
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float complex ctanhf();
+ * float complex z, w;
+ *
+ * w = ctanhf (z);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * tanh z = (sinh 2x + i sin 2y) / (cosh 2x + cos 2y) .
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -10,+10 30000 1.7e-14 2.4e-16
+ *
+ */
+
+#include <complex.h>
+#include <math.h>
+
+float complex
+ctanhf(float complex z)
+{
+ float complex w;
+ float x, y, d;
+
+ x = creal(z);
+ y = cimag(z);
+ d = coshf (2.0f * x) + cosf (2.0f * y);
+ w = sinhf (2.0f * x) / d + (sinf (2.0f * y) / d) * I;
+ return (w);
+}
diff --git a/lib/libm/src/s_erf.c b/lib/libm/src/s_erf.c
index 844e2f5565a..22944c1bc83 100644
--- a/lib/libm/src/s_erf.c
+++ b/lib/libm/src/s_erf.c
@@ -235,7 +235,7 @@ erf(double x)
}
z = x;
SET_LOW_WORD(z,0);
- r = __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S);
+ r = exp(-z*z-0.5625)*exp((z-x)*(z+x)+R/S);
if(hx>=0) return one-r/x; else return r/x-one;
}
@@ -293,8 +293,7 @@ erfc(double x)
}
z = x;
SET_LOW_WORD(z,0);
- r = __ieee754_exp(-z*z-0.5625)*
- __ieee754_exp((z-x)*(z+x)+R/S);
+ r = exp(-z*z-0.5625) * exp((z-x)*(z+x)+R/S);
if(hx>0) return r/x; else return two-r/x;
} else {
if(hx>0) return tiny*tiny; else return two-tiny;
diff --git a/lib/libm/src/s_erff.c b/lib/libm/src/s_erff.c
index faff192c21e..7eadb30dfa3 100644
--- a/lib/libm/src/s_erff.c
+++ b/lib/libm/src/s_erff.c
@@ -144,7 +144,7 @@ erff(float x)
}
GET_FLOAT_WORD(ix,x);
SET_FLOAT_WORD(z,ix&0xfffff000);
- r = __ieee754_expf(-z*z-(float)0.5625)*__ieee754_expf((z-x)*(z+x)+R/S);
+ r = expf(-z*z-(float)0.5625)*expf((z-x)*(z+x)+R/S);
if(hx>=0) return one-r/x; else return r/x-one;
}
@@ -202,8 +202,7 @@ erfcf(float x)
}
GET_FLOAT_WORD(ix,x);
SET_FLOAT_WORD(z,ix&0xfffff000);
- r = __ieee754_expf(-z*z-(float)0.5625)*
- __ieee754_expf((z-x)*(z+x)+R/S);
+ r = expf(-z*z-(float)0.5625) * expf((z-x)*(z+x)+R/S);
if(hx>0) return r/x; else return two-r/x;
} else {
if(hx>0) return tiny*tiny; else return two-tiny;
diff --git a/lib/libm/src/s_fdim.c b/lib/libm/src/s_fdim.c
new file mode 100644
index 00000000000..6af4ba038b9
--- /dev/null
+++ b/lib/libm/src/s_fdim.c
@@ -0,0 +1,44 @@
+/* $OpenBSD: s_fdim.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*-
+ * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#include <math.h>
+
+#define DECL(type, fn) \
+type \
+fn(type x, type y) \
+{ \
+ \
+ if (isnan(x)) \
+ return (x); \
+ if (isnan(y)) \
+ return (y); \
+ return (x > y ? x - y : 0.0); \
+}
+
+DECL(double, fdim)
+DECL(float, fdimf)
+DECL(long double, fdiml)
diff --git a/lib/libm/src/s_fmax.c b/lib/libm/src/s_fmax.c
new file mode 100644
index 00000000000..76f91272f2c
--- /dev/null
+++ b/lib/libm/src/s_fmax.c
@@ -0,0 +1,55 @@
+/* $OpenBSD: s_fmax.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*-
+ * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+double
+fmax(double x, double y)
+{
+ struct ieee_double *px = (struct ieee_double *)&x;
+ struct ieee_double *py = (struct ieee_double *)&y;
+
+ /* Check for NaNs to avoid raising spurious exceptions. */
+ if (px->dbl_exp == DBL_EXP_INFNAN &&
+ (px->dbl_frach | px->dbl_fracl) != 0)
+ return (y);
+ if (py->dbl_exp == DBL_EXP_INFNAN &&
+ (py->dbl_frach | py->dbl_fracl) != 0)
+ return (x);
+
+ /* Handle comparisons of signed zeroes. */
+ if (px->dbl_sign != py->dbl_sign &&
+ px->dbl_sign == 1)
+ return (y);
+ if (px->dbl_sign != py->dbl_sign &&
+ px->dbl_sign == 0)
+ return (x);
+
+ return (x > y ? x : y);
+}
diff --git a/lib/libm/src/s_fmaxf.c b/lib/libm/src/s_fmaxf.c
new file mode 100644
index 00000000000..472372950d8
--- /dev/null
+++ b/lib/libm/src/s_fmaxf.c
@@ -0,0 +1,51 @@
+/* $OpenBSD: s_fmaxf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*-
+ * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+float
+fmaxf(float x, float y)
+{
+ struct ieee_single *px = (struct ieee_single *)&x;
+ struct ieee_single *py = (struct ieee_single *)&y;
+
+ /* Check for NaNs to avoid raising spurious exceptions. */
+ if (px->sng_exp == SNG_EXP_INFNAN && px->sng_frac != 0)
+ return (y);
+ if (py->sng_exp == SNG_EXP_INFNAN && py->sng_frac != 0)
+ return (x);
+
+ /* Handle comparisons of signed zeroes. */
+ if (px->sng_sign != py->sng_sign && px->sng_sign == 1)
+ return (y);
+ if (px->sng_sign != py->sng_sign && px->sng_sign == 0)
+ return (x);
+
+ return (x > y ? x : y);
+}
diff --git a/lib/libm/src/s_fmin.c b/lib/libm/src/s_fmin.c
new file mode 100644
index 00000000000..47c5d9a67a9
--- /dev/null
+++ b/lib/libm/src/s_fmin.c
@@ -0,0 +1,55 @@
+/* $OpenBSD: s_fmin.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*-
+ * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+double
+fmin(double x, double y)
+{
+ struct ieee_double *px = (struct ieee_double *)&x;
+ struct ieee_double *py = (struct ieee_double *)&y;
+
+ /* Check for NaNs to avoid raising spurious exceptions. */
+ if (px->dbl_exp == DBL_EXP_INFNAN &&
+ (px->dbl_frach | px->dbl_fracl) != 0)
+ return (y);
+ if (py->dbl_exp == DBL_EXP_INFNAN &&
+ (py->dbl_frach | py->dbl_fracl) != 0)
+ return (x);
+
+ /* Handle comparisons of signed zeroes. */
+ if (px->dbl_sign != py->dbl_sign &&
+ py->dbl_sign == 1)
+ return (y);
+ if (px->dbl_sign != py->dbl_sign &&
+ py->dbl_sign == 0)
+ return (x);
+
+ return (x < y ? x : y);
+}
diff --git a/lib/libm/src/s_fminf.c b/lib/libm/src/s_fminf.c
new file mode 100644
index 00000000000..37de5c63e83
--- /dev/null
+++ b/lib/libm/src/s_fminf.c
@@ -0,0 +1,51 @@
+/* $OpenBSD: s_fminf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */
+/*-
+ * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+float
+fminf(float x, float y)
+{
+ struct ieee_single *px = (struct ieee_single *)&x;
+ struct ieee_single *py = (struct ieee_single *)&y;
+
+ /* Check for NaNs to avoid raising spurious exceptions. */
+ if (px->sng_exp == SNG_EXP_INFNAN && px->sng_frac != 0)
+ return (y);
+ if (py->sng_exp == SNG_EXP_INFNAN && py->sng_frac != 0)
+ return (x);
+
+ /* Handle comparisons of signed zeroes. */
+ if (px->sng_sign != py->sng_sign && py->sng_sign == 1)
+ return (y);
+ if (px->sng_sign != py->sng_sign && py->sng_sign == 0)
+ return (x);
+
+ return (x < y ? x : y);
+}
diff --git a/lib/libm/src/s_lib_version.c b/lib/libm/src/s_lib_version.c
deleted file mode 100644
index c4cfae37adb..00000000000
--- a/lib/libm/src/s_lib_version.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* @(#)s_lib_ver.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: s_lib_version.c,v 1.6 1995/05/10 20:47:44 jtc Exp $";
-#endif
-
-/*
- * MACRO for standards
- */
-
-#include "math.h"
-#include "math_private.h"
-
-/*
- * define and initialize _LIB_VERSION
- */
-#ifdef _POSIX_MODE
-_LIB_VERSION_TYPE _LIB_VERSION = _POSIX_;
-#else
-#ifdef _XOPEN_MODE
-_LIB_VERSION_TYPE _LIB_VERSION = _XOPEN_;
-#else
-#ifdef _SVID3_MODE
-_LIB_VERSION_TYPE _LIB_VERSION = _SVID_;
-#else /* default _IEEE_MODE */
-_LIB_VERSION_TYPE _LIB_VERSION = _IEEE_;
-#endif
-#endif
-#endif
diff --git a/lib/libm/src/s_matherr.c b/lib/libm/src/s_matherr.c
deleted file mode 100644
index 9dfa8c7dd85..00000000000
--- a/lib/libm/src/s_matherr.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* @(#)s_matherr.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: s_matherr.c,v 1.6 1995/05/10 20:47:53 jtc Exp $";
-#endif
-
-#include "math.h"
-#include "math_private.h"
-
-int
-matherr(struct exception *x)
-{
- int n=0;
- if(x->arg1!=x->arg1) return 0;
- return n;
-}
diff --git a/lib/libm/src/s_nan.c b/lib/libm/src/s_nan.c
index f847545722c..3e99cfda129 100644
--- a/lib/libm/src/s_nan.c
+++ b/lib/libm/src/s_nan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s_nan.c,v 1.3 2008/08/08 00:41:17 martynas Exp $ */
+/* $OpenBSD: s_nan.c,v 1.4 2008/09/07 20:36:09 martynas Exp $ */
/*-
* Copyright (c) 2007 David Schultz
* All rights reserved.
@@ -40,7 +40,7 @@
/*
* OpenBSD's ctype doesn't have digittoint, so we define it here.
*/
-int
+static int
_digittoint(int c)
{
if (!isxdigit(c))
diff --git a/lib/libm/src/s_significand.c b/lib/libm/src/s_significand.c
index 1751d59e72b..cf4faa24d04 100644
--- a/lib/libm/src/s_significand.c
+++ b/lib/libm/src/s_significand.c
@@ -26,5 +26,5 @@ static char rcsid[] = "$NetBSD: s_significand.c,v 1.6 1995/05/10 20:48:11 jtc Ex
double
significand(double x)
{
- return __ieee754_scalb(x,(double) -ilogb(x));
+ return scalb(x,(double) -ilogb(x));
}
diff --git a/lib/libm/src/s_significandf.c b/lib/libm/src/s_significandf.c
index 5a7c0965475..085fabc93d2 100644
--- a/lib/libm/src/s_significandf.c
+++ b/lib/libm/src/s_significandf.c
@@ -23,5 +23,5 @@ static char rcsid[] = "$NetBSD: s_significandf.c,v 1.3 1995/05/10 20:48:13 jtc E
float
significandf(float x)
{
- return __ieee754_scalbf(x,(float) -ilogbf(x));
+ return scalbf(x,(float) -ilogbf(x));
}
diff --git a/lib/libm/src/w_acos.c b/lib/libm/src/w_acos.c
deleted file mode 100644
index 142a6f9c076..00000000000
--- a/lib/libm/src/w_acos.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* @(#)w_acos.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_acos.c,v 1.6 1995/05/10 20:48:26 jtc Exp $";
-#endif
-
-/*
- * wrap_acos(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-acos(double x) /* wrapper acos */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_acos(x);
-#else
- double z;
- z = __ieee754_acos(x);
- if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
- if(fabs(x)>1.0) {
- return __kernel_standard(x,x,1); /* acos(|x|>1) */
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_acosf.c b/lib/libm/src/w_acosf.c
deleted file mode 100644
index ee56e6df6e4..00000000000
--- a/lib/libm/src/w_acosf.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* w_acosf.c -- float version of w_acos.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_acosf.c,v 1.3 1995/05/10 20:48:29 jtc Exp $";
-#endif
-
-/*
- * wrap_acosf(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-acosf(float x) /* wrapper acosf */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_acosf(x);
-#else
- float z;
- z = __ieee754_acosf(x);
- if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
- if(fabsf(x)>(float)1.0) {
- /* acosf(|x|>1) */
- return (float)__kernel_standard((double)x,(double)x,101);
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_acosh.c b/lib/libm/src/w_acosh.c
deleted file mode 100644
index 545b77bd352..00000000000
--- a/lib/libm/src/w_acosh.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* @(#)w_acosh.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_acosh.c,v 1.6 1995/05/10 20:48:31 jtc Exp $";
-#endif
-
-/*
- * wrapper acosh(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-acosh(double x) /* wrapper acosh */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_acosh(x);
-#else
- double z;
- z = __ieee754_acosh(x);
- if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
- if(x<1.0) {
- return __kernel_standard(x,x,29); /* acosh(x<1) */
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_acoshf.c b/lib/libm/src/w_acoshf.c
deleted file mode 100644
index 62e48b0f15b..00000000000
--- a/lib/libm/src/w_acoshf.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* w_acoshf.c -- float version of w_acosh.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- *
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_acoshf.c,v 1.3 1995/05/10 20:48:33 jtc Exp $";
-#endif
-
-/*
- * wrapper acoshf(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-acoshf(float x) /* wrapper acoshf */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_acoshf(x);
-#else
- float z;
- z = __ieee754_acoshf(x);
- if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
- if(x<(float)1.0) {
- /* acosh(x<1) */
- return (float)__kernel_standard((double)x,(double)x,129);
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_asin.c b/lib/libm/src/w_asin.c
deleted file mode 100644
index f039e729f16..00000000000
--- a/lib/libm/src/w_asin.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* @(#)w_asin.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_asin.c,v 1.6 1995/05/10 20:48:35 jtc Exp $";
-#endif
-
-/*
- * wrapper asin(x)
- */
-
-
-#include "math.h"
-#include "math_private.h"
-
-double
-asin(double x) /* wrapper asin */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_asin(x);
-#else
- double z;
- z = __ieee754_asin(x);
- if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
- if(fabs(x)>1.0) {
- return __kernel_standard(x,x,2); /* asin(|x|>1) */
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_asinf.c b/lib/libm/src/w_asinf.c
deleted file mode 100644
index 3d2c94d3c6c..00000000000
--- a/lib/libm/src/w_asinf.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* w_asinf.c -- float version of w_asin.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_asinf.c,v 1.3 1995/05/10 20:48:37 jtc Exp $";
-#endif
-
-/*
- * wrapper asinf(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-asinf(float x) /* wrapper asinf */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_asinf(x);
-#else
- float z;
- z = __ieee754_asinf(x);
- if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
- if(fabsf(x)>(float)1.0) {
- /* asinf(|x|>1) */
- return (float)__kernel_standard((double)x,(double)x,102);
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_atan2.c b/lib/libm/src/w_atan2.c
deleted file mode 100644
index 135836af5b2..00000000000
--- a/lib/libm/src/w_atan2.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* @(#)w_atan2.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_atan2.c,v 1.6 1995/05/10 20:48:39 jtc Exp $";
-#endif
-
-/*
- * wrapper atan2(y,x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-atan2(double y, double x) /* wrapper atan2 */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_atan2(y,x);
-#else
- double z;
- z = __ieee754_atan2(y,x);
- if(_LIB_VERSION == _IEEE_||isnan(x)||isnan(y)) return z;
- if(x==0.0&&y==0.0) {
- return __kernel_standard(y,x,3); /* atan2(+-0,+-0) */
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_atan2f.c b/lib/libm/src/w_atan2f.c
deleted file mode 100644
index a1c9763b0ad..00000000000
--- a/lib/libm/src/w_atan2f.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* w_atan2f.c -- float version of w_atan2.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_atan2f.c,v 1.3 1995/05/10 20:48:42 jtc Exp $";
-#endif
-
-/*
- * wrapper atan2f(y,x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-atan2f(float y, float x) /* wrapper atan2f */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_atan2f(y,x);
-#else
- float z;
- z = __ieee754_atan2f(y,x);
- if(_LIB_VERSION == _IEEE_||isnanf(x)||isnanf(y)) return z;
- if(x==(float)0.0&&y==(float)0.0) {
- /* atan2f(+-0,+-0) */
- return (float)__kernel_standard((double)y,(double)x,103);
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_atanh.c b/lib/libm/src/w_atanh.c
deleted file mode 100644
index 29cd574c018..00000000000
--- a/lib/libm/src/w_atanh.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* @(#)w_atanh.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_atanh.c,v 1.6 1995/05/10 20:48:43 jtc Exp $";
-#endif
-
-/*
- * wrapper atanh(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-atanh(double x) /* wrapper atanh */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_atanh(x);
-#else
- double z,y;
- z = __ieee754_atanh(x);
- if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
- y = fabs(x);
- if(y>=1.0) {
- if(y>1.0)
- return __kernel_standard(x,x,30); /* atanh(|x|>1) */
- else
- return __kernel_standard(x,x,31); /* atanh(|x|==1) */
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_atanhf.c b/lib/libm/src/w_atanhf.c
deleted file mode 100644
index f33d64ebe62..00000000000
--- a/lib/libm/src/w_atanhf.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* w_atanhf.c -- float version of w_atanh.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_atanhf.c,v 1.3 1995/05/10 20:48:45 jtc Exp $";
-#endif
-
-/*
- * wrapper atanhf(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-atanhf(float x) /* wrapper atanhf */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_atanhf(x);
-#else
- float z,y;
- z = __ieee754_atanhf(x);
- if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
- y = fabsf(x);
- if(y>=(float)1.0) {
- if(y>(float)1.0)
- /* atanhf(|x|>1) */
- return (float)__kernel_standard((double)x,(double)x,130);
- else
- /* atanhf(|x|==1) */
- return (float)__kernel_standard((double)x,(double)x,131);
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_cabs.c b/lib/libm/src/w_cabs.c
deleted file mode 100644
index d851d339e58..00000000000
--- a/lib/libm/src/w_cabs.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * cabs() wrapper for hypot().
- *
- * Written by J.T. Conklin, <jtc@wimsey.com>
- * Placed into the Public Domain, 1994.
- */
-
-#include <math.h>
-
-struct complex {
- double x;
- double y;
-};
-
-double
-cabs(struct complex z)
-{
- return hypot(z.x, z.y);
-}
diff --git a/lib/libm/src/w_cabsf.c b/lib/libm/src/w_cabsf.c
deleted file mode 100644
index d98d0422f28..00000000000
--- a/lib/libm/src/w_cabsf.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * cabsf() wrapper for hypotf().
- *
- * Written by J.T. Conklin, <jtc@wimsey.com>
- * Placed into the Public Domain, 1994.
- */
-
-#include "math.h"
-#include "math_private.h"
-
-struct complex {
- float x;
- float y;
-};
-
-float
-cabsf(struct complex z)
-{
- return hypotf(z.x, z.y);
-}
diff --git a/lib/libm/src/w_cosh.c b/lib/libm/src/w_cosh.c
deleted file mode 100644
index 4eb375f6ec1..00000000000
--- a/lib/libm/src/w_cosh.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* @(#)w_cosh.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_cosh.c,v 1.6 1995/05/10 20:48:47 jtc Exp $";
-#endif
-
-/*
- * wrapper cosh(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-cosh(double x) /* wrapper cosh */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_cosh(x);
-#else
- double z;
- z = __ieee754_cosh(x);
- if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
- if(fabs(x)>7.10475860073943863426e+02) {
- return __kernel_standard(x,x,5); /* cosh overflow */
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_coshf.c b/lib/libm/src/w_coshf.c
deleted file mode 100644
index df7915d1e72..00000000000
--- a/lib/libm/src/w_coshf.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* w_coshf.c -- float version of w_cosh.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_coshf.c,v 1.3 1995/05/10 20:48:49 jtc Exp $";
-#endif
-
-/*
- * wrapper coshf(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-coshf(float x) /* wrapper coshf */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_coshf(x);
-#else
- float z;
- z = __ieee754_coshf(x);
- if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
- if(fabsf(x)>(float)8.9415985107e+01) {
- /* cosh overflow */
- return (float)__kernel_standard((double)x,(double)x,105);
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_exp.c b/lib/libm/src/w_exp.c
deleted file mode 100644
index 655b438ca96..00000000000
--- a/lib/libm/src/w_exp.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* @(#)w_exp.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_exp.c,v 1.6 1995/05/10 20:48:51 jtc Exp $";
-#endif
-
-/*
- * wrapper exp(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-static const double
-o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
-u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */
-
-double
-exp(double x) /* wrapper exp */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_exp(x);
-#else
- double z;
- z = __ieee754_exp(x);
- if(_LIB_VERSION == _IEEE_) return z;
- if(finite(x)) {
- if(x>o_threshold)
- return __kernel_standard(x,x,6); /* exp overflow */
- else if(x<u_threshold)
- return __kernel_standard(x,x,7); /* exp underflow */
- }
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_expf.c b/lib/libm/src/w_expf.c
deleted file mode 100644
index f11948b4e74..00000000000
--- a/lib/libm/src/w_expf.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/* w_expf.c -- float version of w_exp.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_expf.c,v 1.3 1995/05/10 20:48:53 jtc Exp $";
-#endif
-
-/*
- * wrapper expf(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-static const float
-o_threshold= 8.8721679688e+01, /* 0x42b17180 */
-u_threshold= -1.0397208405e+02; /* 0xc2cff1b5 */
-
-float
-expf(float x) /* wrapper expf */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_expf(x);
-#else
- float z;
- z = __ieee754_expf(x);
- if(_LIB_VERSION == _IEEE_) return z;
- if(finitef(x)) {
- if(x>o_threshold)
- /* exp overflow */
- return (float)__kernel_standard((double)x,(double)x,106);
- else if(x<u_threshold)
- /* exp underflow */
- return (float)__kernel_standard((double)x,(double)x,107);
- }
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_fmod.c b/lib/libm/src/w_fmod.c
deleted file mode 100644
index 1f1504c13d5..00000000000
--- a/lib/libm/src/w_fmod.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* @(#)w_fmod.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_fmod.c,v 1.6 1995/05/10 20:48:55 jtc Exp $";
-#endif
-
-/*
- * wrapper fmod(x,y)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-
-double
-fmod(double x, double y) /* wrapper fmod */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_fmod(x,y);
-#else
- double z;
- z = __ieee754_fmod(x,y);
- if(_LIB_VERSION == _IEEE_ ||isnan(y)||isnan(x)) return z;
- if(y==0.0) {
- return __kernel_standard(x,y,27); /* fmod(x,0) */
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_fmodf.c b/lib/libm/src/w_fmodf.c
deleted file mode 100644
index c0deb804aba..00000000000
--- a/lib/libm/src/w_fmodf.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* w_fmodf.c -- float version of w_fmod.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_fmodf.c,v 1.3 1995/05/10 20:48:57 jtc Exp $";
-#endif
-
-/*
- * wrapper fmodf(x,y)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-fmodf(float x, float y) /* wrapper fmodf */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_fmodf(x,y);
-#else
- float z;
- z = __ieee754_fmodf(x,y);
- if(_LIB_VERSION == _IEEE_ ||isnanf(y)||isnanf(x)) return z;
- if(y==(float)0.0) {
- /* fmodf(x,0) */
- return (float)__kernel_standard((double)x,(double)y,127);
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_gamma.c b/lib/libm/src/w_gamma.c
index baa7c711248..92112add553 100644
--- a/lib/libm/src/w_gamma.c
+++ b/lib/libm/src/w_gamma.c
@@ -28,18 +28,5 @@ extern int signgam;
double
gamma(double x)
{
-#ifdef _IEEE_LIBM
- return __ieee754_lgamma_r(x,&signgam);
-#else
- double y;
- y = __ieee754_lgamma_r(x,&signgam);
- if(_LIB_VERSION == _IEEE_) return y;
- if(!finite(y)&&finite(x)) {
- if(floor(x)==x&&x<=0.0)
- return __kernel_standard(x,x,41); /* gamma pole */
- else
- return __kernel_standard(x,x,40); /* gamma overflow */
- } else
- return y;
-#endif
+ return lgamma_r(x,&signgam);
}
diff --git a/lib/libm/src/w_gamma_r.c b/lib/libm/src/w_gamma_r.c
index 8157923f203..dcefb1f4832 100644
--- a/lib/libm/src/w_gamma_r.c
+++ b/lib/libm/src/w_gamma_r.c
@@ -24,18 +24,5 @@ static char rcsid[] = "$NetBSD: w_gamma_r.c,v 1.7 1995/11/20 22:06:45 jtc Exp $"
double
gamma_r(double x, int *signgamp) /* wrapper lgamma_r */
{
-#ifdef _IEEE_LIBM
- return __ieee754_lgamma_r(x,signgamp);
-#else
- double y;
- y = __ieee754_lgamma_r(x,signgamp);
- if(_LIB_VERSION == _IEEE_) return y;
- if(!finite(y)&&finite(x)) {
- if(floor(x)==x&&x<=0.0)
- return __kernel_standard(x,x,41); /* gamma pole */
- else
- return __kernel_standard(x,x,40); /* gamma overflow */
- } else
- return y;
-#endif
+ return lgamma_r(x,signgamp);
}
diff --git a/lib/libm/src/w_gammaf.c b/lib/libm/src/w_gammaf.c
deleted file mode 100644
index cf668d2bf10..00000000000
--- a/lib/libm/src/w_gammaf.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* w_gammaf.c -- float version of w_gamma.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_gammaf.c,v 1.4 1995/11/20 22:06:48 jtc Exp $";
-#endif
-
-#include "math.h"
-#include "math_private.h"
-
-extern int signgam;
-
-float
-gammaf(float x)
-{
-#ifdef _IEEE_LIBM
- return __ieee754_lgammaf_r(x,&signgam);
-#else
- float y;
- y = __ieee754_lgammaf_r(x,&signgam);
- if(_LIB_VERSION == _IEEE_) return y;
- if(!finitef(y)&&finitef(x)) {
- if(floorf(x)==x&&x<=(float)0.0)
- /* gammaf pole */
- return (float)__kernel_standard((double)x,(double)x,141);
- else
- /* gammaf overflow */
- return (float)__kernel_standard((double)x,(double)x,140);
- } else
- return y;
-#endif
-}
diff --git a/lib/libm/src/w_gammaf_r.c b/lib/libm/src/w_gammaf_r.c
deleted file mode 100644
index 16f4b43b17f..00000000000
--- a/lib/libm/src/w_gammaf_r.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* w_gammaf_r.c -- float version of w_gamma_r.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_gammaf_r.c,v 1.4 1995/11/20 22:06:50 jtc Exp $";
-#endif
-
-/*
- * wrapper float gammaf_r(float x, int *signgamp)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-gammaf_r(float x, int *signgamp) /* wrapper lgammaf_r */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_lgammaf_r(x,signgamp);
-#else
- float y;
- y = __ieee754_lgammaf_r(x,signgamp);
- if(_LIB_VERSION == _IEEE_) return y;
- if(!finitef(y)&&finitef(x)) {
- if(floorf(x)==x&&x<=(float)0.0)
- /* gammaf pole */
- return (float)__kernel_standard((double)x,(double)x,141);
- else
- /* gamma overflow */
- return (float)__kernel_standard((double)x,(double)x,140);
- } else
- return y;
-#endif
-}
diff --git a/lib/libm/src/w_hypot.c b/lib/libm/src/w_hypot.c
deleted file mode 100644
index 57bdf938dbe..00000000000
--- a/lib/libm/src/w_hypot.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* @(#)w_hypot.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_hypot.c,v 1.6 1995/05/10 20:49:07 jtc Exp $";
-#endif
-
-/*
- * wrapper hypot(x,y)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-hypot(double x, double y)/* wrapper hypot */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_hypot(x,y);
-#else
- double z;
- z = __ieee754_hypot(x,y);
- if(_LIB_VERSION == _IEEE_) return z;
- if((!finite(z))&&finite(x)&&finite(y))
- return __kernel_standard(x,y,4); /* hypot overflow */
- else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_hypotf.c b/lib/libm/src/w_hypotf.c
deleted file mode 100644
index d0f83fc7115..00000000000
--- a/lib/libm/src/w_hypotf.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* w_hypotf.c -- float version of w_hypot.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_hypotf.c,v 1.3 1995/05/10 20:49:09 jtc Exp $";
-#endif
-
-/*
- * wrapper hypotf(x,y)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-hypotf(float x, float y) /* wrapper hypotf */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_hypotf(x,y);
-#else
- float z;
- z = __ieee754_hypotf(x,y);
- if(_LIB_VERSION == _IEEE_) return z;
- if((!finitef(z))&&finitef(x)&&finitef(y))
- /* hypot overflow */
- return (float)__kernel_standard((double)x,(double)y,104);
- else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_j0.c b/lib/libm/src/w_j0.c
deleted file mode 100644
index 6e617427920..00000000000
--- a/lib/libm/src/w_j0.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* @(#)w_j0.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_j0.c,v 1.6 1995/05/10 20:49:11 jtc Exp $";
-#endif
-
-/*
- * wrapper j0(double x), y0(double x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-j0(double x) /* wrapper j0 */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_j0(x);
-#else
- double z = __ieee754_j0(x);
- if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
- if(fabs(x)>X_TLOSS) {
- return __kernel_standard(x,x,34); /* j0(|x|>X_TLOSS) */
- } else
- return z;
-#endif
-}
-
-double
-y0(double x) /* wrapper y0 */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_y0(x);
-#else
- double z;
- z = __ieee754_y0(x);
- if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z;
- if(x <= 0.0){
- if(x==0.0)
- /* d= -one/(x-x); */
- return __kernel_standard(x,x,8);
- else
- /* d = zero/(x-x); */
- return __kernel_standard(x,x,9);
- }
- if(x>X_TLOSS) {
- return __kernel_standard(x,x,35); /* y0(x>X_TLOSS) */
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_j0f.c b/lib/libm/src/w_j0f.c
deleted file mode 100644
index 93ec42b366a..00000000000
--- a/lib/libm/src/w_j0f.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* w_j0f.c -- float version of w_j0.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_j0f.c,v 1.3 1995/05/10 20:49:13 jtc Exp $";
-#endif
-
-/*
- * wrapper j0f(float x), y0f(float x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-j0f(float x) /* wrapper j0f */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_j0f(x);
-#else
- float z = __ieee754_j0f(x);
- if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
- if(fabsf(x)>(float)X_TLOSS) {
- /* j0f(|x|>X_TLOSS) */
- return (float)__kernel_standard((double)x,(double)x,134);
- } else
- return z;
-#endif
-}
-
-float
-y0f(float x) /* wrapper y0f */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_y0f(x);
-#else
- float z;
- z = __ieee754_y0f(x);
- if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z;
- if(x <= (float)0.0){
- if(x==(float)0.0)
- /* d= -one/(x-x); */
- return (float)__kernel_standard((double)x,(double)x,108);
- else
- /* d = zero/(x-x); */
- return (float)__kernel_standard((double)x,(double)x,109);
- }
- if(x>(float)X_TLOSS) {
- /* y0(x>X_TLOSS) */
- return (float)__kernel_standard((double)x,(double)x,135);
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_j1.c b/lib/libm/src/w_j1.c
deleted file mode 100644
index 23ca8befaf6..00000000000
--- a/lib/libm/src/w_j1.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* @(#)w_j1.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_j1.c,v 1.6 1995/05/10 20:49:15 jtc Exp $";
-#endif
-
-/*
- * wrapper of j1,y1
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-j1(double x) /* wrapper j1 */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_j1(x);
-#else
- double z;
- z = __ieee754_j1(x);
- if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z;
- if(fabs(x)>X_TLOSS) {
- return __kernel_standard(x,x,36); /* j1(|x|>X_TLOSS) */
- } else
- return z;
-#endif
-}
-
-double
-y1(double x) /* wrapper y1 */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_y1(x);
-#else
- double z;
- z = __ieee754_y1(x);
- if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z;
- if(x <= 0.0){
- if(x==0.0)
- /* d= -one/(x-x); */
- return __kernel_standard(x,x,10);
- else
- /* d = zero/(x-x); */
- return __kernel_standard(x,x,11);
- }
- if(x>X_TLOSS) {
- return __kernel_standard(x,x,37); /* y1(x>X_TLOSS) */
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_j1f.c b/lib/libm/src/w_j1f.c
deleted file mode 100644
index 770c9ceab61..00000000000
--- a/lib/libm/src/w_j1f.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* w_j1f.c -- float version of w_j1.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_j1f.c,v 1.3 1995/05/10 20:49:17 jtc Exp $";
-#endif
-
-/*
- * wrapper of j1f,y1f
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-j1f(float x) /* wrapper j1f */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_j1f(x);
-#else
- float z;
- z = __ieee754_j1f(x);
- if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z;
- if(fabsf(x)>(float)X_TLOSS) {
- /* j1(|x|>X_TLOSS) */
- return (float)__kernel_standard((double)x,(double)x,136);
- } else
- return z;
-#endif
-}
-
-float
-y1f(float x) /* wrapper y1f */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_y1f(x);
-#else
- float z;
- z = __ieee754_y1f(x);
- if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z;
- if(x <= (float)0.0){
- if(x==(float)0.0)
- /* d= -one/(x-x); */
- return (float)__kernel_standard((double)x,(double)x,110);
- else
- /* d = zero/(x-x); */
- return (float)__kernel_standard((double)x,(double)x,111);
- }
- if(x>(float)X_TLOSS) {
- /* y1(x>X_TLOSS) */
- return (float)__kernel_standard((double)x,(double)x,137);
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_jn.c b/lib/libm/src/w_jn.c
deleted file mode 100644
index 2ea879e0bf3..00000000000
--- a/lib/libm/src/w_jn.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* @(#)w_jn.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_jn.c,v 1.6 1995/05/10 20:49:19 jtc Exp $";
-#endif
-
-/*
- * wrapper jn(int n, double x), yn(int n, double x)
- * floating point Bessel's function of the 1st and 2nd kind
- * of order n
- *
- * Special cases:
- * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
- * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
- * Note 2. About jn(n,x), yn(n,x)
- * For n=0, j0(x) is called,
- * for n=1, j1(x) is called,
- * for n<x, forward recursion us used starting
- * from values of j0(x) and j1(x).
- * for n>x, a continued fraction approximation to
- * j(n,x)/j(n-1,x) is evaluated and then backward
- * recursion is used starting from a supposed value
- * for j(n,x). The resulting value of j(0,x) is
- * compared with the actual value to correct the
- * supposed value of j(n,x).
- *
- * yn(n,x) is similar in all respects, except
- * that forward recursion is used for all
- * values of n>1.
- *
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-jn(int n, double x) /* wrapper jn */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_jn(n,x);
-#else
- double z;
- z = __ieee754_jn(n,x);
- if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z;
- if(fabs(x)>X_TLOSS) {
- return __kernel_standard((double)n,x,38); /* jn(|x|>X_TLOSS,n) */
- } else
- return z;
-#endif
-}
-
-double
-yn(int n, double x) /* wrapper yn */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_yn(n,x);
-#else
- double z;
- z = __ieee754_yn(n,x);
- if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z;
- if(x <= 0.0){
- if(x==0.0)
- /* d= -one/(x-x); */
- return __kernel_standard((double)n,x,12);
- else
- /* d = zero/(x-x); */
- return __kernel_standard((double)n,x,13);
- }
- if(x>X_TLOSS) {
- return __kernel_standard((double)n,x,39); /* yn(x>X_TLOSS,n) */
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_jnf.c b/lib/libm/src/w_jnf.c
deleted file mode 100644
index a45f3b878f5..00000000000
--- a/lib/libm/src/w_jnf.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* w_jnf.c -- float version of w_jn.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_jnf.c,v 1.3 1995/05/10 20:49:21 jtc Exp $";
-#endif
-
-#include "math.h"
-#include "math_private.h"
-
-float
-jnf(int n, float x) /* wrapper jnf */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_jnf(n,x);
-#else
- float z;
- z = __ieee754_jnf(n,x);
- if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z;
- if(fabsf(x)>(float)X_TLOSS) {
- /* jn(|x|>X_TLOSS,n) */
- return (float)__kernel_standard((double)n,(double)x,138);
- } else
- return z;
-#endif
-}
-
-float
-ynf(int n, float x) /* wrapper ynf */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_ynf(n,x);
-#else
- float z;
- z = __ieee754_ynf(n,x);
- if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z;
- if(x <= (float)0.0){
- if(x==(float)0.0)
- /* d= -one/(x-x); */
- return (float)__kernel_standard((double)n,(double)x,112);
- else
- /* d = zero/(x-x); */
- return (float)__kernel_standard((double)n,(double)x,113);
- }
- if(x>(float)X_TLOSS) {
- /* yn(x>X_TLOSS,n) */
- return (float)__kernel_standard((double)n,(double)x,139);
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_lgamma.c b/lib/libm/src/w_lgamma.c
deleted file mode 100644
index 055fdb774fa..00000000000
--- a/lib/libm/src/w_lgamma.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* @(#)w_lgamma.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_lgamma.c,v 1.6 1995/05/10 20:49:24 jtc Exp $";
-#endif
-
-/* double lgamma(double x)
- * Return the logarithm of the Gamma function of x.
- *
- * Method: call __ieee754_lgamma_r
- */
-
-#include "math.h"
-#include "math_private.h"
-
-extern int signgam;
-
-double
-lgamma(double x)
-{
-#ifdef _IEEE_LIBM
- return __ieee754_lgamma_r(x,&signgam);
-#else
- double y;
- y = __ieee754_lgamma_r(x,&signgam);
- if(_LIB_VERSION == _IEEE_) return y;
- if(!finite(y)&&finite(x)) {
- if(floor(x)==x&&x<=0.0)
- return __kernel_standard(x,x,15); /* lgamma pole */
- else
- return __kernel_standard(x,x,14); /* lgamma overflow */
- } else
- return y;
-#endif
-}
diff --git a/lib/libm/src/w_lgamma_r.c b/lib/libm/src/w_lgamma_r.c
deleted file mode 100644
index 5e9d69ce239..00000000000
--- a/lib/libm/src/w_lgamma_r.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* @(#)wr_lgamma.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_lgamma_r.c,v 1.6 1995/05/10 20:49:27 jtc Exp $";
-#endif
-
-/*
- * wrapper double lgamma_r(double x, int *signgamp)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-
-double
-lgamma_r(double x, int *signgamp) /* wrapper lgamma_r */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_lgamma_r(x,signgamp);
-#else
- double y;
- y = __ieee754_lgamma_r(x,signgamp);
- if(_LIB_VERSION == _IEEE_) return y;
- if(!finite(y)&&finite(x)) {
- if(floor(x)==x&&x<=0.0)
- return __kernel_standard(x,x,15); /* lgamma pole */
- else
- return __kernel_standard(x,x,14); /* lgamma overflow */
- } else
- return y;
-#endif
-}
diff --git a/lib/libm/src/w_lgammaf.c b/lib/libm/src/w_lgammaf.c
deleted file mode 100644
index 0ec7716761f..00000000000
--- a/lib/libm/src/w_lgammaf.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* w_lgammaf.c -- float version of w_lgamma.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_lgammaf.c,v 1.3 1995/05/10 20:49:30 jtc Exp $";
-#endif
-
-#include "math.h"
-#include "math_private.h"
-
-extern int signgam;
-
-float
-lgammaf(float x)
-{
-#ifdef _IEEE_LIBM
- return __ieee754_lgammaf_r(x,&signgam);
-#else
- float y;
- y = __ieee754_lgammaf_r(x,&signgam);
- if(_LIB_VERSION == _IEEE_) return y;
- if(!finitef(y)&&finitef(x)) {
- if(floorf(x)==x&&x<=(float)0.0)
- /* lgamma pole */
- return (float)__kernel_standard((double)x,(double)x,115);
- else
- /* lgamma overflow */
- return (float)__kernel_standard((double)x,(double)x,114);
- } else
- return y;
-#endif
-}
diff --git a/lib/libm/src/w_lgammaf_r.c b/lib/libm/src/w_lgammaf_r.c
deleted file mode 100644
index 49973d3637d..00000000000
--- a/lib/libm/src/w_lgammaf_r.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* w_lgammaf_r.c -- float version of w_lgamma_r.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_lgammaf_r.c,v 1.3 1995/05/10 20:49:32 jtc Exp $";
-#endif
-
-/*
- * wrapper float lgammaf_r(float x, int *signgamp)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-
-float
-lgammaf_r(float x, int *signgamp) /* wrapper lgammaf_r */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_lgammaf_r(x,signgamp);
-#else
- float y;
- y = __ieee754_lgammaf_r(x,signgamp);
- if(_LIB_VERSION == _IEEE_) return y;
- if(!finitef(y)&&finitef(x)) {
- if(floorf(x)==x&&x<=(float)0.0)
- /* lgamma pole */
- return (float)__kernel_standard((double)x,(double)x,115);
- else
- /* lgamma overflow */
- return (float)__kernel_standard((double)x,(double)x,114);
- } else
- return y;
-#endif
-}
diff --git a/lib/libm/src/w_log.c b/lib/libm/src/w_log.c
deleted file mode 100644
index b4dcdef1f05..00000000000
--- a/lib/libm/src/w_log.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* @(#)w_log.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_log.c,v 1.6 1995/05/10 20:49:33 jtc Exp $";
-#endif
-
-/*
- * wrapper log(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-log(double x) /* wrapper log */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_log(x);
-#else
- double z;
- z = __ieee754_log(x);
- if(_LIB_VERSION == _IEEE_ || isnan(x) || x > 0.0) return z;
- if(x==0.0)
- return __kernel_standard(x,x,16); /* log(0) */
- else
- return __kernel_standard(x,x,17); /* log(x<0) */
-#endif
-}
diff --git a/lib/libm/src/w_log10.c b/lib/libm/src/w_log10.c
deleted file mode 100644
index f0b4e7c1740..00000000000
--- a/lib/libm/src/w_log10.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* @(#)w_log10.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_log10.c,v 1.6 1995/05/10 20:49:35 jtc Exp $";
-#endif
-
-/*
- * wrapper log10(X)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-log10(double x) /* wrapper log10 */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_log10(x);
-#else
- double z;
- z = __ieee754_log10(x);
- if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
- if(x<=0.0) {
- if(x==0.0)
- return __kernel_standard(x,x,18); /* log10(0) */
- else
- return __kernel_standard(x,x,19); /* log10(x<0) */
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_log10f.c b/lib/libm/src/w_log10f.c
deleted file mode 100644
index 4907438d820..00000000000
--- a/lib/libm/src/w_log10f.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* w_log10f.c -- float version of w_log10.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_log10f.c,v 1.3 1995/05/10 20:49:37 jtc Exp $";
-#endif
-
-/*
- * wrapper log10f(X)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-log10f(float x) /* wrapper log10f */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_log10f(x);
-#else
- float z;
- z = __ieee754_log10f(x);
- if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
- if(x<=(float)0.0) {
- if(x==(float)0.0)
- /* log10(0) */
- return (float)__kernel_standard((double)x,(double)x,118);
- else
- /* log10(x<0) */
- return (float)__kernel_standard((double)x,(double)x,119);
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_logf.c b/lib/libm/src/w_logf.c
deleted file mode 100644
index 5db12a6beaa..00000000000
--- a/lib/libm/src/w_logf.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* w_logf.c -- float version of w_log.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_logf.c,v 1.3 1995/05/10 20:49:40 jtc Exp $";
-#endif
-
-/*
- * wrapper logf(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-logf(float x) /* wrapper logf */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_logf(x);
-#else
- float z;
- z = __ieee754_logf(x);
- if(_LIB_VERSION == _IEEE_ || isnanf(x) || x > (float)0.0) return z;
- if(x==(float)0.0)
- /* logf(0) */
- return (float)__kernel_standard((double)x,(double)x,116);
- else
- /* logf(x<0) */
- return (float)__kernel_standard((double)x,(double)x,117);
-#endif
-}
diff --git a/lib/libm/src/w_pow.c b/lib/libm/src/w_pow.c
deleted file mode 100644
index d1bf6374b9c..00000000000
--- a/lib/libm/src/w_pow.c
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-/* @(#)w_pow.c 5.2 93/10/01 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper pow(x,y) return x**y
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-pow(double x, double y) /* wrapper pow */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_pow(x,y);
-#else
- double z;
- z=__ieee754_pow(x,y);
- if(_LIB_VERSION == _IEEE_|| isnan(y)) return z;
- if(isnan(x)) {
- if(y==0.0)
- return __kernel_standard(x,y,42); /* pow(NaN,0.0) */
- else
- return z;
- }
- if(x==0.0){
- if(y==0.0)
- return __kernel_standard(x,y,20); /* pow(0.0,0.0) */
- if(finite(y)&&y<0.0)
- return __kernel_standard(x,y,23); /* pow(0.0,negative) */
- return z;
- }
- if(!finite(z)) {
- if(finite(x)&&finite(y)) {
- if(isnan(z))
- return __kernel_standard(x,y,24); /* pow neg**non-int */
- else
- return __kernel_standard(x,y,21); /* pow overflow */
- }
- }
- if(z==0.0&&finite(x)&&finite(y))
- return __kernel_standard(x,y,22); /* pow underflow */
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_powf.c b/lib/libm/src/w_powf.c
deleted file mode 100644
index 6d4772a3830..00000000000
--- a/lib/libm/src/w_powf.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* w_powf.c -- float version of w_pow.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_powf.c,v 1.3 1995/05/10 20:49:41 jtc Exp $";
-#endif
-
-/*
- * wrapper powf(x,y) return x**y
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-powf(float x, float y) /* wrapper powf */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_powf(x,y);
-#else
- float z;
- z=__ieee754_powf(x,y);
- if(_LIB_VERSION == _IEEE_|| isnanf(y)) return z;
- if(isnanf(x)) {
- if(y==(float)0.0)
- /* powf(NaN,0.0) */
- return (float)__kernel_standard((double)x,(double)y,142);
- else
- return z;
- }
- if(x==(float)0.0){
- if(y==(float)0.0)
- /* powf(0.0,0.0) */
- return (float)__kernel_standard((double)x,(double)y,120);
- if(finitef(y)&&y<(float)0.0)
- /* powf(0.0,negative) */
- return (float)__kernel_standard((double)x,(double)y,123);
- return z;
- }
- if(!finitef(z)) {
- if(finitef(x)&&finitef(y)) {
- if(isnanf(z))
- /* powf neg**non-int */
- return (float)__kernel_standard((double)x,(double)y,124);
- else
- /* powf overflow */
- return (float)__kernel_standard((double)x,(double)y,121);
- }
- }
- if(z==(float)0.0&&finitef(x)&&finitef(y))
- /* powf underflow */
- return (float)__kernel_standard((double)x,(double)y,122);
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_remainder.c b/lib/libm/src/w_remainder.c
deleted file mode 100644
index 50a41e77c4b..00000000000
--- a/lib/libm/src/w_remainder.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* @(#)w_remainder.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_remainder.c,v 1.6 1995/05/10 20:49:44 jtc Exp $";
-#endif
-
-/*
- * wrapper remainder(x,p)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-remainder(double x, double y) /* wrapper remainder */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_remainder(x,y);
-#else
- double z;
- z = __ieee754_remainder(x,y);
- if(_LIB_VERSION == _IEEE_ || isnan(y)) return z;
- if(y==0.0)
- return __kernel_standard(x,y,28); /* remainder(x,0) */
- else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_remainderf.c b/lib/libm/src/w_remainderf.c
deleted file mode 100644
index 0339c546a94..00000000000
--- a/lib/libm/src/w_remainderf.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* w_remainderf.c -- float version of w_remainder.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_remainderf.c,v 1.3 1995/05/10 20:49:46 jtc Exp $";
-#endif
-
-/*
- * wrapper remainderf(x,p)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-remainderf(float x, float y) /* wrapper remainder */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_remainderf(x,y);
-#else
- float z;
- z = __ieee754_remainderf(x,y);
- if(_LIB_VERSION == _IEEE_ || isnanf(y)) return z;
- if(y==(float)0.0)
- /* remainder(x,0) */
- return (float)__kernel_standard((double)x,(double)y,128);
- else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_scalb.c b/lib/libm/src/w_scalb.c
deleted file mode 100644
index d956ab75ee8..00000000000
--- a/lib/libm/src/w_scalb.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/* @(#)w_scalb.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_scalb.c,v 1.6 1995/05/10 20:49:48 jtc Exp $";
-#endif
-
-/*
- * wrapper scalb(double x, double fn) is provide for
- * passing various standard test suite. One
- * should use scalbn() instead.
- */
-
-#include "math.h"
-#include "math_private.h"
-
-#include <errno.h>
-
-double
-#ifdef _SCALB_INT
-scalb(double x, int fn) /* wrapper scalb */
-#else
-scalb(double x, double fn) /* wrapper scalb */
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_scalb(x,fn);
-#else
- double z;
- z = __ieee754_scalb(x,fn);
- if(_LIB_VERSION == _IEEE_) return z;
- if(!(finite(z)||isnan(z))&&finite(x)) {
- return __kernel_standard(x,(double)fn,32); /* scalb overflow */
- }
- if(z==0.0&&z!=x) {
- return __kernel_standard(x,(double)fn,33); /* scalb underflow */
- }
-#ifndef _SCALB_INT
- if(!finite(fn)) errno = ERANGE;
-#endif
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_scalbf.c b/lib/libm/src/w_scalbf.c
deleted file mode 100644
index 9542611f1b6..00000000000
--- a/lib/libm/src/w_scalbf.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* w_scalbf.c -- float version of w_scalb.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_scalbf.c,v 1.3 1995/05/10 20:49:50 jtc Exp $";
-#endif
-
-/*
- * wrapper scalbf(float x, float fn) is provide for
- * passing various standard test suite. One
- * should use scalbn() instead.
- */
-
-#include "math.h"
-#include "math_private.h"
-
-#include <errno.h>
-
-float
-#ifdef _SCALB_INT
-scalbf(float x, int fn) /* wrapper scalbf */
-#else
-scalbf(float x, float fn) /* wrapper scalbf */
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_scalbf(x,fn);
-#else
- float z;
- z = __ieee754_scalbf(x,fn);
- if(_LIB_VERSION == _IEEE_) return z;
- if(!(finitef(z)||isnanf(z))&&finitef(x)) {
- /* scalbf overflow */
- return (float)__kernel_standard((double)x,(double)fn,132);
- }
- if(z==(float)0.0&&z!=x) {
- /* scalbf underflow */
- return (float)__kernel_standard((double)x,(double)fn,133);
- }
-#ifndef _SCALB_INT
- if(!finitef(fn)) errno = ERANGE;
-#endif
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_sinh.c b/lib/libm/src/w_sinh.c
deleted file mode 100644
index c02a0ae0531..00000000000
--- a/lib/libm/src/w_sinh.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* @(#)w_sinh.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_sinh.c,v 1.6 1995/05/10 20:49:51 jtc Exp $";
-#endif
-
-/*
- * wrapper sinh(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-sinh(double x) /* wrapper sinh */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_sinh(x);
-#else
- double z;
- z = __ieee754_sinh(x);
- if(_LIB_VERSION == _IEEE_) return z;
- if(!finite(z)&&finite(x)) {
- return __kernel_standard(x,x,25); /* sinh overflow */
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_sinhf.c b/lib/libm/src/w_sinhf.c
deleted file mode 100644
index 58df8cd515a..00000000000
--- a/lib/libm/src/w_sinhf.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* w_sinhf.c -- float version of w_sinh.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_sinhf.c,v 1.3 1995/05/10 20:49:54 jtc Exp $";
-#endif
-
-/*
- * wrapper sinhf(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-sinhf(float x) /* wrapper sinhf */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_sinhf(x);
-#else
- float z;
- z = __ieee754_sinhf(x);
- if(_LIB_VERSION == _IEEE_) return z;
- if(!finitef(z)&&finitef(x)) {
- /* sinhf overflow */
- return (float)__kernel_standard((double)x,(double)x,125);
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_sqrt.c b/lib/libm/src/w_sqrt.c
deleted file mode 100644
index fec804b282c..00000000000
--- a/lib/libm/src/w_sqrt.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* @(#)w_sqrt.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_sqrt.c,v 1.6 1995/05/10 20:49:55 jtc Exp $";
-#endif
-
-/*
- * wrapper sqrt(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-sqrt(double x) /* wrapper sqrt */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_sqrt(x);
-#else
- double z;
- z = __ieee754_sqrt(x);
- if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
- if(x<0.0) {
- return __kernel_standard(x,x,26); /* sqrt(negative) */
- } else
- return z;
-#endif
-}
diff --git a/lib/libm/src/w_sqrtf.c b/lib/libm/src/w_sqrtf.c
deleted file mode 100644
index fb21a63529c..00000000000
--- a/lib/libm/src/w_sqrtf.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* w_sqrtf.c -- float version of w_sqrt.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_sqrtf.c,v 1.3 1995/05/10 20:49:59 jtc Exp $";
-#endif
-
-/*
- * wrapper sqrtf(x)
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-sqrtf(float x) /* wrapper sqrtf */
-{
-#ifdef _IEEE_LIBM
- return __ieee754_sqrtf(x);
-#else
- float z;
- z = __ieee754_sqrtf(x);
- if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
- if(x<(float)0.0) {
- /* sqrtf(negative) */
- return (float)__kernel_standard((double)x,(double)x,126);
- } else
- return z;
-#endif
-}
diff --git a/regress/lib/libc/Makefile b/regress/lib/libc/Makefile
index 689f87aa03b..dc9beab1e15 100644
--- a/regress/lib/libc/Makefile
+++ b/regress/lib/libc/Makefile
@@ -1,8 +1,8 @@
-# $OpenBSD: Makefile,v 1.26 2007/09/03 14:42:43 millert Exp $
+# $OpenBSD: Makefile,v 1.27 2008/09/07 20:36:10 martynas Exp $
-SUBDIR+= _setjmp alloca atexit basename cxa-atexit db dirname getaddrinfo
-SUBDIR+= getcap getopt_long hsearch longjmp locale malloc
-SUBDIR+= netdb popen regex setjmp setjmp-signal sigreturn sigsetjmp
+SUBDIR+= _setjmp alloca atexit basename cxa-atexit db dirname fpclassify
+SUBDIR+= getaddrinfo getcap getopt_long hsearch longjmp locale malloc
+SUBDIR+= netdb popen printf regex setjmp setjmp-signal sigreturn sigsetjmp
SUBDIR+= sprintf strerror strtod strtonum telldir time vis
.if (${MACHINE_ARCH} != "vax")
diff --git a/regress/lib/libc/fpclassify/Makefile b/regress/lib/libc/fpclassify/Makefile
new file mode 100644
index 00000000000..96916d20e70
--- /dev/null
+++ b/regress/lib/libc/fpclassify/Makefile
@@ -0,0 +1,5 @@
+# $OpenBSD: Makefile,v 1.1 2008/09/07 20:36:10 martynas Exp $
+
+PROG= fpclassify
+
+.include <bsd.regress.mk>
diff --git a/regress/lib/libc/fpclassify/fpclassify.c b/regress/lib/libc/fpclassify/fpclassify.c
new file mode 100644
index 00000000000..174c04d983f
--- /dev/null
+++ b/regress/lib/libc/fpclassify/fpclassify.c
@@ -0,0 +1,76 @@
+/* $OpenBSD: fpclassify.c,v 1.1 2008/09/07 20:36:10 martynas Exp $ */
+/*-
+ * Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
+ * 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 AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/tools/regression/lib/libc/gen/test-fpclassify.c,v 1.3 2003/03/27 05:32:28 das Exp $
+ */
+
+#include <assert.h>
+#include <float.h>
+#include <math.h>
+#include <stdlib.h>
+
+int
+main(void)
+{
+
+ assert(fpclassify((float)0) == FP_ZERO);
+ assert(fpclassify((float)-0.0) == FP_ZERO);
+ assert(fpclassify((float)1) == FP_NORMAL);
+ assert(fpclassify((float)1000) == FP_NORMAL);
+#ifndef __alpha__
+ assert(fpclassify(0x1.2p-150f) == FP_SUBNORMAL);
+#endif /* !__alpha__ */
+ assert(fpclassify(HUGE_VALF) == FP_INFINITE);
+ assert(fpclassify((float)HUGE_VAL) == FP_INFINITE);
+ assert(fpclassify((float)HUGE_VALL) == FP_INFINITE);
+ assert(fpclassify(NAN) == FP_NAN);
+
+ assert(fpclassify((double)0) == FP_ZERO);
+ assert(fpclassify((double)-0) == FP_ZERO);
+ assert(fpclassify((double)1) == FP_NORMAL);
+ assert(fpclassify((double)1000) == FP_NORMAL);
+#ifndef __alpha__
+ assert(fpclassify(0x1.2p-1075) == FP_SUBNORMAL);
+#endif /* !__alpha__ */
+ assert(fpclassify(HUGE_VAL) == FP_INFINITE);
+ assert(fpclassify((double)HUGE_VALF) == FP_INFINITE);
+ assert(fpclassify((double)HUGE_VALL) == FP_INFINITE);
+ assert(fpclassify((double)NAN) == FP_NAN);
+
+ assert(fpclassify((long double)0) == FP_ZERO);
+ assert(fpclassify((long double)-0.0) == FP_ZERO);
+ assert(fpclassify((long double)1) == FP_NORMAL);
+ assert(fpclassify((long double)1000) == FP_NORMAL);
+#if (LDBL_MANT_DIG > DBL_MANT_DIG)
+ assert(fpclassify(0x1.2p-16383L) == FP_SUBNORMAL);
+#endif /* (LDBL_MANT_DIG > DBL_MANT_DIG) */
+ assert(fpclassify(HUGE_VALL) == FP_INFINITE);
+ assert(fpclassify((long double)HUGE_VALF) == FP_INFINITE);
+ assert(fpclassify((long double)HUGE_VAL) == FP_INFINITE);
+ assert(fpclassify((long double)NAN) == FP_NAN);
+
+ return (0);
+}
diff --git a/regress/lib/libc/printf/Makefile b/regress/lib/libc/printf/Makefile
new file mode 100644
index 00000000000..c2e2732d6e1
--- /dev/null
+++ b/regress/lib/libc/printf/Makefile
@@ -0,0 +1,5 @@
+# $OpenBSD: Makefile,v 1.1 2008/09/07 20:36:10 martynas Exp $
+
+PROG= fp
+
+.include <bsd.regress.mk>
diff --git a/regress/lib/libc/printf/fp.c b/regress/lib/libc/printf/fp.c
new file mode 100644
index 00000000000..6ed52fdb494
--- /dev/null
+++ b/regress/lib/libc/printf/fp.c
@@ -0,0 +1,217 @@
+/* $OpenBSD: fp.c,v 1.1 2008/09/07 20:36:10 martynas Exp $ */
+/*-
+ * Copyright (c) 2002, 2005 David Schultz <das@FreeBSD.org>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * Test for printf() floating point formats.
+ */
+
+#include <assert.h>
+#include <err.h>
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define testfmt(result, fmt, ...) \
+ _testfmt((result), __LINE__, #__VA_ARGS__, fmt, __VA_ARGS__)
+void _testfmt(const char *, int, const char *, const char *, ...);
+void smash_stack(void);
+
+int
+main(int argc, char *argv[])
+{
+ /*
+ * Basic tests of decimal output functionality.
+ */
+ testfmt(" 1.000000E+00", "%13E", 1.0);
+ testfmt(" 1.000000", "%13f", 1.0);
+ testfmt(" 1", "%13G", 1.0);
+ testfmt(" 1.000000E+00", "%13LE", 1.0L);
+ testfmt(" 1.000000", "%13Lf", 1.0L);
+ testfmt(" 1", "%13LG", 1.0L);
+
+ testfmt("2.718282", "%.*f", -2, 2.7182818);
+
+ testfmt("1.234568e+06", "%e", 1234567.8);
+ testfmt("1234567.800000", "%f", 1234567.8);
+ testfmt("1.23457E+06", "%G", 1234567.8);
+ testfmt("1.234568e+06", "%Le", 1234567.8L);
+ testfmt("1234567.800000", "%Lf", 1234567.8L);
+ testfmt("1.23457E+06", "%LG", 1234567.8L);
+
+#if (LDBL_MANT_DIG > DBL_MANT_DIG) && !defined(__i386__)
+ testfmt("123456789.864210", "%Lf", 123456789.8642097531L);
+ testfmt("-1.23457E+08", "%LG", -123456789.8642097531L);
+ testfmt("123456789.8642097531", "%.10Lf", 123456789.8642097531L);
+ testfmt(" 3.141592653589793238e-4000", "%L27.18Le",
+ 3.14159265358979323846e-4000L);
+#endif /* (LDBL_MANT_DIG > DBL_MANT_DIG) && !defined(__i386__) */
+
+ /*
+ * Infinities and NaNs
+ */
+#ifdef NAN
+ testfmt("nan", "%e", NAN);
+ testfmt("NAN", "%F", NAN);
+ testfmt("nan", "%g", NAN);
+ testfmt("NAN", "%LE", (long double)NAN);
+ testfmt(" nan", "%05e", NAN);
+#endif /* NAN */
+
+ testfmt("INF", "%E", HUGE_VAL);
+ testfmt("-inf", "%f", -HUGE_VAL);
+ testfmt("+inf", "%+g", HUGE_VAL);
+ testfmt(" inf", "%4.2Le", HUGE_VALL);
+ testfmt("-inf", "%Lf", -HUGE_VALL);
+ testfmt(" inf", "%05e", HUGE_VAL);
+ testfmt(" -inf", "%05e", -HUGE_VAL);
+
+ /*
+ * Padding
+ */
+ testfmt("0.000000e+00", "%e", 0.0);
+ testfmt("0.000000", "%F", (double)0.0);
+ testfmt("0", "%G", 0.0);
+ testfmt(" 0", "%3.0Lg", 0.0L);
+ testfmt(" 0", "%5.0f", 0.001);
+
+ /*
+ * Precision specifiers
+ */
+ testfmt("1.0123e+00", "%.4e", 1.0123456789);
+ testfmt("1.0123", "%.4f", 1.0123456789);
+ testfmt("1.012", "%.4g", 1.0123456789);
+ testfmt("1.2346e-02", "%.4e", 0.0123456789);
+ testfmt("0.0123", "%.4f", 0.0123456789);
+ testfmt("0.01235", "%.4g", 0.0123456789);
+
+ /*
+ * Signed conversions
+ */
+ testfmt("+2.500000e-01", "%+e", 0.25);
+ testfmt("+0.000000", "%+F", 0.0);
+ testfmt("-1", "%+g", -1.0);
+
+ testfmt("-1.000000e+00", "% e", -1.0);
+ testfmt("+1.000000", "% +f", 1.0);
+ testfmt(" 1", "% g", 1.0);
+ testfmt(" 0", "% g", 0.0);
+
+ /*
+ * ``Alternate form''
+ */
+ testfmt("1.250e+00", "%#.3e", 1.25);
+ testfmt("123.000000", "%#f", 123.0);
+ testfmt(" 12345.", "%#7.5g", 12345.0);
+ testfmt(" 1.00000", "%#8g", 1.0);
+ testfmt("0.0", "%#.2g", 0.0);
+
+ /*
+ * Padding and decimal point placement
+ */
+ testfmt("03.2E+00", "%08.1E", 3.25);
+ testfmt("003.25", "%06.2F", 3.25);
+ testfmt("0003.25", "%07.4G", 3.25);
+
+ testfmt("3.14159e-05", "%g", 3.14159e-5);
+ testfmt("0.000314159", "%g", 3.14159e-4);
+ testfmt("3.14159e+06", "%g", 3.14159e6);
+ testfmt("314159", "%g", 3.14159e5);
+ testfmt("314159.", "%#g", 3.14159e5);
+
+ testfmt(" 9.000000e+03", "%13e", 9000.0);
+ testfmt(" 9000.000000", "%12f", 9000.0);
+ testfmt(" 9000", "%5g", 9000.0);
+ testfmt(" 900000.", "%#8g", 900000.0);
+ testfmt(" 9e+06", "%6g", 9000000.0);
+ testfmt(" 9.000000e-04", "%13e", 0.0009);
+ testfmt(" 0.000900", "%9f", 0.0009);
+ testfmt(" 0.0009", "%7g", 0.0009);
+ testfmt(" 9e-05", "%6g", 0.00009);
+ testfmt(" 9.00000e-05", "%#12g", 0.00009);
+ testfmt(" 9.e-05", "%#7.1g", 0.00009);
+
+ testfmt(" 0.0", "%4.1f", 0.0);
+ testfmt("90.0", "%4.1f", 90.0);
+ testfmt(" 100", "%4.0f", 100.0);
+ testfmt("9.0e+01", "%4.1e", 90.0);
+ testfmt("1e+02", "%4.0e", 100.0);
+
+ /*
+ * Hexadecimal floating point (%a, %A) tests. Some of these
+ * are only valid if the implementation converts to hex digits
+ * on nibble boundaries.
+ */
+ testfmt("0x0p+0", "%a", 0x0.0p0);
+ testfmt("0X0.P+0", "%#LA", 0x0.0p0L);
+#ifdef NAN
+ testfmt("inf", "%La", (long double)INFINITY);
+ testfmt("+INF", "%+A", INFINITY);
+ testfmt("nan", "%La", (long double)NAN);
+ testfmt("NAN", "%A", NAN);
+#endif /* NAN */
+
+ testfmt(" 0x1.23p+0", "%10a", 0x1.23p0);
+ testfmt(" 0x1.23p-500", "%12a", 0x1.23p-500);
+ testfmt(" 0x1.2p+40", "%10.1a", 0x1.23p40);
+ testfmt(" 0X1.230000000000000000000000P-4", "%32.24A", 0x1.23p-4);
+ testfmt("0x1p-1074", "%a", 0x1p-1074);
+ testfmt("0x1.2345p-1024", "%a", 0x1.2345p-1024);
+
+ return (0);
+}
+
+void
+smash_stack(void)
+{
+ static uint32_t junk = 0xdeadbeef;
+ uint32_t buf[512];
+ int i;
+
+ for (i = 0; i < sizeof(buf) / sizeof(buf[0]); i++)
+ buf[i] = junk;
+}
+
+void
+_testfmt(const char *result, int line, const char *argstr, const char *fmt,...)
+{
+ char s[100];
+ va_list ap;
+
+ va_start(ap, fmt);
+ smash_stack();
+ vsnprintf(s, sizeof(s), fmt, ap);
+ if (strcmp(result, s) != 0) {
+ fprintf(stderr,
+ "%d: printf(\"%s\", %s) ==> [%s], expected [%s]\n",
+ line, fmt, argstr, s, result);
+ abort();
+ }
+}
diff --git a/regress/lib/libm/tgamma/tgamma.c b/regress/lib/libm/tgamma/tgamma.c
index a3b1b6964a6..491fe6efcbb 100644
--- a/regress/lib/libm/tgamma/tgamma.c
+++ b/regress/lib/libm/tgamma/tgamma.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tgamma.c,v 1.1 2008/06/11 15:07:34 martynas Exp $ */
+/* $OpenBSD: tgamma.c,v 1.2 2008/09/07 20:36:10 martynas Exp $ */
/* Written by Martynas Venckus, 2008, Public domain. */
@@ -83,8 +83,12 @@ main(void)
if (!_isinf(x))
errx(1, "tgamma(171.64) = %f", x);
- x = tgamma(0);
- if (!_isinf(x))
+ x = tgamma(0.0);
+ if (!_isinf(x) || x < 0)
+ errx(1, "tgamma(0) = %f", x);
+
+ x = tgamma(-0.0);
+ if (!_isinf(x) || x > 0)
errx(1, "tgamma(0) = %f", x);
x = tgamma(-HUGE_VAL);
@@ -95,8 +99,8 @@ main(void)
if (!_isinf(x))
errx(1, "tgamma(HUGE_VAL) = %f", x);
-#if _IEEE /* VAX doesn't have NaN */
- x = tgamma(0.0/0.0);
+#ifdef NAN
+ x = tgamma(NAN);
if (!_isnan(x))
errx(1, "tgamma(NaN) = %f", x);
#endif
diff --git a/sys/arch/alpha/include/ieee.h b/sys/arch/alpha/include/ieee.h
index e5ed1da001d..0fbbe82482f 100644
--- a/sys/arch/alpha/include/ieee.h
+++ b/sys/arch/alpha/include/ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee.h,v 1.4 2003/06/02 23:27:43 millert Exp $ */
+/* $OpenBSD: ieee.h,v 1.5 2008/09/07 20:36:06 martynas Exp $ */
/* $NetBSD: ieee.h,v 1.1 1995/02/13 23:07:40 cgd Exp $ */
/*
@@ -81,6 +81,8 @@
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
+#define DBL_FRACHBITS 20
+#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
struct ieee_single {
diff --git a/sys/arch/amd64/include/ieee.h b/sys/arch/amd64/include/ieee.h
index 5a34355d223..74856b20ebf 100644
--- a/sys/arch/amd64/include/ieee.h
+++ b/sys/arch/amd64/include/ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee.h,v 1.1 2004/01/28 01:39:39 mickey Exp $ */
+/* $OpenBSD: ieee.h,v 1.2 2008/09/07 20:36:06 martynas Exp $ */
/* $NetBSD: ieee.h,v 1.1 1996/09/30 16:34:25 ws Exp $ */
/*
@@ -79,10 +79,19 @@
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
+#define DBL_FRACHBITS 20
+#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
#define EXT_EXPBITS 15
-#define EXT_FRACBITS 112
+#define EXT_FRACHBITS 32
+#define EXT_FRACLBITS 32
+#define EXT_FRACBITS 64
+
+#define EXT_TO_ARRAY32(p, a) do { \
+ (a)[0] = (uint32_t)(p)->ext_fracl; \
+ (a)[1] = (uint32_t)(p)->ext_frach; \
+} while(0)
struct ieee_single {
u_int sng_frac:23;
@@ -99,11 +108,11 @@ struct ieee_double {
struct ieee_ext {
u_int ext_fracl;
- u_int ext_fraclm;
- u_int ext_frachm;
- u_int ext_frach:16;
+ u_int ext_frach;
u_int ext_exp:15;
u_int ext_sign:1;
+ u_int ext_padl:16;
+ u_int ext_padh;
};
/*
diff --git a/sys/arch/arm/include/ieee.h b/sys/arch/arm/include/ieee.h
index fb3620bde41..c0ef9ca2fbd 100644
--- a/sys/arch/arm/include/ieee.h
+++ b/sys/arch/arm/include/ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee.h,v 1.2 2008/07/24 17:36:52 deraadt Exp $ */
+/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:06 martynas Exp $ */
/* $NetBSD: ieee.h,v 1.2 2001/02/21 17:43:50 bjh21 Exp $ */
/*
@@ -92,13 +92,21 @@
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
+#define DBL_FRACHBITS 20
+#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
#ifndef __VFP_FP__
#define E80_EXPBITS 15
+#define E80_FRACHBITS 31
+#define E80_FRACLBITS 32
#define E80_FRACBITS 64
#define EXT_EXPBITS 15
+#define EXT_FRACHBITS 16
+#define EXT_FRACHMBITS 32
+#define EXT_FRACLMBITS 32
+#define EXT_FRACLBITS 32
#define EXT_FRACBITS 112
#endif
diff --git a/sys/arch/hppa/include/ieee.h b/sys/arch/hppa/include/ieee.h
index d908f10c698..d9d263abe37 100644
--- a/sys/arch/hppa/include/ieee.h
+++ b/sys/arch/hppa/include/ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee.h,v 1.2 2003/06/02 23:27:46 millert Exp $ */
+/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:06 martynas Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -78,6 +78,8 @@
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
+#define DBL_FRACHBITS 20
+#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
#ifdef notyet
@@ -85,9 +87,6 @@
#define E80_FRACBITS 64
#endif
-#define EXT_EXPBITS 15
-#define EXT_FRACBITS 112
-
struct ieee_single {
u_int sng_sign:1;
u_int sng_exp:8;
@@ -101,15 +100,6 @@ struct ieee_double {
u_int dbl_fracl;
};
-struct ieee_ext {
- u_int ext_sign:1;
- u_int ext_exp:15;
- u_int ext_frach:16;
- u_int ext_frachm;
- u_int ext_fraclm;
- u_int ext_fracl;
-};
-
/*
* Floats whose exponent is in [1..INFNAN) (of whatever type) are
* `normal'. Floats whose exponent is INFNAN are either Inf or NaN.
@@ -121,12 +111,10 @@ struct ieee_ext {
*/
#define SNG_EXP_INFNAN 255
#define DBL_EXP_INFNAN 2047
-#define EXT_EXP_INFNAN 32767
#if 0
#define SNG_QUIETNAN (1 << 22)
#define DBL_QUIETNAN (1 << 19)
-#define EXT_QUIETNAN (1 << 15)
#endif
/*
@@ -134,4 +122,3 @@ struct ieee_ext {
*/
#define SNG_EXP_BIAS 127
#define DBL_EXP_BIAS 1023
-#define EXT_EXP_BIAS 16383
diff --git a/sys/arch/hppa64/include/ieee.h b/sys/arch/hppa64/include/ieee.h
index dfd8044fd80..f61c962b11a 100644
--- a/sys/arch/hppa64/include/ieee.h
+++ b/sys/arch/hppa64/include/ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+/* $OpenBSD: ieee.h,v 1.2 2008/09/07 20:36:06 martynas Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -78,6 +78,8 @@
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
+#define DBL_FRACHBITS 20
+#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
#ifdef notyet
@@ -86,8 +88,21 @@
#endif
#define EXT_EXPBITS 15
+#define EXT_FRACHBITS 16
+#define EXT_FRACHMBITS 32
+#define EXT_FRACLMBITS 32
+#define EXT_FRACLBITS 32
#define EXT_FRACBITS 112
+#define EXT_IMPLICIT_NBIT
+
+#define EXT_TO_ARRAY32(p, a) do { \
+ (a)[0] = (uint32_t)(p)->ext_fracl; \
+ (a)[1] = (uint32_t)(p)->ext_fraclm; \
+ (a)[2] = (uint32_t)(p)->ext_frachm; \
+ (a)[3] = (uint32_t)(p)->ext_frach; \
+} while(0)
+
struct ieee_single {
u_int sng_sign:1;
u_int sng_exp:8;
diff --git a/sys/arch/i386/include/ieee.h b/sys/arch/i386/include/ieee.h
index 55b3703277c..865fcb9eec6 100644
--- a/sys/arch/i386/include/ieee.h
+++ b/sys/arch/i386/include/ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee.h,v 1.2 2003/06/02 23:27:47 millert Exp $ */
+/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:06 martynas Exp $ */
/* $NetBSD: ieee.h,v 1.1 1996/09/30 16:34:25 ws Exp $ */
/*
@@ -79,10 +79,19 @@
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
+#define DBL_FRACHBITS 20
+#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
#define EXT_EXPBITS 15
-#define EXT_FRACBITS 112
+#define EXT_FRACHBITS 32
+#define EXT_FRACLBITS 32
+#define EXT_FRACBITS 64
+
+#define EXT_TO_ARRAY32(p, a) do { \
+ (a)[0] = (uint32_t)(p)->ext_fracl; \
+ (a)[1] = (uint32_t)(p)->ext_frach; \
+} while(0)
struct ieee_single {
u_int sng_frac:23;
@@ -99,11 +108,10 @@ struct ieee_double {
struct ieee_ext {
u_int ext_fracl;
- u_int ext_fraclm;
- u_int ext_frachm;
- u_int ext_frach:16;
+ u_int ext_frach;
u_int ext_exp:15;
u_int ext_sign:1;
+ u_int ext_pad:16;
};
/*
diff --git a/sys/arch/m68k/include/float.h b/sys/arch/m68k/include/float.h
index cf252b96b1b..954e5733512 100644
--- a/sys/arch/m68k/include/float.h
+++ b/sys/arch/m68k/include/float.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: float.h,v 1.6 2008/07/21 20:50:54 martynas Exp $ */
+/* $OpenBSD: float.h,v 1.7 2008/09/07 20:36:06 martynas Exp $ */
/* $NetBSD: float.h,v 1.10 1995/06/20 20:45:41 jtc Exp $ */
/*
@@ -48,9 +48,9 @@ __END_DECLS
#define FLT_MANT_DIG 24 /* p */
#define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */
#define FLT_DIG 6 /* floor((p-1)*log10(b))+(b == 10) */
-#define FLT_MIN_EXP -125 /* emin */
+#define FLT_MIN_EXP (-125) /* emin */
#define FLT_MIN 1.17549435E-38F /* b**(emin-1) */
-#define FLT_MIN_10_EXP -37 /* ceil(log10(b**(emin-1))) */
+#define FLT_MIN_10_EXP (-37) /* ceil(log10(b**(emin-1))) */
#define FLT_MAX_EXP 128 /* emax */
#define FLT_MAX 3.40282347E+38F /* (1-b**(-p))*b**emax */
#define FLT_MAX_10_EXP 38 /* floor(log10((1-b**(-p))*b**emax)) */
@@ -58,21 +58,21 @@ __END_DECLS
#define DBL_MANT_DIG 53
#define DBL_EPSILON 2.2204460492503131E-16
#define DBL_DIG 15
-#define DBL_MIN_EXP -1021
+#define DBL_MIN_EXP (-1021)
#define DBL_MIN 2.2250738585072014E-308
-#define DBL_MIN_10_EXP -307
+#define DBL_MIN_10_EXP (-307)
#define DBL_MAX_EXP 1024
#define DBL_MAX 1.7976931348623157E+308
#define DBL_MAX_10_EXP 308
-#define LDBL_MANT_DIG DBL_MANT_DIG
-#define LDBL_EPSILON DBL_EPSILON
-#define LDBL_DIG DBL_DIG
-#define LDBL_MIN_EXP DBL_MIN_EXP
-#define LDBL_MIN DBL_MIN
-#define LDBL_MIN_10_EXP DBL_MIN_10_EXP
-#define LDBL_MAX_EXP DBL_MAX_EXP
-#define LDBL_MAX DBL_MAX
-#define LDBL_MAX_10_EXP DBL_MAX_10_EXP
+#define LDBL_MANT_DIG 64
+#define LDBL_EPSILON 1.08420217248550443401e-19L
+#define LDBL_DIG 18
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MIN 3.36210314311209350626e-4932L
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_EXP 16384
+#define LDBL_MAX 1.18973149535723176502e+4932L
+#define LDBL_MAX_10_EXP 4932
#endif /* !_M68K_FLOAT_H_ */
diff --git a/sys/arch/m68k/include/ieee.h b/sys/arch/m68k/include/ieee.h
index 05f903c2286..3ed9aad9885 100644
--- a/sys/arch/m68k/include/ieee.h
+++ b/sys/arch/m68k/include/ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee.h,v 1.3 2006/01/16 22:05:59 miod Exp $ */
+/* $OpenBSD: ieee.h,v 1.4 2008/09/07 20:36:06 martynas Exp $ */
/* $NetBSD: ieee.h,v 1.2 1994/11/20 20:53:10 deraadt Exp $ */
/*
@@ -79,11 +79,20 @@
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
+#define DBL_FRACHBITS 20
+#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
#define EXT_EXPBITS 15
+#define EXT_FRACHBITS 32
+#define EXT_FRACLBITS 32
#define EXT_FRACBITS 64
+#define EXT_TO_ARRAY32(p, a) do { \
+ (a)[0] = (uint32_t)(p)->ext_fracl; \
+ (a)[1] = (uint32_t)(p)->ext_frach; \
+} while(0)
+
struct ieee_single {
u_int sng_sign:1;
u_int sng_exp:8;
@@ -101,8 +110,7 @@ struct ieee_ext {
u_int ext_sign:1;
u_int ext_exp:15;
u_int ext_zero:16;
- u_int ext_int:1;
- u_int ext_frach:31;
+ u_int ext_frach;
u_int ext_fracl;
};
diff --git a/sys/arch/m88k/include/float.h b/sys/arch/m88k/include/float.h
index e6c0d7f3240..8e46928dafb 100644
--- a/sys/arch/m88k/include/float.h
+++ b/sys/arch/m88k/include/float.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: float.h,v 1.2 2008/07/21 20:50:54 martynas Exp $ */
+/* $OpenBSD: float.h,v 1.3 2008/09/07 20:36:06 martynas Exp $ */
/*
* Copyright (c) 1989 Regents of the University of California.
@@ -47,9 +47,9 @@ __END_DECLS
#define FLT_MANT_DIG 24 /* p */
#define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */
#define FLT_DIG 6 /* floor((p-1)*log10(b))+(b == 10) */
-#define FLT_MIN_EXP -125 /* emin */
+#define FLT_MIN_EXP (-125) /* emin */
#define FLT_MIN 1.17549435E-38F /* b**(emin-1) */
-#define FLT_MIN_10_EXP -37 /* ceil(log10(b**(emin-1))) */
+#define FLT_MIN_10_EXP (-37) /* ceil(log10(b**(emin-1))) */
#define FLT_MAX_EXP 128 /* emax */
#define FLT_MAX 3.40282347E+38F /* (1-b**(-p))*b**emax */
#define FLT_MAX_10_EXP 38 /* floor(log10((1-b**(-p))*b**emax)) */
@@ -57,21 +57,21 @@ __END_DECLS
#define DBL_MANT_DIG 53
#define DBL_EPSILON 2.2204460492503131E-16
#define DBL_DIG 15
-#define DBL_MIN_EXP -1021
+#define DBL_MIN_EXP (-1021)
#define DBL_MIN 2.2250738585072014E-308
-#define DBL_MIN_10_EXP -307
+#define DBL_MIN_10_EXP (-307)
#define DBL_MAX_EXP 1024
#define DBL_MAX 1.7976931348623157E+308
#define DBL_MAX_10_EXP 308
-#define LDBL_MANT_DIG DBL_MANT_DIG
-#define LDBL_EPSILON DBL_EPSILON
-#define LDBL_DIG DBL_DIG
-#define LDBL_MIN_EXP DBL_MIN_EXP
-#define LDBL_MIN DBL_MIN
-#define LDBL_MIN_10_EXP DBL_MIN_10_EXP
-#define LDBL_MAX_EXP DBL_MAX_EXP
-#define LDBL_MAX DBL_MAX
-#define LDBL_MAX_10_EXP DBL_MAX_10_EXP
+#define LDBL_MANT_DIG 64
+#define LDBL_EPSILON 1.08420217248550443401e-19L
+#define LDBL_DIG 18
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MIN 3.36210314311209350626e-4932L
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_EXP 16384
+#define LDBL_MAX 1.18973149535723176502e+4932L
+#define LDBL_MAX_10_EXP 4932
#endif /* __M88K_FLOAT_H__ */
diff --git a/sys/arch/m88k/include/ieee.h b/sys/arch/m88k/include/ieee.h
index a849c33906e..d68677c46aa 100644
--- a/sys/arch/m88k/include/ieee.h
+++ b/sys/arch/m88k/include/ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee.h,v 1.2 2006/05/04 19:28:43 miod Exp $ */
+/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:06 martynas Exp $ */
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@@ -77,11 +77,20 @@
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
+#define DBL_FRACHBITS 20
+#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
#define EXT_EXPBITS 15
+#define EXT_FRACHBITS 32
+#define EXT_FRACLBITS 32
#define EXT_FRACBITS 64
+#define EXT_TO_ARRAY32(p, a) do { \
+ (a)[0] = (uint32_t)(p)->ext_fracl; \
+ (a)[1] = (uint32_t)(p)->ext_frach; \
+} while(0)
+
struct ieee_single {
u_int sng_sign:1;
u_int sng_exp:8;
@@ -98,8 +107,7 @@ struct ieee_double {
struct ieee_ext {
u_int ext_sign:1;
u_int ext_exp:15;
- u_int ext_lead:1;
- u_int ext_frach:31;
+ u_int ext_frach;
u_int ext_fracl;
};
diff --git a/sys/arch/mips64/include/float.h b/sys/arch/mips64/include/float.h
index f3fe1b0ed1e..dcb397c28e9 100644
--- a/sys/arch/mips64/include/float.h
+++ b/sys/arch/mips64/include/float.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: float.h,v 1.4 2008/07/21 20:50:54 martynas Exp $ */
+/* $OpenBSD: float.h,v 1.5 2008/09/07 20:36:06 martynas Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -47,9 +47,9 @@ __END_DECLS
#define FLT_MANT_DIG 24 /* p */
#define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */
#define FLT_DIG 6 /* floor((p-1)*log10(b))+(b == 10) */
-#define FLT_MIN_EXP -125 /* emin */
+#define FLT_MIN_EXP (-125) /* emin */
#define FLT_MIN 1.17549435E-38F /* b**(emin-1) */
-#define FLT_MIN_10_EXP -37 /* ceil(log10(b**(emin-1))) */
+#define FLT_MIN_10_EXP (-37) /* ceil(log10(b**(emin-1))) */
#define FLT_MAX_EXP 128 /* emax */
#define FLT_MAX 3.40282347E+38F /* (1-b**(-p))*b**emax */
#define FLT_MAX_10_EXP 38 /* floor(log10((1-b**(-p))*b**emax)) */
@@ -57,21 +57,21 @@ __END_DECLS
#define DBL_MANT_DIG 53
#define DBL_EPSILON 2.2204460492503131E-16
#define DBL_DIG 15
-#define DBL_MIN_EXP -1021
+#define DBL_MIN_EXP (-1021)
#define DBL_MIN 2.225073858507201E-308
-#define DBL_MIN_10_EXP -307
+#define DBL_MIN_10_EXP (-307)
#define DBL_MAX_EXP 1024
#define DBL_MAX 1.797693134862316E+308
#define DBL_MAX_10_EXP 308
-#define LDBL_MANT_DIG DBL_MANT_DIG
-#define LDBL_EPSILON DBL_EPSILON
-#define LDBL_DIG DBL_DIG
-#define LDBL_MIN_EXP DBL_MIN_EXP
-#define LDBL_MIN DBL_MIN
-#define LDBL_MIN_10_EXP DBL_MIN_10_EXP
-#define LDBL_MAX_EXP DBL_MAX_EXP
-#define LDBL_MAX DBL_MAX
-#define LDBL_MAX_10_EXP DBL_MAX_10_EXP
+#define LDBL_MANT_DIG 113
+#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L
+#define LDBL_DIG 33
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_EXP 16384
+#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L
+#define LDBL_MAX_10_EXP 4932
#endif /* !_MIPS_FLOAT_H_ */
diff --git a/sys/arch/mips64/include/ieee.h b/sys/arch/mips64/include/ieee.h
index 28b7d8b21d0..a683ec5bc45 100644
--- a/sys/arch/mips64/include/ieee.h
+++ b/sys/arch/mips64/include/ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee.h,v 1.2 2005/08/07 07:29:44 miod Exp $ */
+/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:07 martynas Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -78,11 +78,26 @@
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
+#define DBL_FRACHBITS 20
+#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
#define EXT_EXPBITS 15
+#define EXT_FRACHBITS 16
+#define EXT_FRACHMBITS 32
+#define EXT_FRACLMBITS 32
+#define EXT_FRACLBITS 32
#define EXT_FRACBITS 112
+#define EXT_IMPLICIT_NBIT
+
+#define EXT_TO_ARRAY32(p, a) do { \
+ (a)[0] = (uint32_t)(p)->ext_fracl; \
+ (a)[1] = (uint32_t)(p)->ext_fraclm; \
+ (a)[2] = (uint32_t)(p)->ext_frachm; \
+ (a)[3] = (uint32_t)(p)->ext_frach; \
+} while(0)
+
struct ieee_single {
u_int sng_sign:1;
u_int sng_exp:8;
diff --git a/sys/arch/powerpc/include/ieee.h b/sys/arch/powerpc/include/ieee.h
index ffa6bf97811..de0b4f76b05 100644
--- a/sys/arch/powerpc/include/ieee.h
+++ b/sys/arch/powerpc/include/ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee.h,v 1.4 2003/06/02 23:27:53 millert Exp $ */
+/* $OpenBSD: ieee.h,v 1.5 2008/09/07 20:36:07 martynas Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -78,11 +78,10 @@
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
+#define DBL_FRACHBITS 20
+#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
-#define EXT_EXPBITS 15
-#define EXT_FRACBITS 112
-
struct ieee_single {
u_int sng_sign:1;
u_int sng_exp:8;
@@ -96,15 +95,6 @@ struct ieee_double {
u_int dbl_fracl;
};
-struct ieee_ext {
- u_int ext_sign:1;
- u_int ext_exp:15;
- u_int ext_frach:16;
- u_int ext_frachm;
- u_int ext_fraclm;
- u_int ext_fracl;
-};
-
/*
* Floats whose exponent is in [1..INFNAN) (of whatever type) are
* `normal'. Floats whose exponent is INFNAN are either Inf or NaN.
@@ -116,12 +106,10 @@ struct ieee_ext {
*/
#define SNG_EXP_INFNAN 255
#define DBL_EXP_INFNAN 2047
-#define EXT_EXP_INFNAN 32767
#if 0
#define SNG_QUIETNAN (1 << 22)
#define DBL_QUIETNAN (1 << 19)
-#define EXT_QUIETNAN (1 << 15)
#endif
/*
@@ -129,4 +117,3 @@ struct ieee_ext {
*/
#define SNG_EXP_BIAS 127
#define DBL_EXP_BIAS 1023
-#define EXT_EXP_BIAS 16383
diff --git a/sys/arch/sh/include/ieee.h b/sys/arch/sh/include/ieee.h
index 7646f85edfc..5de8eec3cf8 100644
--- a/sys/arch/sh/include/ieee.h
+++ b/sys/arch/sh/include/ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee.h,v 1.2 2006/11/10 20:29:36 otto Exp $ */
+/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:07 martynas Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -78,11 +78,10 @@
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
+#define DBL_FRACHBITS 20
+#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
-#define EXT_EXPBITS 15
-#define EXT_FRACBITS 112
-
struct ieee_single {
u_int sng_frac:23;
u_int sng_exp:8;
@@ -96,15 +95,6 @@ struct ieee_double {
u_int dbl_sign:1;
};
-struct ieee_ext {
- u_int ext_sign:1;
- u_int ext_exp:15;
- u_int ext_frach:16;
- u_int ext_frachm;
- u_int ext_fraclm;
- u_int ext_fracl;
-};
-
/*
* Floats whose exponent is in [1..INFNAN) (of whatever type) are
* `normal'. Floats whose exponent is INFNAN are either Inf or NaN.
@@ -116,12 +106,10 @@ struct ieee_ext {
*/
#define SNG_EXP_INFNAN 255
#define DBL_EXP_INFNAN 2047
-#define EXT_EXP_INFNAN 32767
#if 0
#define SNG_QUIETNAN (1 << 22)
#define DBL_QUIETNAN (1 << 19)
-#define EXT_QUIETNAN (1 << 15)
#endif
/*
@@ -129,4 +117,3 @@ struct ieee_ext {
*/
#define SNG_EXP_BIAS 127
#define DBL_EXP_BIAS 1023
-#define EXT_EXP_BIAS 16383
diff --git a/sys/arch/sparc/include/ieee.h b/sys/arch/sparc/include/ieee.h
index a66c9cc6f8c..31010a01238 100644
--- a/sys/arch/sparc/include/ieee.h
+++ b/sys/arch/sparc/include/ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee.h,v 1.3 2003/06/02 23:27:54 millert Exp $ */
+/* $OpenBSD: ieee.h,v 1.4 2008/09/07 20:36:07 martynas Exp $ */
/* $NetBSD: ieee.h,v 1.2 1994/11/20 20:53:10 deraadt Exp $ */
/*
@@ -79,6 +79,8 @@
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
+#define DBL_FRACHBITS 20
+#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
#ifdef notyet
@@ -87,8 +89,21 @@
#endif
#define EXT_EXPBITS 15
+#define EXT_FRACHBITS 16
+#define EXT_FRACHMBITS 32
+#define EXT_FRACLMBITS 32
+#define EXT_FRACLBITS 32
#define EXT_FRACBITS 112
+#define EXT_IMPLICIT_NBIT
+
+#define EXT_TO_ARRAY32(p, a) do { \
+ (a)[0] = (uint32_t)(p)->ext_fracl; \
+ (a)[1] = (uint32_t)(p)->ext_fraclm; \
+ (a)[2] = (uint32_t)(p)->ext_frachm; \
+ (a)[3] = (uint32_t)(p)->ext_frach; \
+} while(0)
+
struct ieee_single {
u_int sng_sign:1;
u_int sng_exp:8;
diff --git a/sys/arch/sparc64/include/ieee.h b/sys/arch/sparc64/include/ieee.h
index 8b60c991853..5c4b39e0d7e 100644
--- a/sys/arch/sparc64/include/ieee.h
+++ b/sys/arch/sparc64/include/ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee.h,v 1.2 2003/06/02 23:27:56 millert Exp $ */
+/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:07 martynas Exp $ */
/* $NetBSD: ieee.h,v 1.1.1.1 1998/06/20 04:58:51 eeh Exp $ */
/*
@@ -79,6 +79,8 @@
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
+#define DBL_FRACHBITS 20
+#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
#ifdef notyet
@@ -87,8 +89,21 @@
#endif
#define EXT_EXPBITS 15
+#define EXT_FRACHBITS 16
+#define EXT_FRACHMBITS 32
+#define EXT_FRACLMBITS 32
+#define EXT_FRACLBITS 32
#define EXT_FRACBITS 112
+#define EXT_IMPLICIT_NBIT
+
+#define EXT_TO_ARRAY32(p, a) do { \
+ (a)[0] = (uint32_t)(p)->ext_fracl; \
+ (a)[1] = (uint32_t)(p)->ext_fraclm; \
+ (a)[2] = (uint32_t)(p)->ext_frachm; \
+ (a)[3] = (uint32_t)(p)->ext_frach; \
+} while(0)
+
struct ieee_single {
u_int sng_sign:1;
u_int sng_exp:8;